From 741fe10d400ba0d20586450d00410796269fdef0 Mon Sep 17 00:00:00 2001 From: donghongyu Date: Sun, 29 Jan 2023 15:44:35 +0800 Subject: [PATCH 01/48] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0]=20[Change]=20[?= =?UTF-8?q?=201=E3=80=81=E4=B8=B4=E6=97=B6=E4=BF=AE=E6=94=B9=E6=B8=85?= =?UTF-8?q?=E6=89=AB=E8=BD=A6=E5=BC=82=E5=B8=B8=EF=BC=8C=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=88=B0dev=5Frobosweeper-d=5Fapp-module=5F2?= =?UTF-8?q?21230=5F1.1.0=E5=88=86=E6=94=AF=EF=BC=8C=E8=BF=99=E9=87=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=AF=E4=BB=A5=E4=B8=8D=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=20]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: donghongyu --- .../sweeper/view/SweeperTrafficDataView.java | 152 ++++++++---------- 1 file changed, 71 insertions(+), 81 deletions(-) diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java index 4164276bcf..4be12b9e35 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java @@ -6,9 +6,18 @@ import android.view.LayoutInflater; import android.widget.ImageView; import android.widget.TextView; -import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotVehicleStateListener; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.constraintlayout.widget.ConstraintLayout; + +import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisGearStateListener; +import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLamplightListener; +import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisSteeringStateListener; import com.mogo.eagle.core.function.api.v2x.LimitingVelocityListener; import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotVehicleStateListenerManager; +import com.mogo.eagle.core.function.call.autopilot.CallerChassisGearStateListenerManager; +import com.mogo.eagle.core.function.call.autopilot.CallerChassisLamplightListenerManager; +import com.mogo.eagle.core.function.call.autopilot.CallerChassisSteeringStateListenerManager; import com.mogo.eagle.core.function.call.v2x.CallLimitingVelocityListenerManager; import com.mogo.eagle.core.function.hmi.ui.widget.TapPositionView; import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; @@ -17,13 +26,12 @@ import com.mogo.och.sweeper.R; import org.jetbrains.annotations.NotNull; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.constraintlayout.widget.ConstraintLayout; import chassis.Chassis; -import chassis.VehicleStateOuterClass; -public class SweeperTrafficDataView extends ConstraintLayout { +public class SweeperTrafficDataView extends ConstraintLayout + implements IMoGoChassisLamplightListener, + IMoGoChassisSteeringStateListener, + IMoGoChassisGearStateListener { private static final String TAG = "SweeperTrafficDataView"; private TapPositionView tapPositionView;//方向盘 private ImageView speedImage;//速度图标 @@ -58,7 +66,10 @@ public class SweeperTrafficDataView extends ConstraintLayout { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - CallerAutopilotVehicleStateListenerManager.INSTANCE.addListener(TAG, mIMoGoAutopilotVehicleStateListener); + //添加 底盘灯光数据 监听 + CallerChassisLamplightListenerManager.INSTANCE.addListener(TAG, this); + CallerChassisSteeringStateListenerManager.INSTANCE.addListener(TAG, this); + CallerChassisGearStateListenerManager.INSTANCE.addListener(TAG, this); //增加限速监听 CallLimitingVelocityListenerManager.INSTANCE.addListener(TAG,limitingVelocityListener); } @@ -66,90 +77,68 @@ public class SweeperTrafficDataView extends ConstraintLayout { @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - CallerAutopilotVehicleStateListenerManager.INSTANCE.removeListener(mIMoGoAutopilotVehicleStateListener); + // 移除 底盘灯光数据 监听 + CallerChassisLamplightListenerManager.INSTANCE.removeListener(TAG); + CallerChassisSteeringStateListenerManager.INSTANCE.removeListener(TAG); + CallerChassisGearStateListenerManager.INSTANCE.removeListener(TAG); CallLimitingVelocityListenerManager.INSTANCE.removeListener(limitingVelocityListener); } - private final IMoGoAutopilotVehicleStateListener mIMoGoAutopilotVehicleStateListener = new IMoGoAutopilotVehicleStateListener() { - @Override - public void onSweeperFutianCleanSystemState(@NonNull VehicleStateOuterClass.SweeperFuTianCleanSystemState cleanSystemState) { - } - /** - * 车辆转向灯 - * @param lightSwitch - */ - @Override - public void onAutopilotLightSwitchData(@org.jetbrains.annotations.Nullable Chassis.LightSwitch lightSwitch) { - //转向灯状态 0是正常 1是左转 2是右转 - if (lightSwitch != null) { - CallerLogger.INSTANCE.d(TAG, "车辆转向灯:" + lightSwitch.toString()); - if (lightSwitch.getNumber()==1){ - sweeperTurnSignal.showLeftSignal(); - }else if(lightSwitch.getNumber()==2){ - sweeperTurnSignal.showRightSignal(); - }else{ - sweeperTurnSignal.showDirection(); - } + /** + * 车辆转向灯 + * @param lightSwitch + */ + @Override + public void onAutopilotLightSwitchData(@org.jetbrains.annotations.Nullable Chassis.LightSwitch lightSwitch) { + //转向灯状态 0是正常 1是左转 2是右转 + if (lightSwitch != null) { + CallerLogger.INSTANCE.d(TAG, "车辆转向灯:" + lightSwitch.toString()); + if (lightSwitch.getNumber()==1){ + sweeperTurnSignal.showLeftSignal(); + }else if(lightSwitch.getNumber()==2){ + sweeperTurnSignal.showRightSignal(); + }else{ + sweeperTurnSignal.showDirection(); } } + } - /** - * 刹车灯 - * @param brakeLight - */ - @Override - public void onAutopilotBrakeLightData(boolean brakeLight) { - CallerLogger.INSTANCE.d(TAG, "刹车灯:" + brakeLight); + /** + * 刹车灯 + * @param brakeLight + */ + @Override + public void onAutopilotBrakeLightData(boolean brakeLight) { + CallerLogger.INSTANCE.d(TAG, "刹车灯:" + brakeLight); + } + + /** + * 方向盘转向角 左+右- + * @param steering + */ + @Override + public void onAutopilotSteeringData(float steering) { + CallerLogger.INSTANCE.d(TAG, "steering原始值====" + steering); + if (Math.abs(steering) < 1) { + steering = 0; } + CallerLogger.INSTANCE.d(TAG, "steering忽略小数点后====" + (int) steering); + } - /** - * 方向盘转向角 左+右- - * @param steering - */ - @Override - public void onAutopilotSteeringData(float steering) { - CallerLogger.INSTANCE.d(TAG, "steering原始值====" + steering); - if (Math.abs(steering) < 1) { - steering = 0; + /** + * 档位 + * @param gear + */ + @Override + public void onAutopilotGearData(@NotNull Chassis.GearPosition gear) { + CallerLogger.INSTANCE.d(TAG, "司机屏档位" + gear.toString()); + ThreadUtils.runOnUiThread(() -> { + if (tapPositionView != null) { + tapPositionView.updateWithGear(gear); } - CallerLogger.INSTANCE.d(TAG, "steering忽略小数点后====" + (int) steering); - } + }); + } - /** - * 档位 - * @param gear - */ - @Override - public void onAutopilotGearData(@NotNull Chassis.GearPosition gear) { - CallerLogger.INSTANCE.d(TAG, "司机屏档位" + gear.toString()); - ThreadUtils.runOnUiThread(() -> { - if (tapPositionView != null) { - tapPositionView.updateWithGear(gear); - } - }); - } - - @Override - public void onAutopilotDataException(long timestamp) { - - } - - @Override - public void onAutopilotAcc(float carAcc) { - - } - - @Override - public void onAutopilotBrake(float brake) { - CallerLogger.INSTANCE.d(TAG, "刹车:" + brake); - } - - @Override - public void onAutopilotThrottle(float throttle) { - CallerLogger.INSTANCE.d(TAG, "油门:" + throttle); - } - - }; /** * 限速监听 */ @@ -172,4 +161,5 @@ public class SweeperTrafficDataView extends ConstraintLayout { speedImage.setBackgroundResource(newSpeed > 60 ? R.drawable.sweeper_traffic_data_speed_warning :R.drawable.sweeper_bg_traffic_data_speed); } } + } From 8433d0c8de15003a0fddcadc4b39d57f851df984 Mon Sep 17 00:00:00 2001 From: zhongchao Date: Sun, 29 Jan 2023 16:24:45 +0800 Subject: [PATCH 02/48] [2.13.0-arch-opt] hmi proxy replace to view --- .../och/bus/fragment/BaseBusTabFragment.java | 10 +- .../java/com/mogo/och/noop/OchNoopFragment.kt | 60 ++-- .../main/res/layout/och_noop_fragment_hmi.xml | 27 +- .../fragment/BaseSweeperTabFragment.java | 12 +- .../ui/TaxiPassengerBaseFragment.java | 10 +- .../mogo/och/taxi/ui/BaseTaxiTabFragment.java | 9 +- .../mogo/launcher/stageone/ConfigStartUp.kt | 4 - .../core/function/hmi/ui/MoGoHmiFragment.kt | 276 +++++++----------- .../hmi/ui/switch/DemoModeHiddenSwitch.kt | 39 +++ .../hmi/ui/tools/AutoPilotAndCheckView.kt | 2 +- .../function/hmi/ui/tools/ToolsImageView.kt | 31 ++ .../hmi/ui/widget/AutoPilotStatusView.kt | 30 +- .../core/function/hmi/ui/widget/CameraView.kt | 28 ++ .../hmi/ui/widget/PerspectiveSwitchView.kt | 21 +- .../function/hmi/ui/widget/SpeedPanelView.kt | 16 +- .../function/hmi/ui/widget/StatusBarView.kt | 53 ++-- .../core/function/main/MainActivity.java | 14 +- .../function/main/MainMoGoApplication.java | 6 +- .../src/main/res/layout/fragment_hmi.xml | 93 +----- .../eagle/core/data/config/HmiBuildConfig.kt | 23 -- .../function/api/hmi/IMoGoHmiViewProxy.kt | 12 - .../api/hmi/view/IViewControlListener.kt | 47 +++ .../api/hmi/warning/IMoGoHmiProvider.kt | 20 +- .../function/call/hmi/CallerHmiManager.kt | 18 -- .../CallerHmiViewControlListenerManager.kt | 52 ++++ .../com/mogo/commons/constants/HostConst.java | 4 +- 26 files changed, 468 insertions(+), 449 deletions(-) create mode 100644 core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/switch/DemoModeHiddenSwitch.kt create mode 100644 core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt create mode 100644 core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/CameraView.kt create mode 100644 core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewControlListener.kt create mode 100644 core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiViewControlListenerManager.kt diff --git a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/fragment/BaseBusTabFragment.java b/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/fragment/BaseBusTabFragment.java index 5233b3699e..06b227fd4f 100644 --- a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/fragment/BaseBusTabFragment.java +++ b/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/fragment/BaseBusTabFragment.java @@ -22,7 +22,6 @@ import androidx.constraintlayout.widget.Group; import com.mogo.commons.mvp.IView; import com.mogo.commons.mvp.MvpFragment; import com.mogo.commons.mvp.Presenter; -import com.mogo.eagle.core.data.config.HmiBuildConfig; import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener; import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener; import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager; @@ -30,7 +29,6 @@ import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListener import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager; import com.mogo.eagle.core.function.call.hmi.CallerHmiManager; import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager; -import com.mogo.eagle.core.function.hmi.ui.setting.SOPSettingView; import com.mogo.eagle.core.function.hmi.ui.widget.TrafficDataView; import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener; @@ -189,9 +187,7 @@ public abstract class BaseBusTabFragment if (mBadcaseBtn != null) { CallerDevaToolsManager.INSTANCE.initBadCase(mBadcaseBtn); - if (!HmiBuildConfig.isShowBadCaseView) { - CallerAutopilotRecordListenerManager.INSTANCE.addListener(TAG, this); - } + CallerAutopilotRecordListenerManager.INSTANCE.addListener(TAG, this); } mAICollectBtn = findViewById(R.id.module_mogo_och_ai_collet_rl); @@ -230,9 +226,7 @@ public abstract class BaseBusTabFragment @Override public void onDestroyView() { super.onDestroyView(); - if (!HmiBuildConfig.isShowBadCaseView) { - CallerAutopilotRecordListenerManager.INSTANCE.removeListener(TAG); - } + CallerAutopilotRecordListenerManager.INSTANCE.removeListener(TAG); EventBus.getDefault().unregister(this); } diff --git a/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OchNoopFragment.kt b/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OchNoopFragment.kt index f071115360..ac540cf7e9 100644 --- a/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OchNoopFragment.kt +++ b/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OchNoopFragment.kt @@ -3,14 +3,14 @@ package com.mogo.och.noop import android.view.View import com.mogo.commons.mvp.MvpFragment import com.mogo.eagle.core.data.config.FunctionBuildConfig -import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager -import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager import com.mogo.eagle.core.function.call.biz.CallerFuncBizManager import com.mogo.eagle.core.function.call.hmi.CallerHmiManager +import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.hmi.ui.setting.CameraLiveView.Companion.cameraLiveView +import com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugView import com.mogo.eagle.core.function.hmi.ui.setting.ToolsView.Companion.toolsView import com.mogo.eagle.core.function.hmi.ui.widget.DemoModeView -import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils +import com.mogo.eagle.core.function.hmi.ui.widget.StatusBarView import com.mogo.och.bus.R import kotlinx.android.synthetic.main.fragment_hmi.* @@ -35,41 +35,35 @@ class OchNoopFragment : MvpFragment(), override fun initViews() { + + //设置StatusBar初始状态 + CallerHmiViewControlListenerManager.updateStatusBarRightView( + StatusBarView.TAG, + FunctionBuildConfig.isDemoMode, + "demoMode", + DemoModeView(requireContext()) + ) + ivCameraIcon?.setOnClickListener { - cameraLiveView.showCameraList(context, CallerFuncBizManager.bizProvider.getCameraList){ liveStatus -> - if(liveStatus){ + cameraLiveView.showCameraList( + context, + CallerFuncBizManager.bizProvider.getCameraList + ) { liveStatus -> + if (liveStatus) { ivCameraIcon.setBackgroundResource(R.drawable.icon_camera_selected) - }else{ + } else { ivCameraIcon.setBackgroundResource(R.drawable.icon_camera_nor) } } } - ivToolsIcon?.setOnClickListener { + ivToolsView?.setOnClickListener { toolsView.showToolsFloat(context) } - //美化模式隐藏开关 - viewDemoModeSwitch.setOnClickListener { - //只在司机端设置美化模式开关功能 - if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { - //单次查询,是否有行程信息(订单进行中时点击不生效),autopilotControlParameters为null代表不处于自动驾驶状态下 - if (CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo().autopilotControlParameters == null) { - FunctionBuildConfig.isDemoMode = !FunctionBuildConfig.isDemoMode - context?.let { - CallerHmiManager.updateStatusBarLeftView( - FunctionBuildConfig.isDemoMode, - "demoMode", - DemoModeView(it) - ) - } - CallerAutoPilotManager.setDemoMode(FunctionBuildConfig.isDemoMode) - if (!FunctionBuildConfig.isDemoMode) { - //关闭美化模式时,通知工控机 - CallerAutoPilotManager.setIPCDemoMode(FunctionBuildConfig.isDemoMode) - } - } - } + viewShowDebugView.setOnLongClickListener { + ToggleDebugView.toggleDebugView.toggle(requireContext()) + true } cbMsgBoxDriver.setOnCheckedChangeListener { _, isChecked -> @@ -99,16 +93,6 @@ class OchNoopFragment : MvpFragment(), } } - if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { - cbMsgBoxDriver.visibility = View.VISIBLE - viewDriverMsgBoxBubble.visibility = View.VISIBLE - } - if (AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode) && - AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode) - ) { - cbMsgBoxPassenger.visibility = View.VISIBLE - viewPassengerMsgBoxBubble.visibility = View.VISIBLE - } } diff --git a/OCH/mogo-och-noop/src/main/res/layout/och_noop_fragment_hmi.xml b/OCH/mogo-och-noop/src/main/res/layout/och_noop_fragment_hmi.xml index ffdf7313df..2638954937 100644 --- a/OCH/mogo-och-noop/src/main/res/layout/och_noop_fragment_hmi.xml +++ b/OCH/mogo-och-noop/src/main/res/layout/och_noop_fragment_hmi.xml @@ -39,14 +39,15 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + - @@ -101,7 +101,8 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" /> - + - @@ -134,7 +132,7 @@ android:layout_marginBottom="40dp" android:src="@drawable/bad_case_selector" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/ivToolsIcon" /> + app:layout_constraintStart_toEndOf="@id/ivToolsView" /> @@ -187,7 +185,7 @@ android:layout_marginEnd="25dp" android:background="@drawable/selector_msg_box" android:button="@null" - android:visibility="gone" + android:visibility="visible" app:layout_constraintRight_toLeftOf="@id/viewLimitingVelocity" app:layout_constraintTop_toBottomOf="@+id/ivCameraIcon" /> @@ -244,7 +242,7 @@ android:layout_width="864px" android:layout_height="wrap_content" android:layout_marginEnd="40dp" - android:visibility="gone" + android:visibility="visible" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/cbMsgBoxDriver" /> @@ -288,6 +286,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + - implements IMogoMapListener, TaxiPassengerTaxiView, ITPClickStartAutopilotCallback, IMoGoHmiViewProxy.IViewNotificationProvider { + implements IMogoMapListener, TaxiPassengerTaxiView, ITPClickStartAutopilotCallback{ static final String TAG = "TaxiPassengerBaseFragment"; @@ -91,8 +91,6 @@ public class TaxiPassengerBaseFragment extends MvpFragment() { if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode) || AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) { //控制HMI展示元素 将不用手动调用setXXXXXViewVisibility - HmiBuildConfig.isShowSpeedView = false HmiBuildConfig.isShowAutopilotStatusView = false HmiBuildConfig.isShowPerspectiveSwitchView = false - HmiBuildConfig.isShowToolsView = false - HmiBuildConfig.isShowBadCaseView = false - HmiBuildConfig.isShowUpgradeTipsView = false } if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) { diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt index 3524050b7d..d73c20c9c1 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt @@ -35,18 +35,21 @@ import com.mogo.eagle.core.data.notice.NoticeTrafficStylePushData import com.mogo.eagle.core.data.report.ReportEntity import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener import com.mogo.eagle.core.function.api.hmi.IMoGoHmiViewProxy -import com.mogo.eagle.core.function.api.hmi.IMoGoHmiViewProxy.IViewNotificationProvider +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.AutoPilotStatusView_TAG +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.CameraView_TAG +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.PerspectiveSwitchView_TAG +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.SpeedPanelView_TAG +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.ToolsView_TAG import com.mogo.eagle.core.function.api.hmi.view.IViewLimitingVelocity -import com.mogo.eagle.core.function.api.hmi.view.IViewNotification import com.mogo.eagle.core.function.api.hmi.view.IViewTrafficLight import com.mogo.eagle.core.function.api.hmi.warning.IMoGoHmiProvider import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager -import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager import com.mogo.eagle.core.function.call.biz.CallerFuncBizManager import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager import com.mogo.eagle.core.function.call.hmi.CallerHmiManager +import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.call.map.CallerMapDataCollectorManager import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager @@ -66,9 +69,7 @@ import com.mogo.eagle.core.function.hmi.ui.setting.IPCReportWindow import com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugView.Companion.toggleDebugView import com.mogo.eagle.core.function.hmi.ui.setting.ToolsView.Companion.toolsView import com.mogo.eagle.core.function.hmi.ui.tools.AdUpgradeDialog -import com.mogo.eagle.core.function.hmi.ui.widget.DemoModeView -import com.mogo.eagle.core.function.hmi.ui.widget.StatusBarView -import com.mogo.eagle.core.function.hmi.ui.widget.V2XNotificationView +import com.mogo.eagle.core.function.hmi.ui.widget.* import com.mogo.eagle.core.function.main.DisplayEffectsHelper import com.mogo.eagle.core.utilcode.kotlin.safeCancel import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils @@ -102,26 +103,19 @@ class MoGoHmiFragment : MvpFragment(), IMoGoHmiProvider, IMoGoHmiViewProxy, MoGoHmiContract.View, - IMoGoAutopilotRecordListener, - IViewNotificationProvider { + IMoGoAutopilotRecordListener { companion object { private const val TAG = "MoGoHmiFragment" } - //StatusView - private var statusBarView: StatusBarView? = null - // HMI 视图控件代理 - // 红绿灯 View代理 + // todo 需要统一数据源 红绿灯 View代理 private var mViewTrafficLight: IViewTrafficLight? = null - // 限速 View代理 + // todo 需要统一数据源 限速 View代理 private var mViewLimitingVelocity: IViewLimitingVelocity? = null - // V2X预警弹窗 View 代理 - private var mViewNotificationProvider: IViewNotificationProvider? = null - private var lastSpeakJob: Job? = null private var lastShowV2XJob: Job? = null @@ -130,18 +124,9 @@ class MoGoHmiFragment : MvpFragment(), override fun initViews() { initViewShowWithConfig() - // 同步AppInfo Config信息 - CallerDevaToolsManager.syncConfig() //todo arrow 页面初始化 放到合适位置 - //todo 抽象fragment能力 放入baseHmi - val decorView = requireActivity().window.decorView as FrameLayout - statusBarView = decorView.findViewWithTag("status_bar") as StatusBarView? //设置StatusBar初始状态 - if (FunctionBuildConfig.isDemoMode) { - statusBarView?.updateRightView(true, "demoMode", DemoModeView(requireContext())) - } else { - statusBarView?.updateRightView(false, "demoMode", DemoModeView(requireContext())) - } + CallerHmiViewControlListenerManager.updateStatusBarRightView(StatusBarView.TAG,FunctionBuildConfig.isDemoMode, "demoMode", DemoModeView(requireContext())) ivCameraIcon?.setOnClickListener { cameraLiveView.showCameraList( @@ -156,38 +141,12 @@ class MoGoHmiFragment : MvpFragment(), } } - ivToolsIcon?.setOnClickListener { - toolsView.showToolsFloat(requireContext()) - } - viewShowDebugView.setOnLongClickListener { toggleDebugView.toggle(requireContext()) true } - //美化模式隐藏开关 - viewDemoModeSwitch.setOnClickListener { - //只在司机端设置美化模式开关功能 - if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { - //单次查询,是否有行程信息(订单进行中时点击不生效),autopilotControlParameters为null代表不处于自动驾驶状态下 - if (CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo().autopilotControlParameters == null) { - FunctionBuildConfig.isDemoMode = !FunctionBuildConfig.isDemoMode - context?.let { - CallerHmiManager.updateStatusBarLeftView( - FunctionBuildConfig.isDemoMode, - "demoMode", - DemoModeView(it) - ) - } - CallerAutoPilotManager.setDemoMode(FunctionBuildConfig.isDemoMode) - if (!FunctionBuildConfig.isDemoMode) { - //关闭美化模式时,通知工控机 - CallerAutoPilotManager.setIPCDemoMode(FunctionBuildConfig.isDemoMode) - } - } - } - } - + //todo 新超,封装至消息盒子 cbMsgBoxDriver.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { viewDriverMsgBoxList.visibility = View.VISIBLE @@ -202,6 +161,7 @@ class MoGoHmiFragment : MvpFragment(), } } + //todo 新超,封装至消息盒子 cbMsgBoxPassenger.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { viewPassengerMsgBoxList.visibility = View.VISIBLE @@ -215,6 +175,7 @@ class MoGoHmiFragment : MvpFragment(), } } + //todo 加载端自己控制 --- 新超 本期我们设置到bus,taxi,sweep Fragment if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { cbMsgBoxDriver.visibility = View.VISIBLE viewDriverMsgBoxBubble.visibility = View.VISIBLE @@ -227,6 +188,24 @@ class MoGoHmiFragment : MvpFragment(), } } + // todo 新超 + override fun updateDriverMsgBoxTipView(show: Boolean) { + if (show) { + MsgBoxTipView.visibility = View.VISIBLE + } else { + MsgBoxTipView.visibility = View.GONE + } + } + + // todo 新超 + override fun updatePassengerMsgBoxTipView(show: Boolean) { + if (show) { + MsgBoxPTipView.visibility = View.VISIBLE + } else { + MsgBoxPTipView.visibility = View.GONE + } + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) CallerAutopilotRecordListenerManager.addListener(TAG, this) @@ -234,15 +213,62 @@ class MoGoHmiFragment : MvpFragment(), // 首次初始化使用默认视图 setProxyTrafficLightView(viewTrafficLightVr) setProxyLimitingSpeedView(viewLimitingVelocity) - setViewNotificationProvider(this) } - override fun getNotificationView(): IViewNotification? = - context?.let { V2XNotificationView(it) } - override fun onAutopilotRecordResult(recordPanel: RecordPanelOuterClass.RecordPanel) { //todo 数据中心 + /** todo ----------------------------------------------**/ + /** + * 设置 红绿灯 代理View + */ + override fun setProxyTrafficLightView(view: IViewTrafficLight) { + mViewTrafficLight = view + } + + /** + * 设置 限速 代理View + */ + override fun setProxyLimitingSpeedView(view: IViewLimitingVelocity) { + mViewLimitingVelocity = view + } + + /** + * 根据配置文件初始化视图显示 + */ + private fun initViewShowWithConfig() { + // 控制 自动驾驶状态 展示 + if (HmiBuildConfig.isShowAutopilotStatusView) { + setAutopilotStatusViewVisibility(View.VISIBLE) + } else { + setAutopilotStatusViewVisibility(View.GONE) + } + + // 控制 切换视角 展示 + if (HmiBuildConfig.isShowPerspectiveSwitchView) { + setPerspectiveSwitchViewVisibility(View.VISIBLE) + } else { + setPerspectiveSwitchViewVisibility(View.GONE) + } + + // 控制 红绿灯 展示 + if (HmiBuildConfig.isShowTrafficLightView) { + setTrafficLightVrVisibility(View.VISIBLE) + } else { + setTrafficLightVrVisibility(View.GONE) + } + + // 控制 远程摄像头图标 展示 + if (HmiBuildConfig.isShowCameraView) { + setCameraViewVisibility(View.VISIBLE) + } else { + setCameraViewVisibility(View.GONE) + } + } + + /** todo----------------------------------------------- **/ + + override fun onAutopilotRecordResult(recordPanel: RecordPanelOuterClass.RecordPanel) { CallerLogger.d("$M_HMI$TAG", "recordKey=${recordPanel.key},stat=${recordPanel.stat}") - if (BadCaseConfig.recordKeyList.contains(recordPanel.key)) { + if (BadCaseConfig.recordKeyList.contains(recordPanel.key)) { //todo InitiativeBadCaseWindow if (recordPanel.stat == 100 || recordPanel.stat == 101) { //成功结束录制 TipToast.shortTip( @@ -279,7 +305,7 @@ class MoGoHmiFragment : MvpFragment(), //处于非美化模式下弹窗;是地图数据采集任务时即type=2时,不弹窗 if (!FunctionBuildConfig.isDemoMode && (recordPanel.stat == 100 || recordPanel.stat == 101) && recordPanel.type != 2) { //只在司机屏生效,乘客屏不生效 - if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { + if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { //todo 数据中心控制来源 CallerMsgBoxManager.saveMsgBox( MsgBoxBean( MsgBoxType.RECORD, RecordBagMsg( @@ -290,7 +316,7 @@ class MoGoHmiFragment : MvpFragment(), ) } } - if (!FunctionBuildConfig.isDemoMode && recordPanel.type == 2 && ( + if (!FunctionBuildConfig.isDemoMode && recordPanel.type == 2 && ( //todo CallerMapDataCollectorManager recordPanel.stat == 101 || //工控机采集完成-被动完成 recordPanel.stat == 100 || //工控机采集完成-主动完成 recordPanel.stat == 102 || //工控机达到最大采集时长 @@ -310,7 +336,7 @@ class MoGoHmiFragment : MvpFragment(), /** * ok - * 工控机重启返回结果 todo 确认数据源 + * 工控机重启返回结果 * @param code * @param msg */ @@ -352,121 +378,26 @@ class MoGoHmiFragment : MvpFragment(), } } - /** todo----------------------------------------------- **/ - override fun setViewNotificationProvider(provider: IViewNotificationProvider) { - mViewNotificationProvider = provider - } - override fun setStatusBarDarkOrLight(light: Boolean) { - statusBarView?.setStatusBarDarkOrLight(light) + CallerHmiViewControlListenerManager.setStatusBarDarkOrLight(StatusBarView.TAG,light) } override fun updateStatusBarRightView(insert: Boolean, tag: String, viewGroup: ViewGroup) { - statusBarView?.updateRightView(insert, tag, viewGroup) + CallerHmiViewControlListenerManager.updateStatusBarRightView(StatusBarView.TAG,insert, tag, viewGroup) } override fun updateStatusBarLeftView(insert: Boolean, tag: String, viewGroup: ViewGroup) { - statusBarView?.updateLeftView(insert, tag, viewGroup) + CallerHmiViewControlListenerManager.updateStatusBarLeftView(StatusBarView.TAG,insert, tag, viewGroup) } override fun updateStatusBarDownloadView(insert: Boolean, tag: String, progress: Int) { - statusBarView?.updateProgressView(insert, tag, progress) + CallerHmiViewControlListenerManager.updateStatusBarDownloadView(StatusBarView.TAG,insert, tag, progress) } override fun updateMfStatus(tag: String, status: Boolean) { - statusBarView?.updateMfStatus(tag, status) + CallerHmiViewControlListenerManager.updateMfStatus(StatusBarView.TAG,tag, status) } - override fun updateDriverMsgBoxTipView(show: Boolean) { - if (show) { - MsgBoxTipView.visibility = View.VISIBLE - } else { - MsgBoxTipView.visibility = View.GONE - } - } - - override fun updatePassengerMsgBoxTipView(show: Boolean) { - if (show) { - MsgBoxPTipView.visibility = View.VISIBLE - } else { - MsgBoxPTipView.visibility = View.GONE - } - } - - /** - * 设置 红绿灯 代理View - */ - override fun setProxyTrafficLightView(view: IViewTrafficLight) { - mViewTrafficLight = view - } - - /** - * 设置 限速 代理View - */ - override fun setProxyLimitingSpeedView(view: IViewLimitingVelocity) { - mViewLimitingVelocity = view - } - - /** - * 根据配置文件初始化视图显示 - */ - private fun initViewShowWithConfig() { - // 控制 速度 展示 - if (HmiBuildConfig.isShowSpeedView) { - setSpeedChartViewVisibility(View.VISIBLE) - } else { - setSpeedChartViewVisibility(View.GONE) - } - - // 控制 自动驾驶状态 展示 - if (HmiBuildConfig.isShowAutopilotStatusView) { - setAutopilotStatusViewVisibility(View.VISIBLE) - } else { - setAutopilotStatusViewVisibility(View.GONE) - } - - // 控制 切换视角 展示 - if (HmiBuildConfig.isShowPerspectiveSwitchView) { - setPerspectiveSwitchViewVisibility(View.VISIBLE) - } else { - setPerspectiveSwitchViewVisibility(View.GONE) - } - - // 控制 切换视角 展示 - if (HmiBuildConfig.isShowToolsView) { - setToolsViewVisibility(View.VISIBLE) - } else { - setToolsViewVisibility(View.GONE) - } - - // 控制 BadCase 按钮展示 - if (HmiBuildConfig.isShowBadCaseView) { - ivBadCaseTools.visibility = View.VISIBLE - ivAiCollectTools.visibility = View.VISIBLE - CallerDevaToolsManager.initBadCase(ivBadCaseTools) //todo 新超 封装在hmi view - CallerDevaToolsManager.initAiCollect(ivAiCollectTools) //todo 新超 封装在hmi view - } else { - ivBadCaseTools.visibility = View.GONE - ivAiCollectTools.visibility = View.GONE - } - - // 控制 红绿灯 展示 - if (HmiBuildConfig.isShowTrafficLightView) { - setTrafficLightVrVisibility(View.VISIBLE) - } else { - setTrafficLightVrVisibility(View.GONE) - } - - // 控制 远程摄像头图标 展示 - if (HmiBuildConfig.isShowCameraView) { - setCameraViewVisibility(View.VISIBLE) - } else { - setCameraViewVisibility(View.GONE) - } - } - - /** todo----------------------------------------------- **/ - override fun getLayoutId(): Int { return R.layout.fragment_hmi } @@ -484,28 +415,28 @@ class MoGoHmiFragment : MvpFragment(), } /** todo----------------------------------------------- **/ - override fun setSpeedChartViewVisibility(visibility: Int) { - viewSpeedChart?.visibility = visibility - } - override fun setTrafficLightVrVisibility(visibility: Int) { mViewTrafficLight?.visibility = visibility } + override fun setToolsViewVisibility(visibility: Int) { + CallerHmiViewControlListenerManager.invokeVisible(ToolsView_TAG,visibility) + } + + override fun setSpeedChartViewVisibility(visibility: Int) { + CallerHmiViewControlListenerManager.invokeVisible(SpeedPanelView_TAG,visibility) + } + override fun setAutopilotStatusViewVisibility(visibility: Int) { - viewAutopilotStatus?.visibility = visibility + CallerHmiViewControlListenerManager.invokeVisible(AutoPilotStatusView_TAG,visibility) } override fun setPerspectiveSwitchViewVisibility(visibility: Int) { - viewPerspectiveSwitch?.visibility = visibility - } - - override fun setToolsViewVisibility(visibility: Int) { - ivToolsIcon?.visibility = visibility + CallerHmiViewControlListenerManager.invokeVisible(PerspectiveSwitchView_TAG,visibility) } override fun setCameraViewVisibility(visibility: Int) { - ivCameraIcon?.visibility = visibility + CallerHmiViewControlListenerManager.invokeVisible(CameraView_TAG, visibility) } /** todo----------------------------------------------- **/ @@ -1035,7 +966,6 @@ class MoGoHmiFragment : MvpFragment(), } } ?.commitAllowingStateLoss() -// context?.let { CallerDevaToolsManager.showStatusBar(it, statusBarContainer) } } override fun onDestroy() { diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/switch/DemoModeHiddenSwitch.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/switch/DemoModeHiddenSwitch.kt new file mode 100644 index 0000000000..ff65be7e7a --- /dev/null +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/switch/DemoModeHiddenSwitch.kt @@ -0,0 +1,39 @@ +package com.mogo.eagle.core.function.hmi.ui.switch + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import com.mogo.eagle.core.data.config.FunctionBuildConfig +import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager +import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager +import com.mogo.eagle.core.function.call.hmi.CallerHmiManager +import com.mogo.eagle.core.function.hmi.ui.widget.DemoModeView +import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils + +class DemoModeHiddenSwitch(context: Context?, attrs: AttributeSet?) : View(context, attrs) { + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + setOnClickListener { + //只在司机端设置美化模式开关功能 + if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { + //单次查询,是否有行程信息(订单进行中时点击不生效),autopilotControlParameters为null代表不处于自动驾驶状态下 + if (CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo().autopilotControlParameters == null) { + FunctionBuildConfig.isDemoMode = !FunctionBuildConfig.isDemoMode + context?.let { + CallerHmiManager.updateStatusBarLeftView( + FunctionBuildConfig.isDemoMode, + "demoMode", + DemoModeView(it) + ) + } + CallerAutoPilotManager.setDemoMode(FunctionBuildConfig.isDemoMode) + if (!FunctionBuildConfig.isDemoMode) { + //关闭美化模式时,通知工控机 + CallerAutoPilotManager.setIPCDemoMode(FunctionBuildConfig.isDemoMode) + } + } + } + } + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/AutoPilotAndCheckView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/AutoPilotAndCheckView.kt index 3de065ef78..77e12619af 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/AutoPilotAndCheckView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/AutoPilotAndCheckView.kt @@ -37,7 +37,7 @@ import kotlin.system.exitProcess * @author ChenFufeng * 设置自动驾驶速度和检测页入口 */ -class AutoPilotAndCheckView @JvmOverloads constructor( +internal class AutoPilotAndCheckView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt new file mode 100644 index 0000000000..6d89368329 --- /dev/null +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt @@ -0,0 +1,31 @@ +package com.mogo.eagle.core.function.hmi.ui.tools + +import android.content.Context +import android.util.AttributeSet +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.ToolsView_TAG +import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager +import com.mogo.eagle.core.function.hmi.R + +class ToolsImageView(context: Context, attrs: AttributeSet?) : + androidx.appcompat.widget.AppCompatImageView(context, attrs), IViewControlListener { + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + setBackgroundResource(R.drawable.module_ext_check) + setImageResource(R.drawable.icon_tools_nor) + scaleType = ScaleType.CENTER + + CallerHmiViewControlListenerManager.addListener(ToolsView_TAG, this) + } + + override fun visible(v: Int) { + super.visible(v) + visibility = v + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + CallerHmiViewControlListenerManager.removeListener(ToolsView_TAG) + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/AutoPilotStatusView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/AutoPilotStatusView.kt index 03546930cc..e6c453db80 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/AutoPilotStatusView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/AutoPilotStatusView.kt @@ -8,11 +8,14 @@ import androidx.constraintlayout.widget.ConstraintLayout import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.AutoPilotStatusView_TAG import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.getCurWgs84Lat import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.getCurWgs84Lon import com.mogo.eagle.core.function.call.hmi.CallerHmiListenerManager +import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI @@ -25,18 +28,21 @@ import kotlinx.android.synthetic.main.view_autopilot_status.view.* * @date 2021/9/22 3:59 下午 * 自动驾驶状态按钮 */ -class AutoPilotStatusView @JvmOverloads constructor( +class AutoPilotStatusView constructor( context: Context, attrs: AttributeSet ) : ConstraintLayout(context, attrs), View.OnClickListener, - IMoGoAutopilotStatusListener { + IMoGoAutopilotStatusListener, IViewControlListener { - private val TAG = "AutopilotStatusView" + companion object { + const val TAG = "AutopilotStatusView" + } private var mAutopilotStatus: Int = 0 - init { + override fun onAttachedToWindow() { + super.onAttachedToWindow() initView(context) } @@ -51,18 +57,22 @@ class AutoPilotStatusView @JvmOverloads constructor( setOnClickListener(this) // 自动驾驶状态监听 CallerAutoPilotStatusListenerManager.addListener(TAG, this) + CallerHmiViewControlListenerManager.addListener(AutoPilotStatusView_TAG, this) CallerLogger.d("$M_HMI$TAG", "autopilotStatus: $mAutopilotStatus") setAutoPilotStatus(mAutopilotStatus) } + override fun visible(v: Int) { + super.visible(v) + visibility = v + } + override fun onClick(v: View?) { when (mAutopilotStatus) { 0 -> {// 不可自动驾驶,adas与工控机没有链接,或工控机异常 CallerLogger.e("$M_HMI$TAG", "不可自动驾驶,adas与工控机没有链接,或工控机异常,请检查") ToastUtils.showShort("不可自动驾驶,adas与工控机没有链接,或工控机异常,请检查") - // TODO 这里临时触发自动驾驶能力,测试功过这里删除 - //CallerHmiListenerManager.invokeCheckAutoPilotBtnListener(true) } 1 -> {// 可自动驾驶,目前处于人工干预状态 CallerHmiListenerManager.invokeCheckAutoPilotBtnListener(true) @@ -85,7 +95,7 @@ class AutoPilotStatusView @JvmOverloads constructor( currentAutopilot.endName = "HYJC" currentAutopilot.isSpeakVoice = false currentAutopilot.startLatLon = - AutopilotControlParameters.AutoPilotLonLat(getCurWgs84Lat(),getCurWgs84Lon()) + AutopilotControlParameters.AutoPilotLonLat(getCurWgs84Lat(), getCurWgs84Lon()) currentAutopilot.endLatLon = AutopilotControlParameters.AutoPilotLonLat(26.819716071924688, 112.57715442110867) currentAutopilot.vehicleType = 10 @@ -126,4 +136,10 @@ class AutoPilotStatusView @JvmOverloads constructor( setAutoPilotStatus(autoPilotStatusInfo.state) } + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + CallerAutoPilotStatusListenerManager.removeListener(TAG) + CallerHmiViewControlListenerManager.removeListener(AutoPilotStatusView_TAG) + } + } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/CameraView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/CameraView.kt new file mode 100644 index 0000000000..8e90c54e8c --- /dev/null +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/CameraView.kt @@ -0,0 +1,28 @@ +package com.mogo.eagle.core.function.hmi.ui.widget + +import android.content.Context +import android.util.AttributeSet +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.CameraView_TAG +import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager +import com.mogo.eagle.core.function.hmi.R + +class CameraView(context: Context, attrs: AttributeSet?) : + androidx.appcompat.widget.AppCompatImageView(context, attrs), IViewControlListener { + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + setBackgroundResource(R.drawable.icon_camera_nor) + CallerHmiViewControlListenerManager.addListener(CameraView_TAG, this) + } + + override fun visible(v: Int) { + super.visible(v) + visibility = v + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + CallerHmiViewControlListenerManager.removeListener(CameraView_TAG) + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/PerspectiveSwitchView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/PerspectiveSwitchView.kt index 020a0b32d0..55e04f82ec 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/PerspectiveSwitchView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/PerspectiveSwitchView.kt @@ -5,6 +5,9 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.view.View import android.widget.FrameLayout +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.PerspectiveSwitchView_TAG +import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager.getMapUIController import com.mogo.eagle.core.function.hmi.R import com.mogo.map.uicontroller.VisualAngleMode @@ -19,12 +22,20 @@ class PerspectiveSwitchView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 -) : FrameLayout(context, attrs, defStyleAttr), View.OnClickListener { +) : FrameLayout(context, attrs, defStyleAttr), View.OnClickListener, IViewControlListener{ - init { + override fun onAttachedToWindow() { + super.onAttachedToWindow() LayoutInflater.from(context).inflate(R.layout.view_perspective_switch, this, true) setBackgroundResource(R.drawable.module_switch_map_bg) setOnClickListener(this) + + CallerHmiViewControlListenerManager.addListener(PerspectiveSwitchView_TAG,this) + } + + override fun visible(v: Int) { + super.visible(v) + visibility = v } override fun onClick(v: View?) { @@ -41,4 +52,10 @@ class PerspectiveSwitchView @JvmOverloads constructor( } } } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + CallerHmiViewControlListenerManager.removeListener(PerspectiveSwitchView_TAG) + } + } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedPanelView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedPanelView.kt index 8f10f9e037..3d5b7cac37 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedPanelView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedPanelView.kt @@ -6,8 +6,11 @@ import android.util.AttributeSet import android.view.Gravity import android.widget.FrameLayout import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.SpeedPanelView_TAG import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ20ListenerManager import com.mogo.eagle.core.function.call.hmi.CallerHmiManager +import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.utilcode.util.UiThreadHandler @@ -22,7 +25,7 @@ class SpeedPanelView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 -) : FrameLayout(context, attrs, defStyleAttr), IMoGoChassisLocationGCJ02Listener { +) : FrameLayout(context, attrs, defStyleAttr), IMoGoChassisLocationGCJ02Listener,IViewControlListener { companion object { const val TAG = "SpeedPanelView" @@ -54,7 +57,10 @@ class SpeedPanelView @JvmOverloads constructor( private var timerTask: TimerTask? = null override fun onAttachedToWindow() { - super.onAttachedToWindow() // 注册位置回调 + super.onAttachedToWindow() + // 注册view控制显示隐藏监听 + CallerHmiViewControlListenerManager.addListener(SpeedPanelView_TAG,this) + // 注册位置回调 CallerChassisLocationGCJ20ListenerManager.addListener(TAG, this) // 开启定时查询速度 timerTask?.cancel() @@ -83,9 +89,15 @@ class SpeedPanelView @JvmOverloads constructor( } } + override fun visible(v: Int) { + super.visible(v) + visibility = v + } + override fun onDetachedFromWindow() { super.onDetachedFromWindow() // 解除注册 + CallerHmiViewControlListenerManager.removeListener(SpeedPanelView_TAG) CallerChassisLocationGCJ20ListenerManager.removeListener(TAG) try { timerTask?.cancel() diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/StatusBarView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/StatusBarView.kt index ae89a8489b..42079aa30b 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/StatusBarView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/StatusBarView.kt @@ -1,18 +1,19 @@ package com.mogo.eagle.core.function.hmi.ui.widget +import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet -import android.util.Log -import android.view.* -import android.widget.* +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.LinearLayout import com.mogo.eagle.core.data.mofang.MfConstants +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener -import com.mogo.eagle.core.function.call.devatools.* +import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager +import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.call.setting.CallerSkinModeListenerManager import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr -import com.mogo.eagle.core.utilcode.util.BarUtils -import com.mogo.eagle.core.utilcode.util.ScreenUtils import kotlinx.android.synthetic.main.view_status_bar.view.* import java.util.concurrent.CopyOnWriteArrayList @@ -20,7 +21,7 @@ class StatusBarView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 -) : LinearLayout(context, attrs, defStyleAttr), IMoGoSkinModeChangeListener { +) : LinearLayout(context, attrs, defStyleAttr), IMoGoSkinModeChangeListener, IViewControlListener { companion object { const val TAG = "StatusBarView" @@ -37,17 +38,19 @@ class StatusBarView @JvmOverloads constructor( override fun onAttachedToWindow() { super.onAttachedToWindow() viewStatusBarRight.addView(BatteryGroupView(this.context)) - - //将状态窗口中的状态移到状态栏上 - CallerDevaToolsManager.showStatusBar(context, status_container) - - // 添加换肤监听 - CallerSkinModeListenerManager.addListener(TAG, this) - - var isBluetoothConnect = SharedPrefsMgr.getInstance(context).getBoolean(MfConstants.BLUETOOTH_STATUS, false) + val isBluetoothConnect = + SharedPrefsMgr.getInstance(context).getBoolean(MfConstants.BLUETOOTH_STATUS, false) if (isBluetoothConnect) { updateMfStatus("MoFangManager", true) } + + //添加view控制 + CallerHmiViewControlListenerManager.addListener(TAG,this) + // 添加换肤监听 + CallerSkinModeListenerManager.addListener(TAG, this) + //将状态窗口中的状态移到状态栏上 + CallerDevaToolsManager.showStatusBar(context, status_container) + } override fun onSkinModeChange(skinMode: Int) { @@ -57,15 +60,13 @@ class StatusBarView @JvmOverloads constructor( } } - fun setStatusBarDarkOrLight(light: Boolean) { - if (light) { - setTextColor(resources.getColor(R.color.color_2C2E30)) - } else { - setTextColor(resources.getColor(R.color.color_FFFFFF)) - } + override fun setStatusBarDarkOrLight(light: Boolean) = if (light) { + setTextColor(resources.getColor(R.color.color_2C2E30)) + } else { + setTextColor(resources.getColor(R.color.color_FFFFFF)) } - fun updateRightView(insert: Boolean, tag: String, viewGroup: ViewGroup) { + override fun updateStatusBarRightView(insert: Boolean, tag: String, viewGroup: ViewGroup) { if (insert) { rightViewList.add(0, tag) viewStatusBarRight.addView(viewGroup, 0) @@ -79,7 +80,7 @@ class StatusBarView @JvmOverloads constructor( } } - fun updateLeftView(insert: Boolean, tag: String, viewGroup: ViewGroup) { + override fun updateStatusBarLeftView(insert: Boolean, tag: String, viewGroup: ViewGroup) { if (insert) { leftViewList.add(0, tag) viewStatusBarLeft.addView(viewGroup, 0) @@ -93,7 +94,8 @@ class StatusBarView @JvmOverloads constructor( } } - fun updateProgressView(insert: Boolean, tag: String, progress: Int) { + @SuppressLint("SetTextI18n") + override fun updateStatusBarDownloadView(insert: Boolean, tag: String, progress: Int) { if (insert) { viewProgressTv.visibility = VISIBLE viewProgressTv.text = "$progress%" @@ -102,7 +104,7 @@ class StatusBarView @JvmOverloads constructor( } } - fun updateMfStatus(tag: String, status: Boolean) { + override fun updateMfStatus(tag: String, status: Boolean) { if (status) { viewMofangStatus.setImageResource(R.drawable.icon_bluetooth_p) } else { @@ -117,6 +119,7 @@ class StatusBarView @JvmOverloads constructor( override fun onDetachedFromWindow() { super.onDetachedFromWindow() + CallerHmiViewControlListenerManager.removeListener(TAG) CallerSkinModeListenerManager.removeListener(TAG) CallerDevaToolsManager.hideStatusBar() } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainActivity.java b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainActivity.java index a2356977c8..236a908598 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainActivity.java +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainActivity.java @@ -39,6 +39,7 @@ import com.mogo.eagle.core.data.config.HdMapBuildConfig; import com.mogo.eagle.core.data.constants.MoGoFragmentPaths; import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener; import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager; +import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager; import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager; import com.mogo.eagle.core.function.hmi.R; import com.mogo.eagle.core.function.hmi.ui.widget.StatusBarView; @@ -137,7 +138,7 @@ public class MainActivity extends MvpActivity implement View statusBarView = decorView.findViewWithTag("status_bar"); if (statusBarView == null) { - statusBarView = new StatusBarView(this); + statusBarView = getStatusBarView(); statusBarView.setTag("status_bar"); } FrameLayout.LayoutParams statusBarLP = @@ -147,6 +148,14 @@ public class MainActivity extends MvpActivity implement decorView.addView(statusBarView, statusBarLP); } + /** + * 修改statusBar 重写实现,需要继承 StatusBarView,xml中基础系统控件不要修改其id,拿来即用 + * @return StatusBarView + */ + protected StatusBarView getStatusBarView(){ + return new StatusBarView(this); + } + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -163,6 +172,9 @@ public class MainActivity extends MvpActivity implement DisplayEffectsHelper.getInstance().init(clSpecialEffect); mPresenter.checkPermission(this); + + // 同步AppInfo Config信息 + CallerDevaToolsManager.INSTANCE.syncConfig(); } private void calculateStartTime() { diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java index 1424238667..075c51f3b5 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java @@ -213,13 +213,13 @@ public abstract class MainMoGoApplication extends AbsMogoApplication { MogoModulePaths.addModuleFunctionServer(new MogoModule(MogoServicePaths.PATH_V2X_OBU_MOGO, "IMoGoObuProvider")); // BIZ MogoModulePaths.addModuleFunctionServer(new MogoModule(MogoServicePaths.PATH_FUNC_BIZ, "IMoGoNoticeProvider")); - // 车聊聊,IM + // todo 后置 车聊聊,IM MogoModulePaths.addModuleFunctionServer(new MogoModule(ChatConsts.CHAT_PROVIDER_PATH, ChatConsts.CHAT_MODULE_NAME)); // V2X 模块 MogoModulePaths.addBaseModule(new MogoModule(MogoServicePaths.PATH_V2X_MODULE, "V2XProvider")); - // 司机身份专属模块 + // 司机身份专属 if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { - // 地图数据收集模块 + // todo 后置 地图数据收集模块 MogoModulePaths.addModuleFunctionServer(new MogoModule(MogoServicePaths.PATH_MAP_DATA_COLLECT_PROVIDER, "MoGoMapDataCollector")); } CallerLogger.INSTANCE.i(M_HMI + TAG, "App launch timer cost " + (System.currentTimeMillis() - start) + "ms"); diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml index e36325e31c..2a527c3329 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml @@ -28,26 +28,15 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:paddingTop="72dp"> - - + - - - - - - - - - + - - - - @@ -102,7 +79,8 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" /> - + - - - - - - - - - - @@ -245,7 +175,7 @@ android:layout_width="864px" android:layout_height="wrap_content" android:layout_marginEnd="40dp" - android:visibility="gone" + android:visibility="visible" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/cbMsgBoxDriver" /> @@ -289,6 +219,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + () { + + /** + * 触发 view 显示隐藏 + * @param v 显示/隐藏状态 + */ + fun invokeVisible(tag: String, v: Int) { + M_LISTENERS[tag]?.visible(v) + } + + fun setStatusBarDarkOrLight(tag: String, light: Boolean) { + M_LISTENERS[tag]?.setStatusBarDarkOrLight(light) + } + + fun updateStatusBarRightView( + tag: String, + insert: Boolean, + viewTag: String, + viewGroup: ViewGroup + ) { + M_LISTENERS[tag]?.updateStatusBarRightView(insert, tag, viewGroup) + } + + fun updateStatusBarLeftView( + tag: String, + insert: Boolean, + viewTag: String, + viewGroup: ViewGroup + ) { + M_LISTENERS[tag]?.updateStatusBarLeftView(insert, tag, viewGroup) + } + + fun updateStatusBarDownloadView(tag: String, insert: Boolean, viewTag: String, progress: Int) { + M_LISTENERS[tag]?.updateStatusBarDownloadView(insert, tag, progress) + } + + fun updateMfStatus(tag: String, viewTag: String, status: Boolean) { + M_LISTENERS[tag]?.updateMfStatus(viewTag, status) + } + +} \ No newline at end of file diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/constants/HostConst.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/constants/HostConst.java index 7268dcf889..36ffa13fce 100644 --- a/foudations/mogo-commons/src/main/java/com/mogo/commons/constants/HostConst.java +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/constants/HostConst.java @@ -20,8 +20,8 @@ public class HostConst { public static final String CMDB_HOST = "http://eagle-mis.zhidaozhixing.com/eagleEye-mis/cmdbapi/"; - public static final String HOST_DEV = "https://eagle-qa.zhidaozhixing.com"; - public static final String HOST_RELEASE = "https://eagle-mis.zhidaozhixing.com"; + public static final String HOST_DEV = "http://eagle-qa.zhidaozhixing.com"; + public static final String HOST_RELEASE = "http://eagle-mis.zhidaozhixing.com"; public static final String HOST_EAGLE_QA = "http://eagle-dns-qa.zhidaozhixing.com/"; From b60fbb261309b7cb10651614bbf21da32f8cdfec Mon Sep 17 00:00:00 2001 From: lixiaopeng Date: Sun, 29 Jan 2023 17:23:41 +0800 Subject: [PATCH 03/48] =?UTF-8?q?=E5=90=88=E5=B9=B62.13.2=E7=9A=84obu?= =?UTF-8?q?=E9=AA=8C=E6=94=B6=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/SweeperLimitingVelocityView.java | 4 +- .../sweeper/view/SweeperTrafficDataView.java | 150 ++-- .../eagle/function/biz/FuncBizProvider.kt | 2 + .../v2x/speedlimit/SpeedLimitDataManager.java | 7 +- .../v2x/speedlimit/SpeedLimitDispatcher.kt | 70 ++ .../core/TrafficLightDispatcher.kt | 141 ++-- .../autopilot/adapter/MoGoAdasListenerImpl.kt | 4 +- .../V2XLimitingVelocityBroadcastReceiver.kt | 2 +- .../receiver/V2XWarningBroadcastReceiver.kt | 2 +- .../core/function/hmi/ui/MoGoHmiFragment.kt | 16 +- .../function/hmi/ui/setting/SOPSettingView.kt | 2 + .../hmi/ui/widget/LimitingVelocityView.kt | 4 +- .../src/main/res/layout/fragment_hmi.xml | 15 + .../obu/mogo/MogoObuDcCombineManager.kt | 667 +++++++++++++++++ .../obu/mogo/MogoPrivateObuNewManager.kt | 671 +++++++++++------- .../eagle/core/data/enums/EventTypeEnumNew.kt | 71 +- .../api/hmi/view/IViewLimitingVelocity.kt | 2 +- .../api/hmi/warning/IMoGoHmiProvider.kt | 2 +- .../api/obu/IMoGoObuTrafficLightListener.kt | 15 + .../obucombine/IMoGoObuDcCombineListener.kt | 17 + .../api/v2x/ObuLimitingSpeedListener.kt | 8 + .../function/call/hmi/CallerHmiManager.kt | 7 +- .../CallerObuTrafficLightListenerManager.kt | 25 + .../CallerObuDcCombineListenerManager.kt | 66 ++ .../CallObuLimitingSpeedListenerManager.kt | 26 + .../v2x_icon_jingzhi_zhangai.png | Bin 0 -> 16798 bytes 26 files changed, 1577 insertions(+), 419 deletions(-) create mode 100644 core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDispatcher.kt create mode 100644 core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoObuDcCombineManager.kt create mode 100644 core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/obu/IMoGoObuTrafficLightListener.kt create mode 100644 core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/obucombine/IMoGoObuDcCombineListener.kt create mode 100644 core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/ObuLimitingSpeedListener.kt create mode 100644 core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/obu/CallerObuTrafficLightListenerManager.kt create mode 100644 core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/obucombine/CallerObuDcCombineListenerManager.kt create mode 100644 core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallObuLimitingSpeedListenerManager.kt create mode 100644 core/mogo-core-res/src/main/res/drawable-xhdpi/v2x_icon_jingzhi_zhangai.png diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperLimitingVelocityView.java b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperLimitingVelocityView.java index a0ac193c03..b8831bae9f 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperLimitingVelocityView.java +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperLimitingVelocityView.java @@ -22,8 +22,8 @@ public class SweeperLimitingVelocityView extends IViewLimitingVelocity { initView(context); } @Override - public void updateLimitingSpeed(int limitingSpeed) { - super.updateLimitingSpeed(limitingSpeed); + public void updateLimitingSpeed(int limitingSpeed, int limitSource) { + super.updateLimitingSpeed(limitingSpeed, limitSource); limitingVelocity.setText(String.valueOf(limitingSpeed)); } private void initView(@NonNull Context context) { diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java index 4164276bcf..7546c63533 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java @@ -20,8 +20,8 @@ import org.jetbrains.annotations.NotNull; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.constraintlayout.widget.ConstraintLayout; -import chassis.Chassis; -import chassis.VehicleStateOuterClass; +//import chassis.Chassis; +//import chassis.VehicleStateOuterClass; public class SweeperTrafficDataView extends ConstraintLayout { private static final String TAG = "SweeperTrafficDataView"; @@ -70,84 +70,84 @@ public class SweeperTrafficDataView extends ConstraintLayout { CallLimitingVelocityListenerManager.INSTANCE.removeListener(limitingVelocityListener); } private final IMoGoAutopilotVehicleStateListener mIMoGoAutopilotVehicleStateListener = new IMoGoAutopilotVehicleStateListener() { - @Override - public void onSweeperFutianCleanSystemState(@NonNull VehicleStateOuterClass.SweeperFuTianCleanSystemState cleanSystemState) { - } - - /** - * 车辆转向灯 - * @param lightSwitch - */ - @Override - public void onAutopilotLightSwitchData(@org.jetbrains.annotations.Nullable Chassis.LightSwitch lightSwitch) { - //转向灯状态 0是正常 1是左转 2是右转 - if (lightSwitch != null) { - CallerLogger.INSTANCE.d(TAG, "车辆转向灯:" + lightSwitch.toString()); - if (lightSwitch.getNumber()==1){ - sweeperTurnSignal.showLeftSignal(); - }else if(lightSwitch.getNumber()==2){ - sweeperTurnSignal.showRightSignal(); - }else{ - sweeperTurnSignal.showDirection(); - } - } - } - - /** - * 刹车灯 - * @param brakeLight - */ - @Override - public void onAutopilotBrakeLightData(boolean brakeLight) { - CallerLogger.INSTANCE.d(TAG, "刹车灯:" + brakeLight); - } - - /** - * 方向盘转向角 左+右- - * @param steering - */ - @Override - public void onAutopilotSteeringData(float steering) { - CallerLogger.INSTANCE.d(TAG, "steering原始值====" + steering); - if (Math.abs(steering) < 1) { - steering = 0; - } - CallerLogger.INSTANCE.d(TAG, "steering忽略小数点后====" + (int) steering); - } - - /** - * 档位 - * @param gear - */ - @Override - public void onAutopilotGearData(@NotNull Chassis.GearPosition gear) { - CallerLogger.INSTANCE.d(TAG, "司机屏档位" + gear.toString()); - ThreadUtils.runOnUiThread(() -> { - if (tapPositionView != null) { - tapPositionView.updateWithGear(gear); - } - }); - } +// @Override +// public void onSweeperFutianCleanSystemState(@NonNull VehicleStateOuterClass.SweeperFuTianCleanSystemState cleanSystemState) { +// } +// +// /** +// * 车辆转向灯 +// * @param lightSwitch +// */ +// @Override +// public void onAutopilotLightSwitchData(@org.jetbrains.annotations.Nullable Chassis.LightSwitch lightSwitch) { +// //转向灯状态 0是正常 1是左转 2是右转 +// if (lightSwitch != null) { +// CallerLogger.INSTANCE.d(TAG, "车辆转向灯:" + lightSwitch.toString()); +// if (lightSwitch.getNumber()==1){ +// sweeperTurnSignal.showLeftSignal(); +// }else if(lightSwitch.getNumber()==2){ +// sweeperTurnSignal.showRightSignal(); +// }else{ +// sweeperTurnSignal.showDirection(); +// } +// } +// } +// +// /** +// * 刹车灯 +// * @param brakeLight +// */ +// @Override +// public void onAutopilotBrakeLightData(boolean brakeLight) { +// CallerLogger.INSTANCE.d(TAG, "刹车灯:" + brakeLight); +// } +// +// /** +// * 方向盘转向角 左+右- +// * @param steering +// */ +// @Override +// public void onAutopilotSteeringData(float steering) { +// CallerLogger.INSTANCE.d(TAG, "steering原始值====" + steering); +// if (Math.abs(steering) < 1) { +// steering = 0; +// } +// CallerLogger.INSTANCE.d(TAG, "steering忽略小数点后====" + (int) steering); +// } +// +// /** +// * 档位 +// * @param gear +// */ +// @Override +// public void onAutopilotGearData(@NotNull Chassis.GearPosition gear) { +// CallerLogger.INSTANCE.d(TAG, "司机屏档位" + gear.toString()); +// ThreadUtils.runOnUiThread(() -> { +// if (tapPositionView != null) { +// tapPositionView.updateWithGear(gear); +// } +// }); +// } @Override public void onAutopilotDataException(long timestamp) { } - @Override - public void onAutopilotAcc(float carAcc) { - - } - - @Override - public void onAutopilotBrake(float brake) { - CallerLogger.INSTANCE.d(TAG, "刹车:" + brake); - } - - @Override - public void onAutopilotThrottle(float throttle) { - CallerLogger.INSTANCE.d(TAG, "油门:" + throttle); - } +// @Override +// public void onAutopilotAcc(float carAcc) { +// +// } +// +// @Override +// public void onAutopilotBrake(float brake) { +// CallerLogger.INSTANCE.d(TAG, "刹车:" + brake); +// } +// +// @Override +// public void onAutopilotThrottle(float throttle) { +// CallerLogger.INSTANCE.d(TAG, "油门:" + throttle); +// } }; /** @@ -158,7 +158,7 @@ public class SweeperTrafficDataView extends ConstraintLayout { @Override public void onLimitingVelocityChange(int limitingVelocity) { //设置限速 - sweeperLimitingVelocity.updateLimitingSpeed(limitingVelocity); + sweeperLimitingVelocity.updateLimitingSpeed(limitingVelocity, 0); //此处小兵合并下 } }; /** diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/FuncBizProvider.kt b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/FuncBizProvider.kt index f0ba86b92a..528509bea4 100644 --- a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/FuncBizProvider.kt +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/FuncBizProvider.kt @@ -11,6 +11,7 @@ import com.mogo.eagle.function.biz.monitoring.CronTaskManager.Companion.cronTask import com.mogo.eagle.function.biz.notice.NoticeSocketManager.Companion.noticeSocketManager import com.mogo.eagle.function.biz.notice.network.NoticeNetWorkManager import com.mogo.eagle.function.biz.v2x.speedlimit.SpeedLimitDataManager +import com.mogo.eagle.function.biz.v2x.speedlimit.SpeedLimitDispatcher import com.mogo.eagle.function.biz.v2x.trafficlight.core.MogoTrafficLightManager import com.mogo.eagle.function.biz.v2x.trafficlight.core.TrafficLightDispatcher import com.mogo.eagle.function.biz.v2x.vip.VipCarManager @@ -30,6 +31,7 @@ class FuncBizProvider : IMoGoFuncBizProvider { TrafficLightDispatcher.INSTANCE.initServer(context) //todo 红绿灯中心模块放入dataCenter VipCarManager.INSTANCE.initServer(context) SpeedLimitDataManager.getInstance().start() + SpeedLimitDispatcher.INSTANCE.initLimit(context) // RedLightWarningManager.INSTANCE.listenTrafficLight() } diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDataManager.java b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDataManager.java index 6c00429fd9..c3e3ffedb3 100644 --- a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDataManager.java +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDataManager.java @@ -61,15 +61,16 @@ public class SpeedLimitDataManager implements IMoGoChassisLocationGCJ02Listener @BizConfig(biz = V2I, dependentBizNode = "", bizNode = BIZ_SLW) private void getSpeedLimit() { - if (!isShowObuLimitSpeedView) { +// if (!isShowObuLimitSpeedView) { int speedLimit = CallerMapUIServiceManager.INSTANCE.getMapUIController().getLimitSpeed(mLocation.getLongitude(), mLocation.getLatitude(), (float) mLocation.getHeading()); UiThreadHandler.post(() -> { if (speedLimit > 0) { - CallerHmiManager.INSTANCE.showLimitingVelocity(speedLimit); +// CallerHmiManager.INSTANCE.showLimitingVelocity(speedLimit, 1); CallLimitingVelocityListenerManager.INSTANCE.invokeOnLimitingVelocityChange(speedLimit); + } }); - } +// } } } diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDispatcher.kt b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDispatcher.kt new file mode 100644 index 0000000000..c236c2ed0e --- /dev/null +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDispatcher.kt @@ -0,0 +1,70 @@ +package com.mogo.eagle.function.biz.v2x.speedlimit + +import android.content.Context +import com.mogo.eagle.core.function.api.v2x.LimitingVelocityListener +import com.mogo.eagle.core.function.api.v2x.ObuLimitingSpeedListener +import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager +import com.mogo.eagle.core.function.call.hmi.CallerHmiManager +import com.mogo.eagle.core.function.call.trafficlight.CallerTrafficLightListenerManager +import com.mogo.eagle.core.function.call.v2x.CallLimitingVelocityListenerManager +import com.mogo.eagle.core.function.call.v2x.CallObuLimitingSpeedListenerManager + +/** + * @author lixiaopeng + * @description 对多个限速进行调度(map,rsu ...) + * @since: 2023/1/12 + */ +class SpeedLimitDispatcher : LimitingVelocityListener, ObuLimitingSpeedListener { + companion object { + const val TAG = "SpeedLimitDispatcher" + val INSTANCE: SpeedLimitDispatcher by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { + SpeedLimitDispatcher() + } + } + + private var mContext: Context? = null + + //是否有AI获取红绿灯灯态 + private var hasObuStatus: Boolean = false + + + fun initLimit(context: Context) { + mContext = context + //注册监听MAP的限速 + CallLimitingVelocityListenerManager.addListener(TAG, this) + //注册监听OBU的限速 + CallObuLimitingSpeedListenerManager.addListener(TAG, this) + } + + /** + * 地图限速数据 + */ + override fun onLimitingVelocityChange(limitingVelocity: Int) { +// CallerHmiManager.disableLimitingVelocity() + if (!hasObuStatus) { + CallerHmiManager.showLimitingVelocity(limitingVelocity, 1) + } + } + + /** + * obu限速 + */ + override fun onObuLimitingSpeedChange(limitingSpeed: Int) { +// CallerHmiManager.disableLimitingVelocity() + if (limitingSpeed > 0) { + hasObuStatus = true + CallerHmiManager.showLimitingVelocity(limitingSpeed, 2) + } else { + hasObuStatus = false + CallerHmiManager.disableLimitingVelocity() + } + } + + fun destroy() { + //取消注册监听AI云获取红绿灯状态 + CallerTrafficLightListenerManager.removeListener(TAG) + //取消注册监听工控机感知红绿灯 + CallerAutopilotIdentifyListenerManager.removeListener(TAG) + } + +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/trafficlight/core/TrafficLightDispatcher.kt b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/trafficlight/core/TrafficLightDispatcher.kt index 2b9099ee0f..2e65445525 100644 --- a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/trafficlight/core/TrafficLightDispatcher.kt +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/trafficlight/core/TrafficLightDispatcher.kt @@ -4,9 +4,11 @@ import android.content.Context import android.os.Handler import com.mogo.eagle.core.data.trafficlight.TrafficLightResult import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotIdentifyListener +import com.mogo.eagle.core.function.api.obu.IMoGoObuTrafficLightListener import com.mogo.eagle.core.function.api.trafficlight.IMoGoTrafficLightListener import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager import com.mogo.eagle.core.function.call.hmi.CallerHmiManager +import com.mogo.eagle.core.function.call.obu.CallerObuTrafficLightListenerManager import com.mogo.eagle.core.function.call.trafficlight.CallerTrafficLightListenerManager import com.mogo.eagle.function.biz.v2x.trafficlight.TrafficLightHMIManager import perception.TrafficLightOuterClass @@ -17,26 +19,36 @@ import perception.TrafficLightOuterClass.TrafficLight * @description 对多个红绿灯信号来源进行统一调度(AI云、工控机) * @since: 2022/4/28 */ -class TrafficLightDispatcher : IMoGoAutopilotIdentifyListener , IMoGoTrafficLightListener { +class TrafficLightDispatcher : IMoGoAutopilotIdentifyListener, IMoGoTrafficLightListener, + IMoGoObuTrafficLightListener { - companion object{ + companion object { const val TAG = "TrafficLightDispatcher" - val INSTANCE: TrafficLightDispatcher by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){ + val INSTANCE: TrafficLightDispatcher by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { TrafficLightDispatcher() } } private var mContext: Context? = null + //是否有AI获取红绿灯灯态 private var hasAiLightStatus: Boolean = false + //obu数据 + private var hasObuLightStatus: Boolean = false - fun initServer(context: Context){ + fun initServer(context: Context) { mContext = context - //注册监听AI云获取红绿灯状态,注册监听AI云进入路口,注册监听红绿灯请求失败 + //注册监听AI云获取红绿灯状态 + CallerTrafficLightListenerManager.addListener(TAG, this) + //注册监听AI云进入路口 + CallerTrafficLightListenerManager.addListener(TAG, this) + //注册监听红绿灯请求失败 CallerTrafficLightListenerManager.addListener(TAG, this) //注册监听工控机感知红绿灯 CallerAutopilotIdentifyListenerManager.addListener(TAG, this) + //obu红绿灯数据 + CallerObuTrafficLightListenerManager.addListener(TAG, this) } /** @@ -44,46 +56,48 @@ class TrafficLightDispatcher : IMoGoAutopilotIdentifyListener , IMoGoTrafficLigh * @param trafficLights 感知红绿灯 */ override fun onAutopilotPerceptionTrafficLight(trafficLights: TrafficLightOuterClass.TrafficLights?) { - if(!hasAiLightStatus){ - trafficLights?.let { it -> - var light :TrafficLight?= null - if(it.hasStraight()){ - light = it.straight - }else if(it.hasLeft()){ - light = it.left - }else if(it.hasRight()){ - light = it.right - }else if(it.hasUTurn()){ - light = it.uTurn - } - if(light == null){ - //隐藏红绿灯显示 - TrafficLightHMIManager.INSTANCE.hideTrafficLight() - }else{ - when (light.state) { - TrafficLightOuterClass.LightState.STATE_RED -> { - //红灯 - CallerHmiManager.showWarningTrafficLight(1,2) - CallerHmiManager.changeCountdownGreen(0) - } - TrafficLightOuterClass.LightState.STATE_YELLOW -> { - //黄灯 - CallerHmiManager.showWarningTrafficLight(2,2) - CallerHmiManager.changeCountdownGreen(0) - } - TrafficLightOuterClass.LightState.STATE_GREEN -> { - //绿灯 - CallerHmiManager.showWarningTrafficLight(3,2) - CallerHmiManager.changeCountdownGreen(0) - } - TrafficLightOuterClass.LightState.STATE_OFF -> { - //黑灯,隐藏红绿灯显示 - TrafficLightHMIManager.INSTANCE.hideTrafficLight() - } - else -> {} + if (!hasObuLightStatus) { + if (!hasAiLightStatus) { + trafficLights?.let { it -> + var light: TrafficLight? = null + if (it.hasStraight()) { + light = it.straight + } else if (it.hasLeft()) { + light = it.left + } else if (it.hasRight()) { + light = it.right + } else if (it.hasUTurn()) { + light = it.uTurn + } + if (light == null) { + //隐藏红绿灯显示 + TrafficLightHMIManager.INSTANCE.hideTrafficLight() + } else { + when (light.state) { + TrafficLightOuterClass.LightState.STATE_RED -> { + //红灯 + CallerHmiManager.showWarningTrafficLight(1, 2) + CallerHmiManager.changeCountdownGreen(0) + } + TrafficLightOuterClass.LightState.STATE_YELLOW -> { + //黄灯 + CallerHmiManager.showWarningTrafficLight(2, 2) + CallerHmiManager.changeCountdownGreen(0) + } + TrafficLightOuterClass.LightState.STATE_GREEN -> { + //绿灯 + CallerHmiManager.showWarningTrafficLight(3, 2) + CallerHmiManager.changeCountdownGreen(0) + } + TrafficLightOuterClass.LightState.STATE_OFF -> { + //黑灯,隐藏红绿灯显示 + TrafficLightHMIManager.INSTANCE.hideTrafficLight() + } + else -> {} + } } - } + } } } } @@ -92,21 +106,28 @@ class TrafficLightDispatcher : IMoGoAutopilotIdentifyListener , IMoGoTrafficLigh * AI云获取红绿灯状态 */ override fun onTrafficLightStatus(trafficLightResult: TrafficLightResult) { - TrafficLightHMIManager.INSTANCE.updateTrafficLight(trafficLightResult) - hasAiLightStatus = true + if (!hasObuLightStatus) { + TrafficLightHMIManager.INSTANCE.updateTrafficLight(trafficLightResult) + hasAiLightStatus = true + } } /** - * 车辆进入路口 + * 车辆进入路口回调 + * @param enter true:进入路口;false:离开路口 */ override fun onEnterCrossRoad(enter: Boolean) { - if(!enter){ + if (!enter) { Handler().postDelayed({ hasAiLightStatus = false + hasObuLightStatus = false }, 5000) + CallerTrafficLightListenerManager.resetTrafficLightData() + //如果没有OBU灯态则进行隐藏,如果有OBU灯态,则交由OBU管理 + if(!hasObuLightStatus){ + TrafficLightHMIManager.INSTANCE.hideTrafficLight() + } } - - } /** @@ -114,14 +135,32 @@ class TrafficLightDispatcher : IMoGoAutopilotIdentifyListener , IMoGoTrafficLigh */ override fun onTrafficRequestError() { hasAiLightStatus = false + CallerTrafficLightListenerManager.resetTrafficLightData() + if(!hasObuLightStatus){ + if (TrafficLightHMIManager.INSTANCE.isWarningTrafficLightShow()) { + TrafficLightHMIManager.INSTANCE.hideTrafficLight() + } + } } + /** + * obu 红绿灯数据 + */ + override fun onObuTrafficLight(light: Int) { + super.onObuTrafficLight(light) + hasObuLightStatus = true + CallerHmiManager.showWarningTrafficLight(light, 3) + } - fun destroy(){ - //取消注册监听AI云获取红绿灯状态,取消注册监听红绿灯请求失败,取消注册监听AI云进入路口 + fun destroy() { + //取消注册监听AI云获取红绿灯状态 CallerTrafficLightListenerManager.removeListener(TAG) //取消注册监听工控机感知红绿灯 CallerAutopilotIdentifyListenerManager.removeListener(TAG) + //取消注册监听红绿灯请求失败 + CallerTrafficLightListenerManager.removeListener(TAG) + //取消注册监听AI云进入路口 + CallerTrafficLightListenerManager.removeListener(TAG) } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/adapter/MoGoAdasListenerImpl.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/adapter/MoGoAdasListenerImpl.kt index f311626dca..73a16dfd68 100644 --- a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/adapter/MoGoAdasListenerImpl.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/adapter/MoGoAdasListenerImpl.kt @@ -52,6 +52,7 @@ import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListener import com.mogo.eagle.core.function.call.autopilot.CallerPlanningTrajectoryListenerManager.invokeAutopilotTrajectory import com.mogo.eagle.core.function.call.autopilot.CallerStartAutopilotFailedListenerManager.invokeStartAutopilotFailed import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager +import com.mogo.eagle.core.function.call.obucombine.CallerObuDcCombineListenerManager import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.Logger import com.zhidao.support.adas.high.AdasManager @@ -533,8 +534,9 @@ class MoGoAdasListenerImpl : OnAdasListener { * @param obuWarningData 数据 */ override fun onObuWarningData(header: MessagePad.Header?, obuWarningData: ObuWarningEvent.ObuWarningData?) { - + CallerObuDcCombineListenerManager.invokeObuDcData(obuWarningData) } + /** * 重构后的功能状态 * diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XLimitingVelocityBroadcastReceiver.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XLimitingVelocityBroadcastReceiver.kt index e8d3961a3e..1395d3578f 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XLimitingVelocityBroadcastReceiver.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XLimitingVelocityBroadcastReceiver.kt @@ -57,7 +57,7 @@ class V2XLimitingVelocityBroadcastReceiver : BroadcastReceiver() { * @param limitingVelocitySpeed 限速速度 */ private fun dispatchShowWaring(limitingVelocitySpeed: Int) { - CallerHmiManager.showLimitingVelocity(limitingVelocitySpeed) + CallerHmiManager.showLimitingVelocity(limitingVelocitySpeed, 1) } /** diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XWarningBroadcastReceiver.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XWarningBroadcastReceiver.kt index 6207e5eb1b..3a60406e12 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XWarningBroadcastReceiver.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XWarningBroadcastReceiver.kt @@ -76,7 +76,7 @@ class V2XWarningBroadcastReceiver : BroadcastReceiver() { tag: String? ) { if (EventTypeEnum.TYPE_USECASE_ID_IVP.poiType == v2xType.toString()) { - CallerHmiManager.showLimitingVelocity(1) + CallerHmiManager.showLimitingVelocity(1, 1) } if (alertContent.isNullOrEmpty() || ttsContent.isNullOrEmpty()) { Log.d("MsgBox-V2XWarningBR", "alertContent或ttsContent为空!") diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt index 3524050b7d..1553ac9c9b 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt @@ -663,18 +663,26 @@ class MoGoHmiFragment : MvpFragment(), /** * 控制展示限速标志及内容 */ - override fun showLimitingVelocity(limitingSpeed: Int) { + override fun showLimitingVelocity(limitingSpeed: Int, limitSpeedSource: Int) { // 控制 限速UI 展示 if (HmiBuildConfig.isShowLimitingVelocityView) { if (limitingSpeed > 0) { mViewLimitingVelocity?.visibility = View.VISIBLE - mViewLimitingVelocity?.updateLimitingSpeed(limitingSpeed) + mViewLimitingVelocity?.updateLimitingSpeed(limitingSpeed, limitSpeedSource) + tvLimitingSource?.visibility = View.VISIBLE + if (limitSpeedSource == 1) { + tvLimitingSource.text = "MAP" + } else if (limitSpeedSource == 2) { + tvLimitingSource.text = "RSU" + } } else { mViewLimitingVelocity?.visibility = View.INVISIBLE - mViewLimitingVelocity?.updateLimitingSpeed(0) + mViewLimitingVelocity?.updateLimitingSpeed(0, limitSpeedSource) + tvLimitingSource?.visibility = View.INVISIBLE } } else { disableLimitingVelocity() + tvLimitingSource?.visibility = View.GONE } } @@ -683,7 +691,7 @@ class MoGoHmiFragment : MvpFragment(), */ override fun disableLimitingVelocity() { mViewLimitingVelocity?.visibility = View.GONE - mViewLimitingVelocity?.updateLimitingSpeed(0) + mViewLimitingVelocity?.updateLimitingSpeed(0, 1) } /** diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/SOPSettingView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/SOPSettingView.kt index 0227d92b75..e6afb2b7b2 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/SOPSettingView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/SOPSettingView.kt @@ -78,6 +78,7 @@ internal class SOPSettingView @JvmOverloads constructor( /** * obu弱势交通控制 */ + tbObuWeaknessTrafficSop.isChecked = HmiBuildConfig.isShowObuWeaknessTrafficView tbObuWeaknessTrafficSop.setOnCheckedChangeListener { _, isChecked -> if (!isChecked) { //默认开启 CallerHmiManager.setObuWeaknessTraffic(true) @@ -89,6 +90,7 @@ internal class SOPSettingView @JvmOverloads constructor( /** * 云端弱势交通控制 */ + tbCloudWeaknessTrafficSop.isChecked = HmiBuildConfig.isShowCloudWeaknessTrafficView tbCloudWeaknessTrafficSop.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { //默认关闭 CallerHmiManager.setCloudWeaknessTraffic(true) diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/LimitingVelocityView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/LimitingVelocityView.kt index b1c509d6f2..c766f7a029 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/LimitingVelocityView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/LimitingVelocityView.kt @@ -20,8 +20,8 @@ class LimitingVelocityView @JvmOverloads constructor( LayoutInflater.from(context).inflate(R.layout.view_limiting_speed_vr, this, true) } - override fun updateLimitingSpeed(limitingSpeed: Int) { - super.updateLimitingSpeed(limitingSpeed) + override fun updateLimitingSpeed(limitingSpeed: Int, limitSource: Int) { + super.updateLimitingSpeed(limitingSpeed, limitSource) tvLimitingVelocity.text = "$limitingSpeed" } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml index e36325e31c..652f98f0f9 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml @@ -179,6 +179,21 @@ app:layout_goneMarginTop="40dp" tools:visibility="gone" /> + + + { //rsiEvent + onMogoObuDcRsiWarning(obuWarningData.rsiEvent) + } + + 2 -> { //RsmEvent + onMogoObuDcRsmWarning(obuWarningData.rsmEvent) + } + + 3 -> { //SpatEvent + onMogoObuDcSpatWarning(obuWarningData.spatEvent) + } + + 4 -> { //map + onMogoObuMapMath(obuWarningData.mapMatchData) + } + } + } + + } + + /** + * RSI预警信息 CvxRtiThreatIndInfo(交通标志预警(前方限速、前方学校等等),交通事件预警(前方拥堵、前方积水等等)) + */ + fun onMogoObuDcRsiWarning(rsiWarningData: RsiWarningData?) { + CallerLogger.d( + "${M_OBU}${TAG}", + "MogoObuDcCombineManager onMogoObuRsiWarning ------> ${rsiWarningData.toString()}" + ) + if (rsiWarningData != null && rsiWarningData.warningMsgList != null && rsiWarningData.warningMsgList.size > 0) { + var alertContent = "" + var ttsContent = "" //TODO 列表还是只有一项吗? + var appId = rsiWarningData.warningMsgList[0].sceneType.toString() + val status = rsiWarningData.status + val level = rsiWarningData.warningMsgList[0].warningLevel + val direction = getMessageDirection(rsiWarningData.warningMsgList[0].targetPosition) + CallerLogger.d("${M_OBU}${TAG}", + "MogoObuDcCombineManager onMogoObuDcRsiWarning appId = $appId --status = $status --level = $level -- eventSerialNum = ${rsiWarningData.warningMsgList[0].eventSerialNum} ---signSerialNum = ${rsiWarningData.warningMsgList[0].signSerialNum} --- direction = $direction -- targetPosition = ${rsiWarningData.warningMsgList[0].targetPosition}" + ) + + when (appId) { + // 道路危险情况预警 + MogoObuConstants.RSI_SCENE_TYPE.HLW.toString() -> { + when (rsiWarningData.warningMsgList[0].eventSerialNum) { + MogoObuConstants.RTE.RTI_TYPE_BREAKDOWN -> {//车辆故障 + appId = EventTypeEnumNew.TYPE_USECASE_ID_BREAKDOWN_WARNING.poiType + } + MogoObuConstants.RTE.RTI_TYPE_ROAD_WATER -> { //道路积水 + appId = EventTypeEnumNew.FOURS_PONDING.poiType + } + MogoObuConstants.RTE.RTI_TYPE_PARKING_VIOLATION -> { //异常停车 + appId = EventTypeEnumNew.TYPE_USECASE_ID_ROAD_PARKING.poiType + } +// MogoObuConstants.RTE.RTI_TYPE_CONSTRUCTION_RTE -> { //施工占道,和标牌重复 +// appId = EventTypeEnumNew.FOURS_ROAD_WORK.poiType +// } + MogoObuConstants.RTE.RTI_TYPE_SPEEDING -> { //超速行驶 + appId = EventTypeEnumNew.TYPE_USECASE_ID_SLW.poiType + } + MogoObuConstants.RTE.RTI_TYPE_RETRIGRADE -> { //车辆逆行 + appId = + EventTypeEnumNew.TYPE_USECASE_ID_ROAD_VEHICLE_RETROGRADE.poiType + } + } + alertContent = EventTypeEnumNew.getWarningContent(appId) + ttsContent = EventTypeEnumNew.getWarningTts(appId) + alertContent = String.format( //事件才有影响范围 + alertContent, + Math.round(rsiWarningData.warningMsgList[0].distance / 100.0).toString(), + Math.round(rsiWarningData.warningMsgList[0].eventRadius / 10.0).toString() + ) + ttsContent = String.format( + ttsContent, + Math.round(rsiWarningData.warningMsgList[0].distance / 100.0).toString(), + Math.round(rsiWarningData.warningMsgList[0].eventRadius / 10.0).toString() + ) + } + + //车内标牌 + MogoObuConstants.RSI_SCENE_TYPE.IVS.toString() -> { + when (rsiWarningData.warningMsgList[0].signSerialNum) { +// MogoObuConstants.RTS.RTI_TYPE_INTERSECTION -> { //十字路口 +// appId = V2iEventTypeEnum.TYPE_ID_NTERSECTION.poiType +// } + MogoObuConstants.RTS.RTI_TYPE_SHAPR_TURNS -> { //急转弯 + appId = EventTypeEnumNew.TYPE_ID_SHAPR_TURNS.poiType + } + MogoObuConstants.RTS.RTI_TYPE_BRIDGE -> { //桥梁 + appId = EventTypeEnumNew.TYPE_ID_BRIDGE.poiType + } + MogoObuConstants.RTS.RTI_TYPE_PEDESTRIAN -> { //行人 + appId = EventTypeEnumNew.TYPE_ID_PEDESTRIAN.poiType + } + MogoObuConstants.RTS.RTI_TYPE_SLIPPERY_ROAD -> { //路滑 + appId = EventTypeEnumNew.TYPE_ID_SLIPPERY_ROAD.poiType + } + MogoObuConstants.RTS.RTI_TYPE_TUNNEL -> { //隧道 + appId = EventTypeEnumNew.TYPE_ID_TUNNEL.poiType + } + MogoObuConstants.RTS.RTI_TYPE_FERRY -> { //渡轮 + appId = EventTypeEnumNew.TYPE_ID_FERRY.poiType + } + MogoObuConstants.RTS.RTI_TYPE_UNEVEN_ROAD -> { //路面不平 + appId = EventTypeEnumNew.TYPE_ID_UNEVEN_ROAD.poiType + } + MogoObuConstants.RTS.RTI_TYPE_NON_MOTOR_VEHICLE -> { //非机动车 + appId = EventTypeEnumNew.TYPE_ID_NON_MOTOR_VEHICLE.poiType + } + MogoObuConstants.RTS.RTI_TYPE_OBSTACLE -> { //障碍 + appId = EventTypeEnumNew.TYPE_ID_OBSTACLE.poiType + } + MogoObuConstants.RTS.RTI_TYPE_CONSTRUCTION -> { //施工 + appId = EventTypeEnumNew.TYPE_FOURS_ROAD_WORK.poiType + } + MogoObuConstants.RTS.RTI_TYPE_VEHICLE_QUEUE -> { //车队 + appId = EventTypeEnumNew.TYPE_VEHICLE_QUEUE.poiType + } + MogoObuConstants.RTS.RTI_TYPE_NO_PASSING -> { //不通 + appId = EventTypeEnumNew.TYPE_NO_PASSING.poiType + } + MogoObuConstants.RTS.RTI_TYPE_NO_TURNING_AROUND -> { //禁止掉头 + appId = EventTypeEnumNew.TYPE_NO_TURNING_AROUND.poiType + } + MogoObuConstants.RTS.RTI_TYPE_NO_STOPPING -> { //禁止停车 + appId = EventTypeEnumNew.TYPE_USECASE_ID_ROAD_NO_PARKING.poiType + } + MogoObuConstants.RTS.RTI_TYPE_NO_TOOTING -> { //禁止鸣笛 + appId = EventTypeEnumNew.TYPE_USECASE_ID_ROAD_NO_TOOTING.poiType + } + MogoObuConstants.RTS.RTI_TYPE_SPEED_LIMIT -> { //限速 + appId = EventTypeEnumNew.TYPE_USECASE_ID_ROAD_SPEED_LIMIT.poiType + } +// MogoObuConstants.RTS.RTI_TYPE_GO_STRAIGHT_TURN_RIGHT -> { //直行或右转 +// appId = +// EventTypeEnumNew.TYPE_USECASE_ID_GO_STRAIGHT_TURN_RIGHT.poiType +// } + MogoObuConstants.RTS.RTI_TYPE_BUS_WARNING -> { //公交提醒 + appId = EventTypeEnumNew.TYPE_USECASE_ID_BUS_WARNING.poiType + } + MogoObuConstants.RTS.RTI_TYPE_NARROW_RIGHT -> { //右侧变窄/车道数减少 + appId = EventTypeEnumNew.TYPE_USECASE_ID_NARROW_RIGHT.poiType + } + MogoObuConstants.RTS.RTI_TYPE_GAS_STATION -> { //加油站 + appId = EventTypeEnumNew.TYPE_USECASE_ID_GAS_STATION.poiType + } + MogoObuConstants.RTS.RTI_TYPE_SCHOOL -> { //学校 + appId = + EventTypeEnumNew.TYPE_USECASE_ID_ROAD_PEDESTRIAN_SCHOOL.poiType + } + MogoObuConstants.RTS.RTI_TYPE_ACCIDENT -> { //事故 + appId = EventTypeEnumNew.TYPE_USECASE_ID_ACCIDENT.poiType + } + } + + alertContent = EventTypeEnumNew.getWarningContent(appId) + ttsContent = EventTypeEnumNew.getWarningTts(appId) + alertContent = String.format( //标牌是没有影响范围的 + alertContent, + Math.round(rsiWarningData.warningMsgList[0].distance / 100.0).toString() + ) + ttsContent = String.format( + ttsContent, + Math.round(rsiWarningData.warningMsgList[0].distance / 100.0).toString() + ) + } + + // 拥堵 + MogoObuConstants.RSI_SCENE_TYPE.TJW.toString() -> { + appId = EventTypeEnumNew.TYPE_USECASE_ID_TJW.poiType + alertContent = EventTypeEnumNew.getWarningContent(appId) + ttsContent = EventTypeEnumNew.getWarningTts(appId) + alertContent = String.format( //事件才有影响范围 + alertContent, + Math.round(rsiWarningData.warningMsgList[0].distance / 100.0).toString(), + Math.round(rsiWarningData.warningMsgList[0].eventRadius / 10.0).toString() + ) + ttsContent = String.format( + ttsContent, + Math.round(rsiWarningData.warningMsgList[0].distance / 100.0).toString(), + Math.round(rsiWarningData.warningMsgList[0].eventRadius / 10.0).toString() + ) + } + + //限速预警, ADD处理一次 + MogoObuConstants.RSI_SCENE_TYPE.SLW.toString() -> { + alertContent = EventTypeEnumNew.getWarningContent(appId) + ttsContent = EventTypeEnumNew.getWarningTts(appId) + } + } + + CallerLogger.d( + "${M_OBU}${TAG}", + "MogoObuDcCombineManager ttsContent = $ttsContent --alertContent = $alertContent --appId = $appId ---direction = ${direction.direction} --distance = ${rsiWarningData.warningMsgList[0].distance} ---eventRadius = ${rsiWarningData.warningMsgList[0].eventRadius} --speedMaxLimit = ${rsiWarningData.warningMsgList[0].speedMaxLimit}" + ) + when (status) { + // 添加 + MogoObuConstants.STATUS.ADD -> { + //显示警告红边 + CallerHmiManager.showWarning(direction) + CallerMsgBoxManager.saveMsgBox( + MsgBoxBean( + MsgBoxType.V2X, + V2XMsg( + appId, + alertContent, + ttsContent + ) + ) +// .apply { +// sourceType = DataSourceType.TELEMATIC +// } + ) + CallerHmiManager.warningV2X( + appId, + alertContent, + ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 + (appId + direction.direction),//使用当前事件类型+方向记录tag,当发生变化的时候关闭当前弹出新的 + object : IMoGoWarningStatusListener { + override fun onDismiss() { + // 关闭警告红边 + CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) + } + }, + true, + 5000L + ) + + // 更新数据,是否需要 +// TrafficDataConvertUtilsNew.cvxRtiThreatIndInfo2TrafficData(rsiWarningData)?.let { +// CallerMapUIServiceManager.getMarkerService() +// ?.updateITrafficThreatLevelInfo(it) +// } + } + + MogoObuConstants.STATUS.UPDATE -> { // 更新 + } + + // 删除 + MogoObuConstants.STATUS.DELETE -> { + // 关闭警告红边 +// CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) + // 移除顶部弹窗 + CallerHmiManager.disableWarningV2X((appId + direction.direction)) + // 更新数据,删除标牌? +// TrafficDataConvertUtilsNew.cvxRtiThreatIndInfo2TrafficData(rsiWarningData) +// ?.let { +// // 事件结束,还原车辆颜色 +// it.threatLevel = 0x01 +// CallerMapUIServiceManager.getMarkerService() +// ?.updateITrafficInfo(it) +// } + } + } + } + } + + /** + * RSM预警信息 CvxPtcThreatIndInfo CvxPtcInfoIndInfo(主车与弱势交通参与者之间的预警(如:弱势交通参与者碰撞预警)) + */ + fun onMogoObuDcRsmWarning(rsmWarningData: RsmWarningData?) { + if (HmiBuildConfig.isShowObuWeaknessTrafficView) { + CallerLogger.d( + "${M_OBU}${TAG}", + "MogoObuDcCombineManager onMogoObuRsmWarning ------> ${rsmWarningData.toString()}" + ) + // 交通参与者类型 0x0:未知 UNKNOWN | 1机动车 2:非机动车 NON_MOTOR | 3:行人 PEDESTRIAN 4:obu + if (rsmWarningData != null && rsmWarningData.participantOfOne != null) { + var v2xType = "" + if (rsmWarningData.participantOfOne.ptcType == 1) { //机动车 + v2xType = + EventTypeEnumNew.TYPE_USECASE_ID_VRUCW_MOTOR_VEHICLES.poiType + } else if (rsmWarningData.participantOfOne.ptcType == 2) { //非机动车 + v2xType = + EventTypeEnumNew.TYPE_USECASE_ID_VRUCW_NOT_MOTOR_VEHICLES.poiType + } else if (rsmWarningData.participantOfOne.ptcType == 3) { //行人 + v2xType = + EventTypeEnumNew.TYPE_USECASE_ID_VRUCW_PERSON.poiType + } else { //未知 + v2xType = EventTypeEnumNew.TYPE_ERROR.poiType + } + val ttsContent = EventTypeEnumNew.getWarningTts(v2xType) + val alertContent = + EventTypeEnumNew.getWarningContent(v2xType) + var level = -1 + val direction = + getMessageDirection(rsmWarningData.participantOfOne.targetPosition) //TODO 只有一个 + if (rsmWarningData.warningMsg != null && rsmWarningData.warningMsg.warningDataList != null && rsmWarningData.warningMsg.warningDataList.size > 0) { + level = rsmWarningData.warningMsg.warningDataList[0].warningLevel + CallerLogger.d( + "${M_OBU}${TAG}", + "MogoObuDcCombineManager onMogoObuRsmWarning ---status---> ${rsmWarningData.status} --list status----> ${rsmWarningData.warningMsg.warningDataList.get(0).status} --v2xType--- $v2xType ---alertContent = $alertContent ---ttsContent= $ttsContent" + ) + + when (rsmWarningData.warningMsg.warningDataList.get(0).status) { + MogoObuConstants.STATUS.ADD -> { // 添加 + //显示警告红边 + CallerHmiManager.showWarning(direction) + CallerMsgBoxManager.saveMsgBox( + MsgBoxBean( + MsgBoxType.V2X, + V2XMsg( + v2xType, + alertContent, + ttsContent + ) + ) +// .apply { //TODO +// sourceType = DataSourceType.TELEMATIC +// } + ) + CallerHmiManager.warningV2X( + v2xType, + alertContent, + ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 + (v2xType + direction.direction),//使用当前事件类型+方向记录tag,当发生变化的时候关闭当前弹出新的 + object : IMoGoWarningStatusListener { + override fun onDismiss() { + // 关闭警告红边 + CallerHmiManager.showWarning( + WarningDirectionEnum.ALERT_WARNING_NON + ) + } + }, + true, + 5000L + ) + + // 更新数据 TODO +// TrafficDataConvertUtils.cvxPtcThreatIndInfo2TrafficData(rsmWarningData)?.let { +//// TrafficMarkerDrawer.updateITrafficThreatLevelInfo(it) +// CallerMapUIServiceManager.getMarkerService() +// ?.updateITrafficThreatLevelInfo(it) +// } + } + + MogoObuConstants.STATUS.UPDATE -> {// 更新 + } + + // 删除 + MogoObuConstants.STATUS.DELETE -> { + // 关闭警告红边 + CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) + // 更新数据 TODO 由于obu通过域控需要转换单位,这里临时转换,后面3.0不需要转换 +// TrafficDataConvertUtils.cvxPtcThreatIndInfo2TrafficData(rsmWarningData)?.let { +// // 事件结束,还原交通参与者颜色 +// it.threatLevel = 0x01 +//// TrafficMarkerDrawer.updateITrafficThreatLevelInfo(it) +// CallerMapUIServiceManager.getMarkerService() +// ?.updateITrafficThreatLevelInfo(it) +// } + //删除弱势交通元素 + CallerMapUIServiceManager.getMarkerService() + ?.removeCvxRvInfoIndInfo(rsmWarningData.participantOfOne.ptcID.toString()) +// TrafficMarkerDrawer.removeCvxRvInfoIndInfo(rsmWarningData.participantOfOne.ptcID.toString()) + } + } + } + } + } + + } + + /** + * 红绿灯预警信息 + */ + fun onMogoObuDcSpatWarning(spatWarningData: SpatWarningData?) { + CallerLogger.d("${M_OBU}${TAG}", "onMogoObuDcSpatWarning warningType = ${spatWarningData!!.warningType} --status = ${spatWarningData?.status} --lightsList = ${spatWarningData.lightsList}") + handlerTrafficLight( + spatWarningData!!.warningType, + spatWarningData?.status, + spatWarningData?.lightsList + ) + } + + /** + * 地图匹配 是OBU算法输出地图匹配结果,主车匹配道路哪条路或者哪条车道 + */ + fun onMogoObuMapMath(data: MapMatchData?) { + CallerLogger.d("${M_OBU}${TAG}", "MogoObuDcCombineManager onMogoObuMapMath HmiBuildConfig.isShowObuLimitSpeedView = " + HmiBuildConfig.isShowObuLimitSpeedView) + if(HmiBuildConfig.isShowObuLimitSpeedView) { + if (data != null) { + CallerLogger.d("${M_OBU}${TAG}", + "MogoObuDcCombineManager onMogoObuMapMath = ${data.status} --speedMaxLimit = ${Math.round((data.speedMaxLimit*0.02*3.6))} --- data.speedMaxLimit = ${data.speedMaxLimit}") + when (data.status) { + MogoObuConstants.STATUS.ADD -> { // 添加 TODO + CallerHmiManager.showLimitingVelocity(Math.round((data.speedMaxLimit*0.02*3.6)).toInt(), 2) + } + + MogoObuConstants.STATUS.UPDATE -> { // 更新 + } + + MogoObuConstants.STATUS.DELETE -> { // 删除 + CallerHmiManager.disableLimitingVelocity() + } + } + } + } + } + + /** + * 获取消息的方位 车辆相关 + */ + private fun getMessageDirection(targetClassification: Int): WarningDirectionEnum { + return when (targetClassification) { + MogoObuConstants.VEH_TARGET_POSITION.AHEAD_IN_LANE, + MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_IN_LANE -> WarningDirectionEnum.ALERT_WARNING_TOP //正前方 + + MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_IN_LANE -> WarningDirectionEnum.ALERT_WARNING_BOTTOM //正后方 + + MogoObuConstants.VEH_TARGET_POSITION.INTERSECTION_RIGHT -> WarningDirectionEnum.ALERT_WARNING_RIGHT //正右方 + + MogoObuConstants.VEH_TARGET_POSITION.INTERSECTION_LEFT -> WarningDirectionEnum.ALERT_WARNING_LEFT //正左方 + + MogoObuConstants.VEH_TARGET_POSITION.AHEAD_LEFT, MogoObuConstants.VEH_TARGET_POSITION.AHEAD_FAR_LEFT, + MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_LEFT, MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_FAR_LEFT + -> WarningDirectionEnum.ALERT_WARNING_TOP_LEFT //左前方 + + MogoObuConstants.VEH_TARGET_POSITION.AHEAD_RIGHT, MogoObuConstants.VEH_TARGET_POSITION.AHEAD_FAR_RIGHT, + MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_RIGHT, MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_FAT_RIGHT + -> WarningDirectionEnum.ALERT_WARNING_TOP_RIGHT //右前方 + + MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_LEFT, MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_FAR_LEFT, + -> WarningDirectionEnum.ALERT_WARNING_BOTTOM_LEFT //左后方 + + MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_RIGHT, MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_FAR_RIGHT, + -> WarningDirectionEnum.ALERT_WARNING_BOTTOM_RIGHT //右后方 + + MogoObuConstants.VEH_TARGET_POSITION.UNCLASSIFIED -> WarningDirectionEnum.ALERT_WARNING_NON //未知 + else -> WarningDirectionEnum.ALERT_WARNING_ALL + } + } + + /** + * 处理红绿灯 + */ + private fun handlerTrafficLight(appId: Int, status: Int, lights: List) { + CallerLogger.d( + "${M_OBU}${TAG}", + "MogoObuDcCombineManager handlerTrafficLight --- status = $status ---lights.size = ${lights.size} ---lights = $lights ---appId = $appId" + ) + when (status) { + // 添加 + MogoObuConstants.STATUS.ADD, + MogoObuConstants.STATUS.UPDATE + -> { + if (lights != null && lights.isNotEmpty()) { + changeTrafficLightStatus(appId, lights) + } + } + // 删除 + MogoObuConstants.STATUS.DELETE -> { + // 移除顶部弹窗,当收不到信号的时候触发一次 + CallerHmiManager.disableWarningTrafficLight() + CallerHmiManager.disableWarningV2X(appId.toString()) + isShowGreenWave = false + isShowRunRedLight = false + } + } + } + + private var isRedLight = false + private var isGreenLight = false + private var isShowGreenWave = false + private var isShowRunRedLight = false + + /** + * 修改红绿灯 + */ + @Synchronized + private fun changeTrafficLightStatus( + appId: Int, + lights: List + ) { + var ttsContent = "" + var alertContent = "" + //这里需要根据真实数据确定 index 取值方式 + val currentLight = lights[0] + CallerLogger.e( + "${M_OBU}${TAG}", + "MogoObuDcCombineManager currentLight = $currentLight ---currentLight.phaseID = ${currentLight.phaseID} ---appId = $appId ---isShowRunRedLight = $isShowRunRedLight ---isShowGreenWave = $isShowGreenWave" + ) + + // 闯红灯预警和绿波通行底层是互斥的 + when (appId) { + 0 -> {//不可用 V2I_RLVW_VIOLATION_TYPE_UNAVAILABLE 无效 + + } + 1 -> { //闯红灯 V2I_RLVW_VIOLATION_TYPE_RUNNING_RED_LIGHT 一个红灯周期只显示一次 + if (!isShowRunRedLight) { + isShowRunRedLight = true + CallerHmiManager.disableWarningV2X(1667.toString()) + ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType) + alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType) + CallerLogger.d("${M_OBU}${TAG}","MogoObuDcCombineManager changeTrafficLightStatus 闯红灯 --------> ttsContent = $ttsContent ---alertContent = $alertContent ") + CallerMsgBoxManager.saveMsgBox( + MsgBoxBean( + MsgBoxType.V2X, + V2XMsg( + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, + alertContent, + ttsContent + ) + ) +// .apply { +// sourceType = DataSourceType.TELEMATIC +// } + ) + + CallerHmiManager.warningV2X( + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, alertContent, ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, null, true, 5000L) + } + } + + 2 -> { //绿波通行引导 V2I_RLVW_VIOLATION_TYPE_NO_VIOLATION 一个绿灯周期只显示一次 + if (!isShowGreenWave) { + isShowGreenWave = true + CallerHmiManager.disableWarningV2X(1666.toString()) + CallerLogger.d( + "${M_OBU}${TAG}", + "MogoObuDcCombineManager 绿波通行引导 --------> speed_min = ${currentLight.suggestMinSpeed} --speed_max = ${currentLight.suggestMaxSpeed}") + val adviceSpeed = + "${Math.round(currentLight.suggestMinSpeed*3.6*0.02)} - ${Math.round(currentLight.suggestMaxSpeed*3.6*0.02)}" + val adviceSpeedTts = + "${Math.round(currentLight.suggestMinSpeed*3.6*0.02)} - ${Math.round(currentLight.suggestMaxSpeed*3.6*0.02)}" + + ttsContent = + String.format( + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType), + adviceSpeedTts + ) + alertContent = + String.format( + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType), + adviceSpeed + ) + val maxSpeed = currentLight.suggestMaxSpeed*3.6 + if (maxSpeed > 0) { + CallerMsgBoxManager.saveMsgBox( + MsgBoxBean( + MsgBoxType.V2X, + V2XMsg( + EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType, + alertContent, + ttsContent + ) + ) +// .apply { //TODO +// sourceType = DataSourceType.TELEMATIC +// } + ) + + CallerHmiManager.warningV2X( + EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType, + alertContent, + ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 + appId.toString(), + null, + true, + 5000L + ) + } + } + } + } + + when (currentLight.light) { + // 灯光不可用 + 0 -> { + CallerHmiManager.showWarningTrafficLight(0, 2) + } + + // 红灯 + 2, 3 -> { + if (!isRedLight) { + CallerHmiManager.disableWarningV2X(appId.toString()) + isRedLight = true + } + isGreenLight = false + CallerHmiManager.showWarningTrafficLight(1, 2) + val red = currentLight.countDown / 10 + CallerHmiManager.changeCountdownRed(red) + } + + // 绿灯 + 4, 5, 6 -> { + if (!isGreenLight) { + CallerHmiManager.disableWarningV2X(appId.toString()) + isGreenLight = true + } + isRedLight = false + CallerHmiManager.showWarningTrafficLight(3, 2) + val green = currentLight.countDown / 10 + CallerHmiManager.changeCountdownGreen(green) + } + + // 黄灯 + 7, 8 -> { + CallerHmiManager.disableWarningV2X(appId.toString()) + CallerHmiManager.showWarningTrafficLight(2, 2) + val yellow = currentLight.countDown / 10 + CallerHmiManager.changeCountdownYellow(yellow) + } + } + } + +} diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt index 897a9432fe..961844e834 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt +++ b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt @@ -1,11 +1,10 @@ package com.mogo.eagle.core.function.obu.mogo import android.content.Context -import android.util.Log import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.data.config.HmiBuildConfig -import com.mogo.eagle.core.data.config.HmiBuildConfig.isShowObuLimitSpeedView import com.mogo.eagle.core.data.enums.* +//import com.mogo.eagle.core.data.msgbox.DataSourceType import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.V2XMsg @@ -18,6 +17,8 @@ import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.Defa import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.TooClose import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager import com.mogo.eagle.core.function.call.obu.CallerObuListenerManager +import com.mogo.eagle.core.function.call.obu.CallerObuTrafficLightListenerManager +import com.mogo.eagle.core.function.call.v2x.CallObuLimitingSpeedListenerManager import com.mogo.eagle.core.function.obu.mogo.utils.TrafficDataConvertUtilsNew import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU @@ -93,7 +94,6 @@ class MogoPrivateObuNewManager private constructor() { */ override fun onConnectStatus(connectStatus: Int) { if (connectStatus == 0) { //断开连接 - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", "onConnectFail ------> ") mObuStatusInfo.obuStatus = false mObuStatusInfo.obuHvStatus = false mObuStatusInfo.obuRvStatus = false @@ -102,7 +102,6 @@ class MogoPrivateObuNewManager private constructor() { mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU_HV", false) } mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU_RV", false) } } else if (connectStatus == 1) { //连接成功 - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", "onConnected ------> ") mObuStatusInfo.obuStatus = true CallerObuListenerManager.invokeListener(mObuStatusInfo) mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU", true) } @@ -170,47 +169,61 @@ class MogoPrivateObuNewManager private constructor() { */ override fun onMogoObuRvWarning(data: MogoObuRvWarningData) { super.onMogoObuRvWarning(data) - if (HmiBuildConfig.isShowObuV2vView) { - mObuStatusInfo.obuRvStatus = true - CallerObuListenerManager.invokeListener(mObuStatusInfo) +// if (HmiBuildConfig.isShowObuV2vView) { //TODO 临时需要关闭v2v开关 + mObuStatusInfo.obuRvStatus = true + CallerObuListenerManager.invokeListener(mObuStatusInfo) + if (!data.warningMsg.warningData.isNullOrEmpty()) { + // 更新数据,远车数据,之前要匹配uuid + TrafficDataConvertUtilsNew.cvxRvInfoIndInfo2TrafficData(data)?.let { + CallerMapUIServiceManager.getMarkerService()?.updateITrafficLocationInfo(it) + } - if (!data.warningMsg.warningData.isNullOrEmpty()) { - // 更新数据,远车数据,之前要匹配uuid - TrafficDataConvertUtilsNew.cvxRvInfoIndInfo2TrafficData(data)?.let { - CallerMapUIServiceManager.getMarkerService()?.updateITrafficLocationInfo(it) - } + CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", data.toString()) + data.let { + //预警信息,预警类型 threat_level 2、3 + data.vehBasicsMsg?.let { + //预警方位 + val direction = getMessageDirection(data.vehBasicsMsg.targetPosition) + //处理预警类型 + var appId = "" + var level = -1 + var status = -1 + data.warningMsg?.let { + if (data.warningMsg.warningData != null && data.warningMsg.warningData.size > 0) { + level = data.warningMsg.warningData[0].warningLevel + appId = data.warningMsg.warningData[0].warningType.toString() + status = data.warningMsg.warningData[0].status - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", data.toString()) - data.let { - //预警信息,预警类型 threat_level 2、3 - var status = data.status - data.vehBasicsMsg?.let { - //预警方位 - val direction = getMessageDirection(data.vehBasicsMsg.targetPosition) - //处理预警类型 - var appId = "" - var level = -1 - data.warningMsg?.let { - if (data.warningMsg.warningData != null && data.warningMsg.warningData.size > 0) { - level = data.warningMsg.warningData[0].warningLevel - appId = data.warningMsg.warningData[0].warningType.toString() + //30秒内同一个事件只出现一次 + if (rvMap.containsKey(appId)) { + var oldTime = rvMap[appId] + var timeDiff = (System.currentTimeMillis() - oldTime!!) / 1000 + if (timeDiff < 30) { + return + } + rvMap.remove(appId) + rvMap[appId] = System.currentTimeMillis() + } else { + rvMap[appId] = System.currentTimeMillis() + } + + //拼凑数据 + if (appId != null) { + handleSdkObu(appId, direction, status, level, data) } } - - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "onMogoObuRvWarning target_classification = ${ - getMessageDirection(data.vehBasicsMsg.targetPosition) - } --- direction = $direction --- appId = $appId ---level = $level -- status = $status" - ) - //拼凑数据 - if (appId != null) { - handleSdkObu(appId, direction, status, level, data) - } } + + CallerLogger.d( + "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", + "onMogoObuRvWarning target_classification = ${ + getMessageDirection(data.vehBasicsMsg.targetPosition) + } --- direction = $direction --- appId = $appId ---level = $level -- status = $status" + ) } } } +// } } /** @@ -218,46 +231,48 @@ class MogoPrivateObuNewManager private constructor() { */ override fun onMogoObuSpatWarning(data: MogoObuSpatWarningData) { super.onMogoObuSpatWarning(data) - if (data?.lights != null && data.lights.isNotEmpty() - ) { - if (HmiBuildConfig.isShowObuV2iView) { - handlerTrafficLight( - data.warningType, - data.status, - data.lights - ) - } + if (data != null) { +// if (HmiBuildConfig.isShowObuV2iView) { + handlerTrafficLight( + data.warningType, + data.status, + data.lights + ) +// } } } + val rvMap = mutableMapOf() + val rsiMap = mutableMapOf() + val rsmMap = mutableMapOf() + val rsmPtcIdMap = mutableMapOf() + /** - * RSI预警信息 CvxRtiThreatIndInfo(交通标志预警(前方限速、前方学校等等),交通事件预警(前方拥堵、前方积水等等)) + * RSI预警信息 onMogoObuRsiWarning(交通标志预警(前方限速、前方学校等等),交通事件预警(前方拥堵、前方积水等等)) */ override fun onMogoObuRsiWarning(data: MogoObuRsiWarningData) { super.onMogoObuRsiWarning(data) - if (HmiBuildConfig.isShowObuV2iView) { +// if (HmiBuildConfig.isShowObuV2iView) { + if (data != null && data.warningMsg != null && data.warningMsg.size > 0) { + var alertContent = "" + var ttsContent = "" + var appId = data.warningMsg[0].sceneType.toString() + val status = data.status + val level = data.warningMsg[0].warningLevel + val direction = getMessageDirection(data.warningMsg[0].targetPosition) CallerLogger.d( "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "onMogoObuRsiWarning ------> $data" + "onMogoObuRsiWarning appId = $appId --status = $status --level = $level -- eventSerialNum = ${data.warningMsg[0].eventSerialNum} ---signSerialNum = ${data.warningMsg[0].signSerialNum} --- direction = $direction -- targetPosition = ${data.warningMsg[0].targetPosition}" ) - if (data != null && data.warningMsg != null && data.warningMsg.size > 0) { - var alertContent = "" - var ttsContent = "" - var appId = data.warningMsg[0].sceneType.toString() - val status = data.status - val level = data.warningMsg[0].warningLevel - val direction = getMessageDirection(data.warningMsg[0].targetPosition) - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "onCvxRtiThreatIndInfo appId = $appId --status = $status --level = $level -- eventSerialNum = ${data.warningMsg[0].eventSerialNum} ---signSerialNum = ${data.warningMsg[0].signSerialNum} --- direction = $direction -- targetPosition = ${data.warningMsg[0].targetPosition}" - ) + if (appId != "0") { when (appId) { // 道路危险情况预警 MogoObuConstants.RSI_SCENE_TYPE.HLW.toString() -> { when (data.warningMsg[0].eventSerialNum) { MogoObuConstants.RTE.RTI_TYPE_BREAKDOWN -> {//车辆故障 - appId = EventTypeEnumNew.TYPE_USECASE_ID_BREAKDOWN_WARNING.poiType + appId = + EventTypeEnumNew.TYPE_USECASE_ID_BREAKDOWN_WARNING.poiType } MogoObuConstants.RTE.RTI_TYPE_ROAD_WATER -> { //道路积水 appId = EventTypeEnumNew.FOURS_PONDING.poiType @@ -302,9 +317,9 @@ class MogoPrivateObuNewManager private constructor() { MogoObuConstants.RTS.RTI_TYPE_BRIDGE -> { //桥梁 appId = EventTypeEnumNew.TYPE_ID_BRIDGE.poiType } - MogoObuConstants.RTS.RTI_TYPE_PEDESTRIAN -> { //行人 - appId = EventTypeEnumNew.TYPE_ID_PEDESTRIAN.poiType - } +// MogoObuConstants.RTS.RTI_TYPE_PEDESTRIAN -> { //行人 TODO 暂时去掉 +// appId = EventTypeEnumNew.TYPE_ID_PEDESTRIAN.poiType +// } MogoObuConstants.RTS.RTI_TYPE_SLIPPERY_ROAD -> { //路滑 appId = EventTypeEnumNew.TYPE_ID_SLIPPERY_ROAD.poiType } @@ -341,9 +356,11 @@ class MogoPrivateObuNewManager private constructor() { MogoObuConstants.RTS.RTI_TYPE_NO_TOOTING -> { //禁止鸣笛 appId = EventTypeEnumNew.TYPE_USECASE_ID_ROAD_NO_TOOTING.poiType } - MogoObuConstants.RTS.RTI_TYPE_SPEED_LIMIT -> { //限速 - appId = EventTypeEnumNew.TYPE_USECASE_ID_ROAD_SPEED_LIMIT.poiType - } +// MogoObuConstants.RTS.RTI_TYPE_SPEED_LIMIT -> { //限速 +// appId = +// EventTypeEnumNew.TYPE_USECASE_ID_ROAD_SPEED_LIMIT.poiType +// } + // MogoObuConstants.RTS.RTI_TYPE_GO_STRAIGHT_TURN_RIGHT -> { //直行或右转 // appId = // EventTypeEnumNew.TYPE_USECASE_ID_GO_STRAIGHT_TURN_RIGHT.poiType @@ -381,7 +398,6 @@ class MogoPrivateObuNewManager private constructor() { // 拥堵 MogoObuConstants.RSI_SCENE_TYPE.TJW.toString() -> { appId = EventTypeEnumNew.TYPE_USECASE_ID_TJW.poiType - alertContent = EventTypeEnumNew.getWarningContent(appId) ttsContent = EventTypeEnumNew.getWarningTts(appId) alertContent = String.format( //事件才有影响范围 @@ -398,32 +414,52 @@ class MogoPrivateObuNewManager private constructor() { //限速预警, ADD处理一次 MogoObuConstants.RSI_SCENE_TYPE.SLW.toString() -> { + appId = EventTypeEnumNew.TYPE_USECASE_ID_ROAD_SPEED_LIMIT.poiType alertContent = EventTypeEnumNew.getWarningContent(appId) ttsContent = EventTypeEnumNew.getWarningTts(appId) } } + //30秒内同一个事件只出现一次 + if (rsiMap.containsKey(appId)) { + var oldTime = rsiMap[appId] + var timeDiff = (System.currentTimeMillis() - oldTime!!) / 1000 + if (timeDiff < 30) { + return + } + rsiMap.remove(appId) + rsiMap[appId] = System.currentTimeMillis() + } else { + rsiMap[appId] = System.currentTimeMillis() + } + CallerLogger.d( "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "new onMogoObuRsiWarning ttsContent = $ttsContent --alertContent = $alertContent --appId = $appId ---direction = ${direction.direction} --distance = ${Math.round(data.warningMsg[0].distance)} ---eventRadius = ${Math.round(data.warningMsg[0].eventRadius)} --speedMaxLimit = ${data.warningMsg[0].speedMaxLimit.toInt()}" + "new onMogoObuRsiWarning appId = $appId ---status = $status --- ttsContent = $ttsContent --alertContent = $alertContent -- eventSerialNum = ${data.warningMsg[0].eventSerialNum} ---signSerialNum = ${data.warningMsg[0].signSerialNum} ---direction = ${direction.direction} --distance = ${ + Math.round(data.warningMsg[0].distance) + } ---eventRadius = ${Math.round(data.warningMsg[0].eventRadius)} --speedMaxLimit = ${data.warningMsg[0].speedMaxLimit.toInt()}" ) + when (status) { MogoObuConstants.STATUS.ADD -> { // 添加 //显示警告红边 // CallerHmiManager.showWarning(direction) //不显示弹框,语音提示,数据在消息盒子里面展示,此处不在处理弹框 if (alertContent.isNullOrEmpty() || ttsContent.isNullOrEmpty()) { - Log.d("MsgBox-PriObuNewMana1", "alertContent或ttsContent为空!") + return } CallerMsgBoxManager.saveMsgBox( MsgBoxBean( - MsgBoxType.OBU, + MsgBoxType.V2X, V2XMsg( appId, alertContent, ttsContent ) ) +// .apply { +// sourceType = DataSourceType.OBU +// } ) CallerHmiManager.warningV2X( appId, @@ -437,7 +473,7 @@ class MogoPrivateObuNewManager private constructor() { } }, true, - 3000L + 5000L ) // 更新数据 @@ -451,10 +487,6 @@ class MogoPrivateObuNewManager private constructor() { } MogoObuConstants.STATUS.DELETE -> { // 删除 - // 关闭警告红边 -// CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) - // 移除顶部弹窗 -// CallerHmiManager.disableWarningV2X((appId + direction.direction)) // 更新数据 TrafficDataConvertUtilsNew.cvxRtiThreatIndInfo2TrafficData(data) ?.let { @@ -467,7 +499,7 @@ class MogoPrivateObuNewManager private constructor() { } } } - +// } } /** @@ -483,106 +515,160 @@ class MogoPrivateObuNewManager private constructor() { data: MogoObuRsmWarningData? ) { super.onMogoObuRsmWarning(data) - if (HmiBuildConfig.isShowObuV2iView) { - if (HmiBuildConfig.isShowObuWeaknessTrafficView) { + CallerLogger.d( + "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", + "onMogoObuRsmWarning ------> ${data.toString()}" + ) +// if (HmiBuildConfig.isShowObuV2iView) { + if (HmiBuildConfig.isShowObuWeaknessTrafficView) { + // 交通参与者类型 0x0:未知 UNKNOWN | 1机动车 2:非机动车 NON_MOTOR | 3:行人 PEDESTRIAN 4:obu + if (data != null && data.participant != null) { + var v2xType = "" + if (data.participant.ptcType == 1) { //机动车 + v2xType = + EventTypeEnumNew.TYPE_USECASE_ID_VRUCW_MOTOR_VEHICLES.poiType + } else if (data.participant.ptcType == 2) { //非机动车 + v2xType = + EventTypeEnumNew.TYPE_USECASE_ID_VRUCW_NOT_MOTOR_VEHICLES.poiType + } else if (data.participant.ptcType == 3) { //行人 + v2xType = + EventTypeEnumNew.TYPE_USECASE_ID_VRUCW_PERSON.poiType + } else { //未知 + v2xType = EventTypeEnumNew.TYPE_ERROR.poiType + } + + val ttsContent = EventTypeEnumNew.getWarningTts(v2xType) + val alertContent = + EventTypeEnumNew.getWarningContent(v2xType) + var level = -1 + val direction = getMessageDirection(data.participant.targetPosition) + + //物体数据绘制 TODO 这里与dc通过工控机有区别 CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "onMogoObuRsmWarning ------> ${data.toString()}" - ) - // 交通参与者类型 0x0:未知 UNKNOWN | 1机动车 2:非机动车 NON_MOTOR | 3:行人 PEDESTRIAN 4:obu - if (data != null && data.participant != null) { - var v2xType = "" - if (data.participant.ptcType == 1) { //机动车 - v2xType = - EventTypeEnumNew.TYPE_USECASE_ID_VRUCW_MOTOR_VEHICLES.poiType - } else if (data.participant.ptcType == 2) { //非机动车 - v2xType = - EventTypeEnumNew.TYPE_USECASE_ID_VRUCW_NOT_MOTOR_VEHICLES.poiType - } else if (data.participant.ptcType == 3) { //行人 - v2xType = - EventTypeEnumNew.TYPE_USECASE_ID_VRUCW_PERSON.poiType - } else { //未知 - v2xType = EventTypeEnumNew.TYPE_ERROR.poiType + "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", "onMogoObuRsmWarning ---- data.status = ${data.status} ---data.participant.ptcId = ${data.participant.ptcId} ---data.participant.ptcType = ${data.participant.ptcType} ---data.warningMsg = ${data.warningMsg} -----data = ${data.toString()}") + when (data.status) { + MogoObuConstants.STATUS.ADD -> { // 添加 + // 更新数据,模型变色的时候是不是update,如果不是更新,可能导致模型不变色,(add的时候,是否有level高的) TODO + TrafficDataConvertUtilsNew.cvxPtcThreatIndInfo2TrafficData(data) + ?.let { + CallerMapUIServiceManager.getMarkerService() + ?.updateITrafficThreatLevelInfo(it) + } } - val ttsContent = EventTypeEnumNew.getWarningTts(v2xType) - val alertContent = - EventTypeEnumNew.getWarningContent(v2xType) - var level = -1 - val direction = getMessageDirection(data.participant.targetPosition) - if (data.warningMsg != null && data.warningMsg.warningData != null && data.warningMsg.warningData.size > 0) { - level = data.warningMsg.warningData[0].warningLevel //默认是1个 - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "new onMogoObuRsmWarning ---status---> ${data.status} ---data.warningMsg.warningData[0].status = ${data.warningMsg.warningData[0].status} ---v2xType = $v2xType ---alertContent = $alertContent ---ttsContent = $ttsContent " - ) - when (data.warningMsg.warningData[0].status) { - MogoObuConstants.STATUS.ADD -> { // 添加 -// if (level == 2 || level == 3) { //不考虑level - //显示警告红边 - CallerHmiManager.showWarning(direction) - if (alertContent.isNullOrEmpty() || ttsContent.isNullOrEmpty()) { - Log.d("MsgBox-PriObuNewMana2", "alertContent或ttsContent为空!") + MogoObuConstants.STATUS.UPDATE -> { // 更新 + //处理删除逻辑, +// if (rsmPtcIdMap.containsKey(data.participant.ptcId.toString())) { +// var oldTime = rsmPtcIdMap[data.participant.ptcId.toString()] +// var timeDiff = (System.currentTimeMillis() - oldTime!!) / 1000 +// if (timeDiff > 3) { //超过3秒,删除对应弱势交通元素 +// CallerMapUIServiceManager.getMarkerService() +// ?.removeCvxRvInfoIndInfo(data.participant.ptcId.toString()) +// } +// rsmPtcIdMap.remove(data.participant.ptcId.toString()) +// rsmPtcIdMap[data.participant.ptcId.toString()] = System.currentTimeMillis() +// } else { +// rsmPtcIdMap[data.participant.ptcId.toString()] = System.currentTimeMillis() +// } + } + + MogoObuConstants.STATUS.DELETE -> { // 删除 + // 更新数据 TODO 删除原来的,改变颜色,删除marker。不影响别的模型添加 + TrafficDataConvertUtilsNew.cvxPtcThreatIndInfo2TrafficData(data) + ?.let { + // 事件结束,还原交通参与者颜色 + it.threatLevel = 0x01 + CallerMapUIServiceManager.getMarkerService() + ?.updateITrafficThreatLevelInfo(it) + } + + //删除弱势交通元素 + CallerMapUIServiceManager.getMarkerService() + ?.removeCvxRvInfoIndInfo(data.participant.ptcId.toString()) + } + } + + //预警status + if (data.warningMsg != null && data.warningMsg.warningData != null && data.warningMsg.warningData.size > 0) { + level = data.warningMsg.warningData[0].warningLevel //默认是1个 + CallerLogger.d( + "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", + "onMogoObuRsmWarning ---status---> ${data.status} ---data.warningMsg.warningData[0].status = ${data.warningMsg.warningData[0].status} ---v2xType = $v2xType ---alertContent = $alertContent ---ttsContent = $ttsContent ---level = $level" + ) + when (data.warningMsg.warningData[0].status) { + MogoObuConstants.STATUS.ADD -> { // 添加 + //更新模型的颜色 + //30秒内同一个事件只出现一次 + if (rsmMap.containsKey(v2xType)) { + var oldTime = rsmMap[v2xType] + var timeDiff = (System.currentTimeMillis() - oldTime!!) / 1000 + if (timeDiff < 30) { + return } - CallerMsgBoxManager.saveMsgBox( - MsgBoxBean( - MsgBoxType.OBU, - V2XMsg( - v2xType, - alertContent, - ttsContent - ) - ) - ) - CallerHmiManager.warningV2X( - v2xType, - alertContent, - ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 - (v2xType + direction.direction),//使用当前事件类型+方向记录tag,当发生变化的时候关闭当前弹出新的 - object : IMoGoWarningStatusListener { - override fun onDismiss() { - // 关闭警告红边 - CallerHmiManager.showWarning( - WarningDirectionEnum.ALERT_WARNING_NON - ) - } - }, - true, - 5000L - ) -// } + rsmMap.remove(v2xType) + rsmMap[v2xType] = System.currentTimeMillis() + } else { + rsmMap[v2xType] = System.currentTimeMillis() + } - // 更新数据 - TrafficDataConvertUtilsNew.cvxPtcThreatIndInfo2TrafficData(data)?.let { - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", "add cvxPtcThreatIndInfo2TrafficData ---it---> $it") + TrafficDataConvertUtilsNew.cvxPtcThreatIndInfo2TrafficData(data) + ?.let { CallerMapUIServiceManager.getMarkerService() ?.updateITrafficThreatLevelInfo(it) } - } - MogoObuConstants.STATUS.UPDATE -> {// 更新 + if (alertContent.isNullOrEmpty() || ttsContent.isNullOrEmpty()) { + return } + //显示警告红边 + CallerHmiManager.showWarning(direction) + CallerMsgBoxManager.saveMsgBox( + MsgBoxBean( + MsgBoxType.V2X, + V2XMsg( + v2xType, + alertContent, + ttsContent + ) + ) +// .apply { //TODO +// sourceType = DataSourceType.OBU +// } + ) - // 删除 - MogoObuConstants.STATUS.DELETE -> { - // 关闭警告红边 - CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) - // 更新数据 TODO 删除原来的,改变颜色,删除marker。不影响别的模型添加 - TrafficDataConvertUtilsNew.cvxPtcThreatIndInfo2TrafficData(data) - ?.let { - // 事件结束,还原交通参与者颜色 - it.threatLevel = 0x01 - CallerMapUIServiceManager.getMarkerService() - ?.updateITrafficThreatLevelInfo(it) + CallerHmiManager.warningV2X( + v2xType, + alertContent, + ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 + (v2xType + direction.direction),//使用当前事件类型+方向记录tag,当发生变化的时候关闭当前弹出新的 + object : IMoGoWarningStatusListener { + override fun onDismiss() { + // 关闭警告红边 + CallerHmiManager.showWarning( + WarningDirectionEnum.ALERT_WARNING_NON + ) } + }, + true, + 5000L + ) + } - //删除弱势交通元素 - CallerMapUIServiceManager.getMarkerService()?.removeCvxRvInfoIndInfo(data.participant.ptcId.toString()) - } + MogoObuConstants.STATUS.UPDATE -> {// 更新 + } + + MogoObuConstants.STATUS.DELETE -> { // 删除 + // 关闭警告红边 + CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) + //删除弱势交通元素 + CallerMapUIServiceManager.getMarkerService() + ?.removeCvxRvInfoIndInfo(data.participant.ptcId.toString()) } } } } } +// } } /** @@ -590,16 +676,19 @@ class MogoPrivateObuNewManager private constructor() { */ override fun onMogoObuMapMath(data: MogoObuMapMathData?) { super.onMogoObuMapMath(data) - if(isShowObuLimitSpeedView) { +// if (isShowObuLimitSpeedView) { if (data != null) { CallerLogger.d( "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "onMogoObuMapMathstatus = ${data.status} --speedMaxLimit = ${Math.round((data.speedMaxLimit*3.6))}") + "onMogoObuMapMath = ${data.status} --speedMaxLimit = ${Math.round((data.speedMaxLimit * 3.6))}" + ) when (data.status) { MogoObuConstants.STATUS.ADD -> { // 添加 UiThreadHandler.post { - if(data.speedMaxLimit > 0) { - CallerHmiManager.showLimitingVelocity(Math.round((data.speedMaxLimit*3.6)).toInt()) + if (data.speedMaxLimit > 0) { +// CallerHmiManager.showLimitingVelocity( +// Math.round((data.speedMaxLimit * 3.6)).toInt(), 2) + CallObuLimitingSpeedListenerManager.invokeOnObuLimitingSpeedChange(Math.round((data.speedMaxLimit * 3.6)).toInt()) } } } @@ -609,22 +698,23 @@ class MogoPrivateObuNewManager private constructor() { MogoObuConstants.STATUS.DELETE -> { // 删除 UiThreadHandler.post { - CallerHmiManager.disableLimitingVelocity() +// CallerHmiManager.disableLimitingVelocity() + CallObuLimitingSpeedListenerManager.invokeOnObuLimitingSpeedChange(-1) } } } } - } +// } } } - } +} /** * 获取消息的方位 车辆相关 */ private fun getMessageDirection(targetClassification: Int): WarningDirectionEnum { -// CallerLogger.d("$M_OBU${TAG_MOGO_NEW_OBU}", "预警红边:预警方向->$targetClassification") + // CallerLogger.d("$M_OBU${TAG_MOGO_NEW_OBU}", "预警红边:预警方向->$targetClassification") return when (targetClassification) { MogoObuConstants.VEH_TARGET_POSITION.AHEAD_IN_LANE, MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_IN_LANE -> WarningDirectionEnum.ALERT_WARNING_TOP //正前方 @@ -657,7 +747,7 @@ class MogoPrivateObuNewManager private constructor() { /** * 构造对应展示数据和场景 根据obu的场景,add change delete确定是否展示 * - * @param appId 使用WarningTypeEnum获取icon、提示内容、tts内容 + * @param appId 使用WarningTypeEnum获取icon、提示内容、tts内容 TODO 添加事件频繁播报拦截 * * @see com.mogo.module.common.enums.EventTypeEnum */ @@ -669,56 +759,32 @@ class MogoPrivateObuNewManager private constructor() { info: MogoObuRvWarningData ) { // 这里排除需要特殊定制的语音及文案外,其余的都可以使用 EventTypeEnumNew 提供的 - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "handleSdkObu appId = $appId --- handleDirection = $direction ---level = $level ---status = $status" - ) - - var alertContent: String - var ttsContent: String + var alertContent: String = "" + var ttsContent: String = "" var changeVisualAngle = false when (appId) { - // 变道预警,注意左后车辆/注意右后车辆 - EventTypeEnumNew.TYPE_USECASE_ID_LCW.poiType -> { - alertContent = EventTypeEnumNew.getWarningContent(appId) - ttsContent = EventTypeEnumNew.getWarningTts(appId) - if ( - direction == WarningDirectionEnum.ALERT_WARNING_LEFT || - direction == WarningDirectionEnum.ALERT_WARNING_TOP_LEFT || - direction == WarningDirectionEnum.ALERT_WARNING_BOTTOM_LEFT - ) { - ttsContent = String.format(ttsContent, "左") - alertContent = String.format(alertContent, "左") - } else if ( - direction == WarningDirectionEnum.ALERT_WARNING_RIGHT || - direction == WarningDirectionEnum.ALERT_WARNING_TOP_RIGHT || - direction == WarningDirectionEnum.ALERT_WARNING_BOTTOM_RIGHT - ) { - ttsContent = String.format(ttsContent, "右") - alertContent = String.format(alertContent, "右") - } + //交叉路口碰撞预警 + MogoObuConstants.V2X_WARNING_TYPE.FCW.toString() -> { + alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_FCW.poiType) + ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_FCW.poiType) } - //车辆失控预警 - EventTypeEnumNew.TYPE_USECASE_ID_CLW.poiType -> { - alertContent = EventTypeEnumNew.getWarningContent(appId) - ttsContent = EventTypeEnumNew.getWarningTts(appId) - alertContent = String.format(alertContent, direction.desc) - ttsContent = String.format(ttsContent, direction.desc) + //交叉路口碰撞预警 + MogoObuConstants.V2X_WARNING_TYPE.ICW.toString() -> { + alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_ICW.poiType) + ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_ICW.poiType) } - //异常车辆提醒 - EventTypeEnumNew.TYPE_USECASE_ID_AVW.poiType -> { - alertContent = EventTypeEnumNew.getWarningContent(appId) - ttsContent = EventTypeEnumNew.getWarningTts(appId) - alertContent = String.format(alertContent, direction.desc) - ttsContent = String.format(ttsContent, direction.desc) + //左转辅助预警 + MogoObuConstants.V2X_WARNING_TYPE.LTA.toString() -> { + alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_LTA.poiType) + ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_LTA.poiType) } //盲区预警 - EventTypeEnumNew.TYPE_USECASE_ID_BSW.poiType -> { - ttsContent = EventTypeEnumNew.getWarningTts(appId) - alertContent = EventTypeEnumNew.getWarningContent(appId) + MogoObuConstants.V2X_WARNING_TYPE.BSW.toString() -> { + ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_BSW.poiType) + alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_BSW.poiType) if ( direction == WarningDirectionEnum.ALERT_WARNING_LEFT || direction == WarningDirectionEnum.ALERT_WARNING_TOP_LEFT || @@ -737,10 +803,65 @@ class MogoPrivateObuNewManager private constructor() { alertContent = String.format(alertContent, "右") } } + + // 变道预警,注意左后车辆/注意右后车辆 + MogoObuConstants.V2X_WARNING_TYPE.LCW.toString() -> { + alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_LCW.poiType) + ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_LCW.poiType) + if ( + direction == WarningDirectionEnum.ALERT_WARNING_LEFT || + direction == WarningDirectionEnum.ALERT_WARNING_TOP_LEFT || + direction == WarningDirectionEnum.ALERT_WARNING_BOTTOM_LEFT + ) { + ttsContent = String.format(ttsContent, "左") + alertContent = String.format(alertContent, "左") + } else if ( + direction == WarningDirectionEnum.ALERT_WARNING_RIGHT || + direction == WarningDirectionEnum.ALERT_WARNING_TOP_RIGHT || + direction == WarningDirectionEnum.ALERT_WARNING_BOTTOM_RIGHT + ) { + ttsContent = String.format(ttsContent, "右") + alertContent = String.format(alertContent, "右") + } + } + + //逆向超车预警 + MogoObuConstants.V2X_WARNING_TYPE.DNPW.toString() -> { + alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_DNPW.poiType) + ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_DNPW.poiType) + } + + //紧急制动预警 + MogoObuConstants.V2X_WARNING_TYPE.EBW.toString() -> { + alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_EBW.poiType) + ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_EBW.poiType) + } + + //异常车辆提醒 + MogoObuConstants.V2X_WARNING_TYPE.AVW.toString() -> { + alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_AVW.poiType) + ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_AVW.poiType) + alertContent = String.format(alertContent, direction.desc) + ttsContent = String.format(ttsContent, direction.desc) + } + + //车辆失控预警 + MogoObuConstants.V2X_WARNING_TYPE.CLW.toString() -> { + alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_CLW.poiType) + ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_CLW.poiType) + alertContent = String.format(alertContent, direction.desc) + ttsContent = String.format(ttsContent, direction.desc) + } + //车辆失控预警 + MogoObuConstants.V2X_WARNING_TYPE.EVW.toString() -> { + alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_EVW.poiType) + ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_EVW.poiType) + } + // 这里处理固定的提示信息,包括了<紧急车辆提醒> - else -> { - ttsContent = EventTypeEnumNew.getWarningTts(appId) - alertContent = EventTypeEnumNew.getWarningContent(appId) + else -> { //TODO +// ttsContent = EventTypeEnumNew.getWarningTts(appId.toString()) +// alertContent = EventTypeEnumNew.getWarningContent(appId.toString()) } } @@ -753,19 +874,19 @@ class MogoPrivateObuNewManager private constructor() { "new handleSdkObu appId2 = $appId --- level = $level ---ttsContent = $ttsContent --- alertContent = $alertContent --- direction = $direction" ) if (level == 2 || level == 3) { - if (alertContent.isNullOrEmpty() || ttsContent.isNullOrEmpty()) { - Log.d("MsgBox-PriObuNewManager2", "alertContent或ttsContent为空!") - } //不显示弹框,其它保留 CallerMsgBoxManager.saveMsgBox( MsgBoxBean( - MsgBoxType.OBU, + MsgBoxType.V2X, V2XMsg( appId, alertContent, ttsContent ) ) +// .apply { +// sourceType = DataSourceType.OBU +// } ) CallerHmiManager.warningV2X( appId, @@ -789,7 +910,7 @@ class MogoPrivateObuNewManager private constructor() { } }, true, - 3000L + 5000L ) //显示警告红边 CallerHmiManager.showWarning(direction) @@ -805,7 +926,7 @@ class MogoPrivateObuNewManager private constructor() { // 关闭警告红边 CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) // 移除顶部弹窗 - // CallerHmiManager.disableWarningV2X((appId + direction.direction)) + // CallerHmiManager.disableWarningV2X((appId + direction.direction)) //更新周边车辆进行预警颜色变换,车辆实时移动和变色 TrafficDataConvertUtilsNew.cvxV2vThreatIndInfo2TrafficData(info)?.let { it.threatLevel = 0x01 @@ -829,7 +950,9 @@ class MogoPrivateObuNewManager private constructor() { MogoObuConstants.STATUS.ADD, MogoObuConstants.STATUS.UPDATE -> { - changeTrafficLightStatus(appId, lights) + if (lights != null && lights.isNotEmpty()) { + changeTrafficLightStatus(appId, lights) + } } // 删除 MogoObuConstants.STATUS.DELETE -> { @@ -838,15 +961,25 @@ class MogoPrivateObuNewManager private constructor() { CallerHmiManager.disableWarningV2X(appId.toString()) isShowGreenWave = false isShowRunRedLight = false + isYellowLight = false +// lightCountDownRed = 1 +// lightCountDownGreen = 1 +// lightCountDownYellow = 1 } } } private var isRedLight = false private var isGreenLight = false + private var isYellowLight = false private var isShowGreenWave = false private var isShowRunRedLight = false +// private var lightCountDownRed : Int = 1 +// private var lightCountDownGreen : Int = 1 +// private var lightCountDownYellow : Int = 1 + + /** * 修改红绿灯 */ @@ -861,63 +994,95 @@ class MogoPrivateObuNewManager private constructor() { val currentLight = lights[0] CallerLogger.d( "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "currentLight = $currentLight ---currentLight.phase = ${currentLight.phaseId} ---appId = $appId" + "changeTrafficLightStatus currentLight = $currentLight ----currentLight.light = ${currentLight.light} ---currentLight.phase = ${currentLight.phaseId} ---appId = $appId --countDown = ${currentLight.countDown.toInt()}" ) // 闯红灯预警,绿波通行和闯红灯是互斥的 when (appId) { - 0x0 -> {//不可用 V2I_RLVW_VIOLATION_TYPE_UNAVAILABLE 无效 + 0 -> {//不可用 V2I_RLVW_VIOLATION_TYPE_UNAVAILABLE 无效 } - 0x1 -> {//闯红灯 V2I_RLVW_VIOLATION_TYPE_RUNNING_RED_LIGHT 一个红灯周期只显示一次 + 1 -> {//闯红灯 V2I_RLVW_VIOLATION_TYPE_RUNNING_RED_LIGHT 一个红灯周期只显示一次 if (!isShowRunRedLight) { isShowRunRedLight = true - CallerHmiManager.disableWarningV2X(0x2.toString()) - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}","changeTrafficLightStatus 闯红灯 --------> ") - ttsContent = EventTypeEnumNew.getWarningTts(appId.toString()) - alertContent = EventTypeEnumNew.getWarningContent(appId.toString()) + CallerHmiManager.disableWarningV2X(1667.toString()) + CallerLogger.d( + "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", + "changeTrafficLightStatus 闯红灯 --------> " + ) + ttsContent = + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType) + alertContent = + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType) + CallerMsgBoxManager.saveMsgBox( + MsgBoxBean( + MsgBoxType.V2X, + V2XMsg( + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, + alertContent, + ttsContent + ) + ) +// .apply { +// sourceType = DataSourceType.OBU +// } + ) + CallerHmiManager.warningV2X( - appId.toString(), alertContent, ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 - appId.toString(), null, true, 5000L) + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, + alertContent, + ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, + null, + true, + 5000L + ) } } - 0x2 -> { //绿波通行引导 V2I_RLVW_VIOLATION_TYPE_NO_VIOLATION 一个绿灯周期只显示一次 100m的时候 + 2 -> { //绿波通行引导 V2I_RLVW_VIOLATION_TYPE_NO_VIOLATION 一个绿灯周期只显示一次 100m的时候 if (!isShowGreenWave) { isShowGreenWave = true - CallerHmiManager.disableWarningV2X(0x1.toString()) - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "new changeTrafficLightStatus speed_min = ${currentLight.suggestMinSpeed} --speed_max = ${currentLight.suggestMaxSpeed} --TYPE_USECASE_ID_IVP_GREEN ---alertContent = $alertContent ---ttsContent = $ttsContent" - ) - val adviceSpeed = - "${currentLight.suggestMinSpeed} - ${currentLight.suggestMaxSpeed}" - val adviceSpeedTts = - "${currentLight.suggestMinSpeed}到${currentLight.suggestMaxSpeed}" + CallerHmiManager.disableWarningV2X(1666.toString()) + + var minSpeedTemp = Math.round(currentLight.suggestMinSpeed*3.6) + var maxSpeedTemp = Math.round(currentLight.suggestMaxSpeed*3.6) + if (minSpeedTemp == maxSpeedTemp) { + minSpeedTemp -= 5 + } + + val adviceSpeed = "$minSpeedTemp - $maxSpeedTemp" + val adviceSpeedTts = "$minSpeedTemp 到 $maxSpeedTemp" + +// val adviceSpeed = +// "${Math.round(currentLight.suggestMinSpeed*3.6)} - ${Math.round(currentLight.suggestMaxSpeed*3.6)}" +// val adviceSpeedTts = +// "${Math.round(currentLight.suggestMinSpeed*3.6)} 到 ${Math.round(currentLight.suggestMaxSpeed*3.6)}" + ttsContent = String.format( - EventTypeEnumNew.getWarningTts(appId.toString()), + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType), adviceSpeedTts ) alertContent = String.format( - EventTypeEnumNew.getWarningContent(appId.toString()), + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType), adviceSpeed ) val maxSpeed = currentLight.suggestMaxSpeed if (maxSpeed > 0) { - if (alertContent.isNullOrEmpty() || ttsContent.isNullOrEmpty()) { - Log.d("MsgBox-PriObuNewManager1", "alertContent或ttsContent为空!") - } CallerMsgBoxManager.saveMsgBox( MsgBoxBean( - MsgBoxType.OBU, + MsgBoxType.V2X, V2XMsg( EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType, alertContent, ttsContent ) ) +// .apply { //TODO +// sourceType = DataSourceType.OBU +// } ) CallerHmiManager.warningV2X( @@ -937,7 +1102,7 @@ class MogoPrivateObuNewManager private constructor() { when (currentLight.light) { // 灯光不可用 0 -> { - CallerHmiManager.showWarningTrafficLight(0, 2) + CallerObuTrafficLightListenerManager.invokeObuTrafficLight(0) } // 红灯 2, 3 -> { @@ -946,8 +1111,8 @@ class MogoPrivateObuNewManager private constructor() { isRedLight = true } isGreenLight = false - CallerHmiManager.showWarningTrafficLight(1, 2) - + isYellowLight = false + CallerObuTrafficLightListenerManager.invokeObuTrafficLight(1) val red = currentLight.countDown.toInt() CallerHmiManager.changeCountdownRed(red) } @@ -959,17 +1124,23 @@ class MogoPrivateObuNewManager private constructor() { isGreenLight = true } isRedLight = false - CallerHmiManager.showWarningTrafficLight(3, 2) + isYellowLight = false + CallerObuTrafficLightListenerManager.invokeObuTrafficLight(3) val green = currentLight.countDown.toInt() CallerHmiManager.changeCountdownGreen(green) } // 黄灯 7, 8 -> { + if (!isYellowLight) { + isYellowLight = true + } + isRedLight = false + isGreenLight = false CallerHmiManager.disableWarningV2X(appId.toString()) - CallerHmiManager.showWarningTrafficLight(2, 2) + CallerObuTrafficLightListenerManager.invokeObuTrafficLight(2) val yellow = currentLight.countDown.toInt() CallerHmiManager.changeCountdownYellow(yellow) } } - } + } diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt index 748b847aef..cf1d029c1f 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt @@ -133,21 +133,30 @@ enum class EventTypeEnumNew( // 违章停车 ALERT_ILLEGAL_PARK("99992"), - //-------------v2n start ------------> + //TODO 这个确认值 + TYPE_USECASE_OPTIMAL_LANE( + 0x2B06.toString(), + "最优车道", + poiTypeSrcVr = R.drawable.v2x_icon_live_logo, + content = "最优车道", + tts = "最优车道" + ), + + //-------------obu v2v start ------------> TYPE_USECASE_ID_FCW( - 2000.toString(), + 2010.toString(), "前向碰撞预警", poiTypeSrcVr = R.drawable.icon_warning_v2x_collision_warning, content = "前车碰撞预警", tts = "小心前车" ), - // TYPE_USECASE_ID_ICW( - // 1.toString(), - // "交叉路口碰撞预警", - // poiTypeSrcVr = R.drawable.icon_warning_v2x_collision_warning, - // content = "交叉路口碰撞预警", - // tts = "注意交叉路口车辆" - // ), + TYPE_USECASE_ID_ICW( + 2009.toString(), + "交叉路口碰撞预警", + poiTypeSrcVr = R.drawable.icon_warning_v2x_collision_warning, + content = "交叉路口碰撞预警", + tts = "注意交叉路口车辆" + ), TYPE_USECASE_ID_LTA( 2001.toString(), "左转辅助", @@ -205,16 +214,15 @@ enum class EventTypeEnumNew( content = "注意特种车辆通行", tts = "请避让特种车辆" ), - //-------------v2n end ------------> + //-------------obu v2v end ------------> - - //---------弱势交通参与者 start ------> + //---------弱势交通参与者 obu and cloud start ------> TYPE_USECASE_ID_VRUCW_MOTOR_VEHICLES( 1001.toString(), "弱势交通参与者碰撞预警", poiTypeSrcVr = R.drawable.icon_warning_v2x_motorcycle_collision, - content = "注意机动车", - tts = "注意机动车" + content = "注意摩托车", + tts = "注意摩托车" ), TYPE_USECASE_ID_VRUCW_NOT_MOTOR_VEHICLES( 1002.toString(), @@ -237,10 +245,9 @@ enum class EventTypeEnumNew( content = "前方有未知障碍物", tts = "前方有未知障碍物" ), - //---------弱势交通参与者 end --------> + //---------弱势交通参与者 obu and cloud end --------> - - //--------------红绿灯 start -------> TODO 修改重复 + //--------------红绿灯 start -------> TYPE_USECASE_ID_IVP_RED( 1666.toString(), "闯红灯预警", @@ -258,7 +265,7 @@ enum class EventTypeEnumNew( ), //-------------红绿灯 end ----------> - //-----------道路危险情况预警 start ---------------> + //-----------道路危险情况预警 obu start ---------------> TYPE_USECASE_ID_BREAKDOWN_WARNING( //故障车辆 101.toString(), "车辆故障", @@ -308,10 +315,9 @@ enum class EventTypeEnumNew( content = "您已超速,请减速行驶", tts = "您已超速,请减速行驶" ), - //------------道路危险情况预警 end -----------> + //------------道路危险情况预警 obu end -----------> - - //------------车内标牌 start --------------> + //------------车内标牌 obu start --------------> TYPE_ID_SHAPR_TURNS( 2.toString(), "急转弯", @@ -447,10 +453,27 @@ enum class EventTypeEnumNew( ), TYPE_USECASE_ID_ACCIDENT( 244.toString(), - "事故", + "交通事故", poiTypeSrcVr = R.drawable.v2x_icon_jiaotongshigu_vr, - content = "前方%s米事故", - tts = "前方%s米事故" + content = "前方%s米交通事故", + tts = "前方%s米交通事故" + ), + //------------车内标牌 obu end --------------> + + TYPE_SOCKET_ROAD_CONGESTION( + "100071", + "交通拥堵", + poiTypeSrcVr = R.drawable.v2x_icon_yongdu_vr, + content = "前方%s米交通拥堵", + tts = "前方%s米交通拥堵" + ), + + TYPE_SOCKET_ROAD_JINGZHI( + "100251", + "前方%s米静止障碍物占道", + poiTypeSrcVr = R.drawable.v2x_icon_jingzhi_zhangai, + content = "前方%s米静止障碍物占道", + tts = "前方%s米静止障碍物占道" ), //------------车内标牌 end --------------> diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewLimitingVelocity.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewLimitingVelocity.kt index aef782d2d6..3d566205ef 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewLimitingVelocity.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewLimitingVelocity.kt @@ -14,5 +14,5 @@ abstract class IViewLimitingVelocity(context: Context?, attrs: AttributeSet?, de * 更新限速数据 * @param limitingSpeed 限速值,单位:km/h */ - open fun updateLimitingSpeed(limitingSpeed: Int) {} + open fun updateLimitingSpeed(limitingSpeed: Int, limitSource: Int) {} } \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoHmiProvider.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoHmiProvider.kt index ac85e3c66c..e8617252a3 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoHmiProvider.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoHmiProvider.kt @@ -140,7 +140,7 @@ interface IMoGoHmiProvider : IMoGoHmiViewProxy { * * @param limitingSpeed 限速速度 */ - fun showLimitingVelocity(limitingSpeed: Int) + fun showLimitingVelocity(limitingSpeed: Int, limitSpeedSource: Int) /** * 关闭限速预警 diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/obu/IMoGoObuTrafficLightListener.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/obu/IMoGoObuTrafficLightListener.kt new file mode 100644 index 0000000000..1b4be4e95c --- /dev/null +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/obu/IMoGoObuTrafficLightListener.kt @@ -0,0 +1,15 @@ +package com.mogo.eagle.core.function.api.obu + + +/** + * @author lixiaopeng + * @date 2022/1/30 10:28 下午 + * OBU 灯态信息 + */ +interface IMoGoObuTrafficLightListener { + /** + * @param light 灯的信息 + */ + fun onObuTrafficLight(light: Int){} + +} \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/obucombine/IMoGoObuDcCombineListener.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/obucombine/IMoGoObuDcCombineListener.kt new file mode 100644 index 0000000000..942102318c --- /dev/null +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/obucombine/IMoGoObuDcCombineListener.kt @@ -0,0 +1,17 @@ +package com.mogo.eagle.core.function.api.obucombine + +import mogo.v2x.ObuWarningEvent + +/** + * obu和dc 通道打通融合 + */ +interface IMoGoObuDcCombineListener { + + /** + * obu透传v2i数据,(标牌,弱势交通,红绿灯,限速,道路危险状况) + * @param obuWarningData + */ + fun onMoGoObuDcCombineData(obuWarningData: ObuWarningEvent.ObuWarningData?) + + + } \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/ObuLimitingSpeedListener.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/ObuLimitingSpeedListener.kt new file mode 100644 index 0000000000..1fb84cdeaa --- /dev/null +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/ObuLimitingSpeedListener.kt @@ -0,0 +1,8 @@ +package com.mogo.eagle.core.function.api.v2x + +/** + * 限速信息 + */ +interface ObuLimitingSpeedListener { + fun onObuLimitingSpeedChange(limitingSpeed: Int) +} \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt index e65f5542fb..9fc14f5158 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt @@ -144,7 +144,7 @@ object CallerHmiManager { * 展示红绿灯预警 * * @param checkLightId 0-都是默认,1-红,2-黄,3-绿 - * @param lightSource 1:云端下发;2:自车感知 + * @param lightSource 1:云端下发;2:自车感知;3:OBU */ fun showWarningTrafficLight(checkLightId: Int, lightSource: Int) { waringProviderApi?.showWarningTrafficLight(checkLightId, lightSource) @@ -205,10 +205,11 @@ object CallerHmiManager { * 展示限速预警 * * @param limitingSpeed 限速速度 + * @param limitSpeedSource 限速来源 1:MAP, 2:RSU */ @BizConfig(V2I, "", BIZ_SLW) - fun showLimitingVelocity(limitingSpeed: Int) { - waringProviderApi?.showLimitingVelocity(limitingSpeed) + fun showLimitingVelocity(limitingSpeed: Int, limitSpeedSource: Int) { + waringProviderApi?.showLimitingVelocity(limitingSpeed, limitSpeedSource) } /** diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/obu/CallerObuTrafficLightListenerManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/obu/CallerObuTrafficLightListenerManager.kt new file mode 100644 index 0000000000..e881947ad9 --- /dev/null +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/obu/CallerObuTrafficLightListenerManager.kt @@ -0,0 +1,25 @@ +package com.mogo.eagle.core.function.call.obu + +import com.mogo.eagle.core.function.api.obu.IMoGoObuTrafficLightListener +import com.mogo.eagle.core.function.call.base.CallerBase +import java.util.concurrent.ConcurrentHashMap + + +object CallerObuTrafficLightListenerManager : CallerBase() { + + private val M_OBU_TRAFFIC_LIGHT_LISTENER: ConcurrentHashMap = + ConcurrentHashMap() + + var mLight: Int = 0 + + + fun invokeObuTrafficLight(light: Int) { + this.mLight = light + M_OBU_TRAFFIC_LIGHT_LISTENER.forEach { + val tag = it.key + val listener = it.value + listener.onObuTrafficLight(light) + } + } + +} \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/obucombine/CallerObuDcCombineListenerManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/obucombine/CallerObuDcCombineListenerManager.kt new file mode 100644 index 0000000000..2ecbf31c29 --- /dev/null +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/obucombine/CallerObuDcCombineListenerManager.kt @@ -0,0 +1,66 @@ +package com.mogo.eagle.core.function.call.obucombine + +import androidx.annotation.Nullable +import com.mogo.eagle.core.function.api.obu.IMoGoObuStatusListener +import com.mogo.eagle.core.function.api.obucombine.IMoGoObuDcCombineListener +import com.mogo.eagle.core.function.call.base.CallerBase +import mogo.v2x.ObuWarningEvent +import java.util.concurrent.ConcurrentHashMap + +/** + * obu和dc数据通道 回调监听 + */ +object CallerObuDcCombineListenerManager : CallerBase() { + // 存储所有注册了监听的对象,invokeXXXX进行遍历回调,将信息同步 + private val M_DC_COMBINE_LISTENERS: ConcurrentHashMap = + ConcurrentHashMap() + + /** + * 添加 obu和dc数据通道 监听 + * @param tag 标记,用来注销监听使用 + * @param listener 监听回调 + */ +// fun addListener( +// @Nullable tag: String, +// @Nullable listener: IMoGoObuDcCombineListener +// ) { +// if (M_DC_COMBINE_LISTENERS.containsKey(tag)) { +// return +// } +// M_DC_COMBINE_LISTENERS[tag] = listener +// } + + /** + * 删除监听 + * @param tag 标记,用来注销监听使用 + */ +// fun removeListener(@Nullable tag: String) { +// if (!M_DC_COMBINE_LISTENERS.containsKey(tag)) { +// return +// } +// M_DC_COMBINE_LISTENERS.remove(tag) +// } + + /** + * 删除自动驾驶按钮选中监听 + * @param listener 要删除的监听对象 + */ +// fun removeListener(@Nullable listener: IMoGoObuDcCombineListener) { +// M_DC_COMBINE_LISTENERS.forEach { +// if (it.value == listener) { +// M_DC_COMBINE_LISTENERS.remove(it.key) +// } +// } +// } + + /** + * v2i数据 + */ + fun invokeObuDcData(obuWarningData: ObuWarningEvent.ObuWarningData?){ + M_DC_COMBINE_LISTENERS.forEach{ + val listener = it.value + listener.onMoGoObuDcCombineData(obuWarningData) + } + } + +} \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallObuLimitingSpeedListenerManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallObuLimitingSpeedListenerManager.kt new file mode 100644 index 0000000000..1a33b7af68 --- /dev/null +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallObuLimitingSpeedListenerManager.kt @@ -0,0 +1,26 @@ +package com.mogo.eagle.core.function.call.v2x + +import com.mogo.eagle.core.function.api.v2x.ObuLimitingSpeedListener +import com.mogo.eagle.core.function.call.base.CallerBase +import java.util.concurrent.ConcurrentHashMap + +/** + * 限速信息监听 + */ +object CallObuLimitingSpeedListenerManager : CallerBase(){ + + private const val TAG = "CallObuLimitingSpeedListenerManager" + private val M_TRAFFIC_LIGHT_LISTENER: ConcurrentHashMap = + ConcurrentHashMap() + private var mObuLimitSpeed = 0 + + fun invokeOnObuLimitingSpeedChange(limitingSpeed: Int) { + this.mObuLimitSpeed = limitingSpeed + M_TRAFFIC_LIGHT_LISTENER.forEach { + val tag = it.key + val listener = it.value + listener.onObuLimitingSpeedChange(limitingSpeed) + } + } + +} \ No newline at end of file diff --git a/core/mogo-core-res/src/main/res/drawable-xhdpi/v2x_icon_jingzhi_zhangai.png b/core/mogo-core-res/src/main/res/drawable-xhdpi/v2x_icon_jingzhi_zhangai.png new file mode 100644 index 0000000000000000000000000000000000000000..c5e2711db3a495382a8be257b49d18cdca7db531 GIT binary patch literal 16798 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 Rsd4}S002ovPDHLkV1mc2f+hd} literal 0 HcmV?d00001 From 7ae3e13fabad5b14a9b86853f77d7c4977f7f66a Mon Sep 17 00:00:00 2001 From: renwj Date: Sun, 29 Jan 2023 17:58:41 +0800 Subject: [PATCH 04/48] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0][merge]=E5=90=88?= =?UTF-8?q?=E5=B9=B62.13.2=E5=88=86=E6=94=AF=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 24 +- .../com/mogo/functions/test/RoadAITest.kt | 23 +- .../com/mogo/launcher/MogoApplication.java | 41 +- .../java/com/mogo/launcher/lancet/CrashFix.kt | 32 + .../com/mogo/launcher/stageone/APMStartup.kt | 2 +- .../mogo/launcher/stageone/ARouterStartUp.kt | 4 + .../mogo/launcher/stageone/ConfigStartUp.kt | 4 + .../mogo/launcher/stageone/HttpDnsStartUp.kt | 4 +- .../launcher/stageone/ThreadOptStartup.kt | 33 + build.gradle | 2 +- config.gradle | 2 - .../core/function/hmi/ui/MoGoHmiFragment.kt | 27 +- .../hmi/ui/setting/DebugSettingView.kt | 26 +- .../mogo-core-function-v2x/build.gradle | 21 +- .../function/v2x/events/V2XEventManager.kt | 290 ++++--- .../v2x/events/alarm/V2XAlarmServer.java | 12 +- .../events/manager/IMoGoV2XMarkerManager.java | 9 +- .../manager/impl/MoGoV2XMarkerManager.java | 57 +- .../v2x/events/marker/MarkerManager.kt | 193 +++++ .../events/scenario/impl/AbsV2XScenario.java | 18 +- .../scenario/impl/V2XScenarioManager.java | 2 + .../scenario/scene/airoad/AiRoadMarker.kt | 415 +++------ .../scene/road/V2XAiRoadEventMarker.kt | 173 ++-- .../scene/road/V2XRoadEventMarker.java | 72 +- .../scene/road/V2XRoadEventScenario.java | 87 +- .../route/V2XOptimalRouteVREventMarker.java | 14 +- .../route/V2XOptimalRouteVREventScenario.java | 15 +- .../warning/V2XFrontWarningScenario.java | 7 +- .../scene/warning/V2XWarningMarker.java | 4 +- .../function/v2x/events/utils/EntityUtils.kt | 214 ++++- .../core/function/v2x/internal/V2XManager.kt | 257 ++++++ .../v2x/internal/callback/IV2XCallback.kt | 24 + .../function/v2x/internal/config/V2XConfig.kt | 174 ++++ .../v2x/internal/data/V2XAdvanceWarning.kt | 120 +++ .../function/v2x/internal/data/V2XBaseData.kt | 9 + .../function/v2x/internal/data/V2XLocation.kt | 26 + .../v2x/internal/data/V2XMarkerCardResult.kt | 815 ++++++++++++++++++ .../v2x/internal/data/V2XMarkerResponse.kt | 28 + .../v2x/internal/data/V2XOptimalRoute.kt | 56 ++ .../v2x/internal/data/V2XRoadXEvent.kt | 59 ++ .../v2x/internal/data/V2XWarningTarget.kt | 176 ++++ .../function/v2x/internal/event/V2XEvent.kt | 75 ++ .../v2x/internal/executor/Executors.kt | 35 + .../v2x/internal/http/V2XRefreshModel.kt | 84 ++ .../v2x/internal/http/api/V2XApiService.kt | 14 + .../internal/http/body/V2XRefreshEntity.kt | 39 + .../http/callback/IV2XRefreshCallback.kt | 11 + .../function/v2x/internal/logger/Logger.kt | 24 + .../socket/V2XMessageListener_401012.kt | 27 + .../socket/V2XMessageListener_401018.kt | 27 + .../socket/V2XMessageListener_402000.kt | 27 + .../socket/V2XMessageListener_404000.kt | 27 + .../socket/V2XMessageListener_503000.kt | 27 + .../socket/V2XMessageListener_70001.kt | 27 + .../v2x/internal/utils/DeviceUtils.kt | 46 + .../v2x/internal/utils/DistanceUtils.kt | 52 ++ .../src/main/proto/road.proto | 59 ++ .../core/data/config/CloudPoiManager.java | 3 +- .../eagle/core/data/enums/EventTypeEnumNew.kt | 203 ++--- .../data/map/entity/V2XRoadEventEntity.java | 4 +- .../call/map/CallerVisualAngleManager.kt | 7 +- .../v2x_icon_shigong_zhandao.png | Bin 0 -> 17365 bytes .../v2x_icon_shigu_sanjiaopai.png | Bin 0 -> 15743 bytes .../main/res/raw/v2x_shigu_sanjiaopai.nt3d | Bin 0 -> 228665 bytes .../src/main/res/raw/v2x_zhangai.nt3d | Bin 0 -> 498336 bytes gradle.properties | 3 +- .../java/com/mogo/map/AMapViewWrapper.java | 2 +- .../main/java/com/mogo/map/AMapWrapper.java | 15 +- 68 files changed, 3446 insertions(+), 963 deletions(-) create mode 100644 app/src/main/java/com/mogo/launcher/lancet/CrashFix.kt create mode 100644 app/src/main/java/com/mogo/launcher/stageone/ThreadOptStartup.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/MarkerManager.kt create mode 100755 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/V2XManager.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/callback/IV2XCallback.kt create mode 100755 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/config/V2XConfig.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XAdvanceWarning.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XBaseData.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XLocation.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XMarkerCardResult.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XMarkerResponse.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XOptimalRoute.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XRoadXEvent.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XWarningTarget.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/event/V2XEvent.kt create mode 100755 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/executor/Executors.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/V2XRefreshModel.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/api/V2XApiService.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/body/V2XRefreshEntity.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/http/callback/IV2XRefreshCallback.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/logger/Logger.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_401012.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_401018.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_402000.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_404000.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_503000.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_70001.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/utils/DeviceUtils.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/utils/DistanceUtils.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/proto/road.proto create mode 100644 core/mogo-core-res/src/main/res/drawable-xhdpi/v2x_icon_shigong_zhandao.png create mode 100644 core/mogo-core-res/src/main/res/drawable-xhdpi/v2x_icon_shigu_sanjiaopai.png create mode 100644 core/mogo-core-res/src/main/res/raw/v2x_shigu_sanjiaopai.nt3d create mode 100644 core/mogo-core-res/src/main/res/raw/v2x_zhangai.nt3d diff --git a/app/build.gradle b/app/build.gradle index 8ef4cbbd4f..734265a7d3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -39,14 +39,14 @@ if (!isAndroidTestBuild()) { apply plugin: 'apm-plugin' } -//if (!isAndroidTestBuild()) { -// apply plugin: 'bytex.threadOpt' -// thread_opt { -// enable !isReleaseBuild -// enableInDebug !isReleaseBuild -// logLevel "DEBUG" -// } -//} +if (!isAndroidTestBuild()) { + apply plugin: 'bytex.threadOpt' + thread_opt { + enable true + enableInDebug true + logLevel "DEBUG" + } +} if (!isAndroidTestBuild()) { apply plugin: 'LancetX' @@ -55,13 +55,12 @@ if (!isAndroidTestBuild()) { enableInDebug true weaveGroup { - leak_canary_crash_fix { - enable !isReleaseBuild - } - anr_fix { enable true } + crash_fix { + enable true + } } } } @@ -354,7 +353,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..6f50da9ea0 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,10 @@ 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.data.V2XRoadXData +import com.mogo.eagle.core.function.v2x.internal.event.V2XEvent +import com.mogo.eagle.core.function.v2x.internal.event.V2XEvent.RoadAI +import com.mogo.eagle.core.utilcode.util.GsonUtils import kotlinx.coroutines.* import org.junit.* import org.junit.runner.* @@ -157,4 +160,22 @@ class RoadAITest { } } + + @Test + fun testRoadAI() = runBlocking { + ensureMoGoHmiFragmentShow() + val shigu = "{\"poiType\":\"100321\",\"receiveTime\":1673506266967,\"detectTime\":1673506266924,\"id\":\"f7b1df85-895a-41c1-b05d-7356955c1c91\",\"index\":\"636136931493454271\",\"polygon\":[{\"lon\":112.57321291454436,\"lat\":26.823070465392494},{\"lon\":112.573215006931,\"lat\":26.8230675990919},{\"lon\":112.573219106955,\"lat\":26.823061914715},{\"lon\":112.573223182233,\"lat\":26.8230562153801},{\"lon\":112.573227231639,\"lat\":26.8230505007471},{\"lon\":112.573231254048,\"lat\":26.8230447704754},{\"lon\":112.573235248336,\"lat\":26.8230390242245},{\"lon\":112.573239213377,\"lat\":26.8230332616541},{\"lon\":112.573243148045,\"lat\":26.8230274824236},{\"lon\":112.573247051217,\"lat\":26.8230216861928},{\"lon\":112.573250921765,\"lat\":26.823015872621},{\"lon\":112.573254758566,\"lat\":26.823010041368},{\"lon\":112.573258560494,\"lat\":26.8230041920932},{\"lon\":112.573262326424,\"lat\":26.8229983244562},{\"lon\":112.573266055231,\"lat\":26.8229924381166},{\"lon\":112.573269779025,\"lat\":26.8229864802436},{\"lon\":112.573273466,\"lat\":26.8229805039295},{\"lon\":112.573277118207,\"lat\":26.8229745102999},{\"lon\":112.573280737695,\"lat\":26.8229685004807},{\"lon\":112.573284326516,\"lat\":26.8229624755973},{\"lon\":112.57328788672,\"lat\":26.8229564367755},{\"lon\":112.573291420358,\"lat\":26.822950385141},{\"lon\":112.573294929481,\"lat\":26.8229443218192},{\"lon\":112.573298416139,\"lat\":26.822938247936},{\"lon\":112.573301882384,\"lat\":26.822932164617},{\"lon\":112.573305330265,\"lat\":26.8229260729878},{\"lon\":112.573308761833,\"lat\":26.8229199741741},{\"lon\":112.57331217914,\"lat\":26.8229138693015},{\"lon\":112.573315584235,\"lat\":26.8229077594956},{\"lon\":112.573318940869,\"lat\":26.8229017005891},{\"lon\":112.57332227685,\"lat\":26.8228956326057},{\"lon\":112.573325593901,\"lat\":26.8228895563037},{\"lon\":112.573328893742,\"lat\":26.8228834724414},{\"lon\":112.573332178097,\"lat\":26.8228773817772},{\"lon\":112.573335448685,\"lat\":26.8228712850694},{\"lon\":112.573338707228,\"lat\":26.8228651830762},{\"lon\":112.573341955449,\"lat\":26.822859076556},{\"lon\":112.573345195068,\"lat\":26.8228529662671},{\"lon\":112.573348427807,\"lat\":26.8228468529679},{\"lon\":112.573351655387,\"lat\":26.8228407374165},{\"lon\":112.57335487953,\"lat\":26.8228346203714},{\"lon\":112.573358101958,\"lat\":26.8228285025908},{\"lon\":112.573361324391,\"lat\":26.8228223848331},{\"lon\":112.573364548551,\"lat\":26.8228162678566},{\"lon\":112.573367776161,\"lat\":26.8228101524196},{\"lon\":112.57337100894,\"lat\":26.8228040392803},{\"lon\":112.573374248612,\"lat\":26.8227979291972},{\"lon\":112.573377570805,\"lat\":26.8227916708447},{\"lon\":112.573380890942,\"lat\":26.8227854119249},{\"lon\":112.573384209049,\"lat\":26.8227791523835},{\"lon\":112.573387525157,\"lat\":26.8227728921664},{\"lon\":112.573390839291,\"lat\":26.8227666312191},{\"lon\":112.573394151482,\"lat\":26.8227603694874},{\"lon\":112.573397461756,\"lat\":26.8227541069172},{\"lon\":112.573400770143,\"lat\":26.822747843454},{\"lon\":112.573404076669,\"lat\":26.8227415790437},{\"lon\":112.573407381363,\"lat\":26.822735313632},{\"lon\":112.573410684254,\"lat\":26.8227290471645},{\"lon\":112.57341398537,\"lat\":26.8227227795872},{\"lon\":112.573417284738,\"lat\":26.8227165108456},{\"lon\":112.573420582386,\"lat\":26.8227102408855},{\"lon\":112.573423878344,\"lat\":26.8227039696526},{\"lon\":112.573427172639,\"lat\":26.8226976970928},{\"lon\":112.573430465298,\"lat\":26.8226914231516},{\"lon\":112.5736541921437,\"lat\":26.822260937315143},{\"lon\":112.57362367177457,\"lat\":26.822244991227713},{\"lon\":112.573399937477,\"lat\":26.822675492918},{\"lon\":112.573396691977,\"lat\":26.8226816946351},{\"lon\":112.573393403264,\"lat\":26.8226879586397},{\"lon\":112.573390112889,\"lat\":26.8226942213535},{\"lon\":112.573386820836,\"lat\":26.8227004828209},{\"lon\":112.573383527072,\"lat\":26.822706742987},{\"lon\":112.573380231507,\"lat\":26.8227130021005},{\"lon\":112.573376934206,\"lat\":26.8227192599775},{\"lon\":112.573373635113,\"lat\":26.8227255169308},{\"lon\":112.573370334197,\"lat\":26.8227317727439},{\"lon\":112.573367031403,\"lat\":26.8227380276418},{\"lon\":112.573363726739,\"lat\":26.822744281759},{\"lon\":112.573360420141,\"lat\":26.8227505349933},{\"lon\":112.573357111541,\"lat\":26.8227567875221},{\"lon\":112.573353801054,\"lat\":26.8227630392523},{\"lon\":112.573350488563,\"lat\":26.8227692902611},{\"lon\":112.573347174021,\"lat\":26.8227755406808},{\"lon\":112.573343849991,\"lat\":26.8227818018286},{\"lon\":112.57334059532,\"lat\":26.8227879346295},{\"lon\":112.573337344447,\"lat\":26.8227940752481},{\"lon\":112.57333410391,\"lat\":26.8228002103548},{\"lon\":112.573330872,\"lat\":26.8228063391622},{\"lon\":112.573327646909,\"lat\":26.8228124609577},{\"lon\":112.573324426983,\"lat\":26.8228185749099},{\"lon\":112.573321210588,\"lat\":26.8228246801823},{\"lon\":112.573317995803,\"lat\":26.8228307762173},{\"lon\":112.573314781099,\"lat\":26.8228368621259},{\"lon\":112.573311564666,\"lat\":26.8228429372788},{\"lon\":112.573308344862,\"lat\":26.822849000878},{\"lon\":112.573305119998,\"lat\":26.8228550522037},{\"lon\":112.573301888377,\"lat\":26.8228610905445},{\"lon\":112.573298648327,\"lat\":26.8228671151949},{\"lon\":112.573295398165,\"lat\":26.8228731254473},{\"lon\":112.573292136233,\"lat\":26.822879120603},{\"lon\":112.573288860863,\"lat\":26.8228850999821},{\"lon\":112.573285560822,\"lat\":26.8228910767817},{\"lon\":112.573282199005,\"lat\":26.822897124157},{\"lon\":112.573278821808,\"lat\":26.8229031714324},{\"lon\":112.573275437073,\"lat\":26.8229092033326},{\"lon\":112.573272042813,\"lat\":26.8229152188038},{\"lon\":112.573268637042,\"lat\":26.8229212167948},{\"lon\":112.573265217788,\"lat\":26.8229271962611},{\"lon\":112.573261783086,\"lat\":26.8229331561851},{\"lon\":112.573258330982,\"lat\":26.8229390955283},{\"lon\":112.573254859519,\"lat\":26.8229450132931},{\"lon\":112.573251366753,\"lat\":26.8229509084733},{\"lon\":112.573247850743,\"lat\":26.8229567800818},{\"lon\":112.57324430955,\"lat\":26.8229626271411},{\"lon\":112.573240741245,\"lat\":26.8229684486883},{\"lon\":112.573237142704,\"lat\":26.8229742453022},{\"lon\":112.573233541124,\"lat\":26.8229799700034},{\"lon\":112.573229900299,\"lat\":26.8229856807403},{\"lon\":112.573226220729,\"lat\":26.8229913784753},{\"lon\":112.573222503466,\"lat\":26.8229970634612},{\"lon\":112.573218749581,\"lat\":26.8230027359391},{\"lon\":112.573214960128,\"lat\":26.8230083961865},{\"lon\":112.573211136192,\"lat\":26.8230140444302},{\"lon\":112.573207278832,\"lat\":26.8230196809522},{\"lon\":112.573203389132,\"lat\":26.8230253060135},{\"lon\":112.573199468169,\"lat\":26.8230309198603},{\"lon\":112.573195517033,\"lat\":26.8230365227693},{\"lon\":112.573191536797,\"lat\":26.8230421150085},{\"lon\":112.573187548559,\"lat\":26.8230476745161},{\"lon\":112.57318546455338,\"lat\":26.823050549063097}],\"polygonRoads\":[{\"tileId\":556834853,\"roadId\":\"130372\",\"laneNo\":-1,\"bearing\":152,\"roadName\":\"雁鸣路\"},{\"tileId\":556834853,\"roadId\":\"130372\",\"laneNo\":-2,\"bearing\":152,\"roadName\":\"雁鸣路\"},{\"tileId\":556834853,\"roadId\":\"130372\",\"laneNo\":-3,\"bearing\":152,\"roadName\":\"雁鸣路\"}],\"center\":{\"lon\":112.57320982521519,\"lat\":26.82306821019599},\"centerRoad\":{\"tileId\":556834853,\"roadId\":\"130372\",\"laneNo\":-2,\"bearing\":152,\"roadName\":\"雁鸣路\"},\"obstacles\":[{\"id\":0,\"type\":1,\"score\":95,\"polygon\":[{\"lon\":112.57321361221982,\"lat\":26.823054701276522},{\"lon\":112.57321254435868,\"lat\":26.823070134384093},{\"lon\":112.57320704440468,\"lat\":26.823066238995114},{\"lon\":112.57320772757787,\"lat\":26.823050237509577}],\"boundBox\":[{\"x\":2979.852783203125,\"y\":929.4248657226562},{\"x\":3031.54296875,\"y\":929.4248657226562},{\"x\":3031.54296875,\"y\":977.5980834960938},{\"x\":2979.852783203125,\"y\":977.5980834960938}],\"center\":{\"lon\":112.57320982521519,\"lat\":26.82306821019599}}],\"imgUrl\":\"http://petchfile-1255510688.cos.ap-beijing.myqcloud.com/roadwork_image/2023-01-12/f7b1df85-895a-41c1-b05d-7356955c1c91_172_18_24_62.jpg?sign=q-sign-algorithm%3Dsha1%26q-ak%3DAKIDCWfcNwD5PXVWLxwejccR3Tiz5zhIkx0T%26q-sign-time%3D1673506267%3B1673513467%26q-key-time%3D1673506267%3B1673513467%26q-header-list%3D%26q-url-param-list%3D%26q-signature%3Db6b2911110c9941471cfc447d7704b9caa57a0e1\",\"ip\":\"172.18.24.62\",\"score\":95,\"radius\":0,\"type\":2,\"trianglePolygon\":[[{\"lon\":112.57321291454436,\"lat\":26.823070465392494},{\"lon\":112.573215006931,\"lat\":26.8230675990919},{\"lon\":112.573219106955,\"lat\":26.823061914715},{\"lon\":112.573223182233,\"lat\":26.8230562153801},{\"lon\":112.573227231639,\"lat\":26.8230505007471},{\"lon\":112.573231254048,\"lat\":26.8230447704754},{\"lon\":112.573235248336,\"lat\":26.8230390242245},{\"lon\":112.573239213377,\"lat\":26.8230332616541},{\"lon\":112.573243148045,\"lat\":26.8230274824236},{\"lon\":112.573247051217,\"lat\":26.8230216861928},{\"lon\":112.573250921765,\"lat\":26.823015872621},{\"lon\":112.573254758566,\"lat\":26.823010041368},{\"lon\":112.573258560494,\"lat\":26.8230041920932},{\"lon\":112.573262326424,\"lat\":26.8229983244562},{\"lon\":112.573266055231,\"lat\":26.8229924381166},{\"lon\":112.573269779025,\"lat\":26.8229864802436},{\"lon\":112.573273466,\"lat\":26.8229805039295},{\"lon\":112.573277118207,\"lat\":26.8229745102999},{\"lon\":112.573280737695,\"lat\":26.8229685004807},{\"lon\":112.573284326516,\"lat\":26.8229624755973},{\"lon\":112.57328788672,\"lat\":26.8229564367755},{\"lon\":112.573291420358,\"lat\":26.822950385141},{\"lon\":112.573294929481,\"lat\":26.8229443218192},{\"lon\":112.573298416139,\"lat\":26.822938247936},{\"lon\":112.573301882384,\"lat\":26.822932164617},{\"lon\":112.573305330265,\"lat\":26.8229260729878},{\"lon\":112.573308761833,\"lat\":26.8229199741741},{\"lon\":112.57331217914,\"lat\":26.8229138693015},{\"lon\":112.573315584235,\"lat\":26.8229077594956},{\"lon\":112.573318940869,\"lat\":26.8229017005891},{\"lon\":112.57332227685,\"lat\":26.8228956326057},{\"lon\":112.573325593901,\"lat\":26.8228895563037},{\"lon\":112.573328893742,\"lat\":26.8228834724414},{\"lon\":112.573332178097,\"lat\":26.8228773817772},{\"lon\":112.573335448685,\"lat\":26.8228712850694},{\"lon\":112.573338707228,\"lat\":26.8228651830762},{\"lon\":112.573341955449,\"lat\":26.822859076556},{\"lon\":112.573345195068,\"lat\":26.8228529662671},{\"lon\":112.573348427807,\"lat\":26.8228468529679},{\"lon\":112.573351655387,\"lat\":26.8228407374165},{\"lon\":112.57335487953,\"lat\":26.8228346203714},{\"lon\":112.573358101958,\"lat\":26.8228285025908},{\"lon\":112.573361324391,\"lat\":26.8228223848331},{\"lon\":112.573364548551,\"lat\":26.8228162678566},{\"lon\":112.573367776161,\"lat\":26.8228101524196},{\"lon\":112.57337100894,\"lat\":26.8228040392803},{\"lon\":112.573374248612,\"lat\":26.8227979291972},{\"lon\":112.573377570805,\"lat\":26.8227916708447},{\"lon\":112.573380890942,\"lat\":26.8227854119249},{\"lon\":112.573384209049,\"lat\":26.8227791523835},{\"lon\":112.573387525157,\"lat\":26.8227728921664},{\"lon\":112.573390839291,\"lat\":26.8227666312191},{\"lon\":112.573394151482,\"lat\":26.8227603694874},{\"lon\":112.573397461756,\"lat\":26.8227541069172},{\"lon\":112.573400770143,\"lat\":26.822747843454},{\"lon\":112.573404076669,\"lat\":26.8227415790437},{\"lon\":112.573407381363,\"lat\":26.822735313632},{\"lon\":112.573410684254,\"lat\":26.8227290471645},{\"lon\":112.57341398537,\"lat\":26.8227227795872},{\"lon\":112.573417284738,\"lat\":26.8227165108456},{\"lon\":112.573420582386,\"lat\":26.8227102408855},{\"lon\":112.573423878344,\"lat\":26.8227039696526},{\"lon\":112.573427172639,\"lat\":26.8226976970928},{\"lon\":112.573430465298,\"lat\":26.8226914231516},{\"lon\":112.5736541921437,\"lat\":26.822260937315143},{\"lon\":112.57362367177457,\"lat\":26.822244991227713},{\"lon\":112.573399937477,\"lat\":26.822675492918},{\"lon\":112.573396691977,\"lat\":26.8226816946351},{\"lon\":112.573393403264,\"lat\":26.8226879586397},{\"lon\":112.573390112889,\"lat\":26.8226942213535},{\"lon\":112.573386820836,\"lat\":26.8227004828209},{\"lon\":112.573383527072,\"lat\":26.822706742987},{\"lon\":112.573380231507,\"lat\":26.8227130021005},{\"lon\":112.573376934206,\"lat\":26.8227192599775},{\"lon\":112.573373635113,\"lat\":26.8227255169308},{\"lon\":112.573370334197,\"lat\":26.8227317727439},{\"lon\":112.573367031403,\"lat\":26.8227380276418},{\"lon\":112.573363726739,\"lat\":26.822744281759},{\"lon\":112.573360420141,\"lat\":26.8227505349933},{\"lon\":112.573357111541,\"lat\":26.8227567875221},{\"lon\":112.573353801054,\"lat\":26.8227630392523},{\"lon\":112.573350488563,\"lat\":26.8227692902611},{\"lon\":112.573347174021,\"lat\":26.8227755406808},{\"lon\":112.573343849991,\"lat\":26.8227818018286},{\"lon\":112.57334059532,\"lat\":26.8227879346295},{\"lon\":112.573337344447,\"lat\":26.8227940752481},{\"lon\":112.57333410391,\"lat\":26.8228002103548},{\"lon\":112.573330872,\"lat\":26.8228063391622},{\"lon\":112.573327646909,\"lat\":26.8228124609577},{\"lon\":112.573324426983,\"lat\":26.8228185749099},{\"lon\":112.573321210588,\"lat\":26.8228246801823},{\"lon\":112.573317995803,\"lat\":26.8228307762173},{\"lon\":112.573314781099,\"lat\":26.8228368621259},{\"lon\":112.573311564666,\"lat\":26.8228429372788},{\"lon\":112.573308344862,\"lat\":26.822849000878},{\"lon\":112.573305119998,\"lat\":26.8228550522037},{\"lon\":112.573301888377,\"lat\":26.8228610905445},{\"lon\":112.573298648327,\"lat\":26.8228671151949},{\"lon\":112.573295398165,\"lat\":26.8228731254473},{\"lon\":112.573292136233,\"lat\":26.822879120603},{\"lon\":112.573288860863,\"lat\":26.8228850999821},{\"lon\":112.573285560822,\"lat\":26.8228910767817},{\"lon\":112.573282199005,\"lat\":26.822897124157},{\"lon\":112.573278821808,\"lat\":26.8229031714324},{\"lon\":112.573275437073,\"lat\":26.8229092033326},{\"lon\":112.573272042813,\"lat\":26.8229152188038},{\"lon\":112.573268637042,\"lat\":26.8229212167948},{\"lon\":112.573265217788,\"lat\":26.8229271962611},{\"lon\":112.573261783086,\"lat\":26.8229331561851},{\"lon\":112.573258330982,\"lat\":26.8229390955283},{\"lon\":112.573254859519,\"lat\":26.8229450132931},{\"lon\":112.573251366753,\"lat\":26.8229509084733},{\"lon\":112.573247850743,\"lat\":26.8229567800818},{\"lon\":112.57324430955,\"lat\":26.8229626271411},{\"lon\":112.573240741245,\"lat\":26.8229684486883},{\"lon\":112.573237142704,\"lat\":26.8229742453022},{\"lon\":112.573233541124,\"lat\":26.8229799700034},{\"lon\":112.573229900299,\"lat\":26.8229856807403},{\"lon\":112.573226220729,\"lat\":26.8229913784753},{\"lon\":112.573222503466,\"lat\":26.8229970634612},{\"lon\":112.573218749581,\"lat\":26.8230027359391},{\"lon\":112.573214960128,\"lat\":26.8230083961865},{\"lon\":112.573211136192,\"lat\":26.8230140444302},{\"lon\":112.573207278832,\"lat\":26.8230196809522},{\"lon\":112.573203389132,\"lat\":26.8230253060135},{\"lon\":112.573199468169,\"lat\":26.8230309198603},{\"lon\":112.573195517033,\"lat\":26.8230365227693},{\"lon\":112.573191536797,\"lat\":26.8230421150085},{\"lon\":112.573187548559,\"lat\":26.8230476745161},{\"lon\":112.57318546455338,\"lat\":26.823050549063097}]],\"obstaclePoint\":[{\"lon\":112.573443,\"lat\":26.822538},{\"lon\":112.573691,\"lat\":26.822676},{\"lon\":112.573021,\"lat\":26.823149},{\"lon\":112.572974,\"lat\":26.823199}],\"createTime\":1673506267760,\"createTimeStr\":\"2023-01-12 14:51:07\"}" + val road1 = "{\"poiType\":\"100061\",\"receiveTime\":1673509755649,\"detectTime\":1673509755637,\"id\":\"86447e30-2dfc-4a27-8d01-41ffe9a9a7fe\",\"index\":\"636136931493457343\",\"polygon\":[{\"lon\":112.57337137520945,\"lat\":26.822950000610152},{\"lon\":112.5733703998375,\"lat\":26.82294943400411},{\"lon\":112.57336923793872,\"lat\":26.82294944578748},{\"lon\":112.57336827709125,\"lat\":26.82295003202963},{\"lon\":112.57336786590433,\"lat\":26.822950822795498},{\"lon\":112.57332583348149,\"lat\":26.823144415135413},{\"lon\":112.57332583904886,\"lat\":26.823145130116597},{\"lon\":112.57332615359141,\"lat\":26.82314578706645},{\"lon\":112.57332672775591,\"lat\":26.823146282906478},{\"lon\":112.57332747145331,\"lat\":26.823146539837108},{\"lon\":112.57332807078356,\"lat\":26.823146549872188},{\"lon\":112.57332882464814,\"lat\":26.82314631801647},{\"lon\":112.57332941903356,\"lat\":26.823145841742402},{\"lon\":112.57332970267485,\"lat\":26.82314536795171},{\"lon\":112.57339652767452,\"lat\":26.82297757920771},{\"lon\":112.57339644737766,\"lat\":26.82297673161999},{\"lon\":112.57339607387638,\"lat\":26.822976136665098},{\"lon\":112.57337137520945,\"lat\":26.822950000610152}],\"polygonRoads\":[{\"tileId\":556834853,\"roadId\":\"130314\",\"laneNo\":-1,\"bearing\":330,\"roadName\":\"雁鸣路\"},{\"tileId\":556834853,\"roadId\":\"130314\",\"laneNo\":-2,\"bearing\":330,\"roadName\":\"雁鸣路\"},{\"tileId\":556834853,\"roadId\":\"130314\",\"laneNo\":-3,\"bearing\":330,\"roadName\":\"雁鸣路\"},{\"tileId\":556834853,\"roadId\":\"130583\",\"laneNo\":-1,\"bearing\":278}],\"center\":{\"lon\":112.57336404707121,\"lat\":26.823024407262803},\"centerRoad\":{\"tileId\":556834853,\"roadId\":\"130314\",\"laneNo\":-2,\"bearing\":330,\"roadName\":\"雁鸣路\"},\"obstacles\":[{\"id\":0,\"type\":1,\"score\":88,\"polygon\":[{\"lon\":112.57334137965555,\"lat\":26.82313245733589},{\"lon\":112.573329020958,\"lat\":26.823145531571242},{\"lon\":112.57332663570918,\"lat\":26.823144025991855},{\"lon\":112.57333875695714,\"lat\":26.823130823353114}],\"boundBox\":[{\"x\":1439.8624267578125,\"y\":893.4229736328125},{\"x\":1474.45361328125,\"y\":893.4229736328125},{\"x\":1474.45361328125,\"y\":966.433837890625},{\"x\":1439.8624267578125,\"y\":966.433837890625}],\"center\":{\"lon\":112.57332779256919,\"lat\":26.823144756804734}},{\"id\":1,\"type\":1,\"score\":87,\"polygon\":[{\"lon\":112.57339986657128,\"lat\":26.822898951544797},{\"lon\":112.5733716620538,\"lat\":26.822952992001163},{\"lon\":112.57336786188131,\"lat\":26.822949186370185},{\"lon\":112.57339561566401,\"lat\":26.822894141465785}],\"boundBox\":[{\"x\":2085.054443359375,\"y\":503.0662841796875},{\"x\":2116.11865234375,\"y\":503.0662841796875},{\"x\":2116.11865234375,\"y\":559.9113159179688},{\"x\":2085.054443359375,\"y\":559.9113159179688}],\"center\":{\"lon\":112.5733698249888,\"lat\":26.822951164464232}},{\"id\":2,\"type\":1,\"score\":71,\"polygon\":[{\"lon\":112.57342641528835,\"lat\":26.82293191667262},{\"lon\":112.57339610867105,\"lat\":26.82297860774548},{\"lon\":112.5733928192764,\"lat\":26.822975877911627},{\"lon\":112.57342270277888,\"lat\":26.822928610829003}],\"boundBox\":[{\"x\":1873.2490234375,\"y\":507.2391357421875},{\"x\":1900.5283203125,\"y\":507.2391357421875},{\"x\":1900.5283203125,\"y\":562.299560546875},{\"x\":1873.2490234375,\"y\":562.299560546875}],\"center\":{\"lon\":112.57339452365564,\"lat\":26.822977300519444}}],\"imgUrl\":\"http://petchfile-1255510688.cos.ap-beijing.myqcloud.com/roadwork_image/2023-01-12/86447e30-2dfc-4a27-8d01-41ffe9a9a7fe_172_18_24_62.jpg?sign=q-sign-algorithm%3Dsha1%26q-ak%3DAKIDCWfcNwD5PXVWLxwejccR3Tiz5zhIkx0T%26q-sign-time%3D1673509757%3B1673516957%26q-key-time%3D1673509757%3B1673516957%26q-header-list%3D%26q-url-param-list%3D%26q-signature%3D557de14ddfb999d35ddef9e23b3532d9d299c62f\",\"ip\":\"172.18.24.62\",\"score\":82,\"radius\":0,\"type\":1,\"createTime\":1673509757496,\"createTimeStr\":\"2023-01-12 15:49:17\"}" + val road2 = "{\"poiType\":\"100061\",\"receiveTime\":1673509756306,\"detectTime\":1673509756290,\"id\":\"be6a2000-a96c-42c8-a7ef-f83388d84858\",\"index\":\"636136931493532287\",\"polygon\":[{\"lon\":112.5733515539896,\"lat\":26.823143145432386},{\"lon\":112.57335140084462,\"lat\":26.823142454672727},{\"lon\":112.57335096472467,\"lat\":26.823141869074952},{\"lon\":112.57335031202503,\"lat\":26.82314147779103},{\"lon\":112.57334954211333,\"lat\":26.82314134039038},{\"lon\":112.57334877220161,\"lat\":26.82314147779103},{\"lon\":112.573348119502,\"lat\":26.823141869074952},{\"lon\":112.57334768338202,\"lat\":26.823142454672727},{\"lon\":112.57334753023707,\"lat\":26.823143145432386},{\"lon\":112.57334768338202,\"lat\":26.82314383619207},{\"lon\":112.57334811950196,\"lat\":26.82314442178987},{\"lon\":112.5733487722016,\"lat\":26.823144813073792},{\"lon\":112.57334954211333,\"lat\":26.823144950474443},{\"lon\":112.57335031202504,\"lat\":26.823144813073792},{\"lon\":112.57335096472468,\"lat\":26.82314442178987},{\"lon\":112.57335140084464,\"lat\":26.82314383619207},{\"lon\":112.5733515539896,\"lat\":26.823143145432386}],\"polygonRoads\":[{\"tileId\":556834853,\"roadId\":\"130314\",\"laneNo\":-4,\"bearing\":332,\"roadName\":\"雁鸣路\"}],\"center\":{\"lon\":112.57334952644263,\"lat\":26.823143141971546},\"centerRoad\":{\"tileId\":556834853,\"roadId\":\"130314\",\"laneNo\":-4,\"bearing\":332,\"roadName\":\"雁鸣路\"},\"obstacles\":[{\"id\":0,\"type\":1,\"score\":72,\"polygon\":[{\"lon\":112.57341760772391,\"lat\":26.823104379136176},{\"lon\":112.57335121413183,\"lat\":26.82314367391432},{\"lon\":112.57334751791018,\"lat\":26.823142500693834},{\"lon\":112.57341321183773,\"lat\":26.82310322131963}],\"boundBox\":[{\"x\":1551.2252197265625,\"y\":352.58837890625},{\"x\":1562.4649658203125,\"y\":352.58837890625},{\"x\":1562.4649658203125,\"y\":376.17327880859375},{\"x\":1551.2252197265625,\"y\":376.17327880859375}],\"center\":{\"lon\":112.57334952644263,\"lat\":26.823143141971546}}],\"imgUrl\":\"http://petchfile-1255510688.cos.ap-beijing.myqcloud.com/roadwork_image/2023-01-12/be6a2000-a96c-42c8-a7ef-f83388d84858_172_18_24_42.jpg?sign=q-sign-algorithm%3Dsha1%26q-ak%3DAKIDCWfcNwD5PXVWLxwejccR3Tiz5zhIkx0T%26q-sign-time%3D1673509758%3B1673516958%26q-key-time%3D1673509758%3B1673516958%26q-header-list%3D%26q-url-param-list%3D%26q-signature%3Db2682464078ae53eae6e87f924abe17fa7c04ac8\",\"ip\":\"172.18.24.42\",\"score\":72,\"radius\":0,\"type\":1,\"createTime\":1673509758511,\"createTimeStr\":\"2023-01-12 15:49:18\"}" + val jingzhi1 = "{\"poiType\":\"100321\",\"detectTime\":1673506266924,\"id\":\"f7b1df85-895a-41c1-b05d-7356955c1c91\",\"index\":\"636136931493454271\",\"polygon\":[],\"center\":{\"lon\":112.57320982521519,\"lat\":26.82306821019599},\"centerRoad\":{\"tileId\":556834853,\"laneNo\":-2,\"bearing\":152},\"score\":95,\"radius\":0,\"type\":2}" + val jingzhi2 = "{\"poiType\":\"100321\",\"detectTime\":1673506266924,\"id\":\"f7b1df85-895a-41c1-b05d-7356955c1c91\",\"index\":\"636136931493454271\",\"polygon\":[],\"center\":{\"lon\":112.57320982521519,\"lat\":26.82306821019599},\"centerRoad\":{\"tileId\":556834853,\"laneNo\":-2,\"bearing\":152},\"score\":95,\"radius\":0,\"type\":2}" + val jingzhi3 = "{\"poiType\":\"100321\",\"detectTime\":1673506266924,\"id\":\"f7b1df85-895a-41c1-b05d-7356955c1c91\",\"index\":\"636136931493454271\",\"polygon\":[],\"center\":{\"lon\":112.57320982521519,\"lat\":26.82306821019599},\"centerRoad\":{\"tileId\":556834853,\"laneNo\":-2,\"bearing\":152},\"score\":95,\"radius\":0,\"type\":2}" + while (true) { + delay(1000) + V2XEventManager.onAck(V2XEvent.RoadEventX(data = GsonUtils.fromJson(shigu, V2XRoadXData::class.java))) + V2XEventManager.onAck(V2XEvent.RoadEventX(data = GsonUtils.fromJson(road1, V2XRoadXData::class.java))) + V2XEventManager.onAck(V2XEvent.RoadEventX(data = GsonUtils.fromJson(road2, V2XRoadXData::class.java))) + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/MogoApplication.java b/app/src/main/java/com/mogo/launcher/MogoApplication.java index 422a345196..5170e83c20 100644 --- a/app/src/main/java/com/mogo/launcher/MogoApplication.java +++ b/app/src/main/java/com/mogo/launcher/MogoApplication.java @@ -70,45 +70,6 @@ public class MogoApplication extends MainMoGoApplication { } - @Override - protected void attachBaseContext(Context base) { - super.attachBaseContext(base); -// ThreadConfig.Builder builder = new ThreadConfig.Builder().listener(new ThreadConfig.TaskExecuteListener() { -// @Override -// public boolean isEnabled() { -// return true; // 如果返回true,会有后续的回调;如果返回false, 不会有后续的回调 -// } -// -// @Override -// public void onExecutorBefore(@NonNull Runnable runnable, @NonNull ThreadConfig.TaskType type) { -// //每个任务执行前回调 -//// if (type == ThreadConfig.TaskType.HandlerThread) { -//// -//// -//// } -// } -// -// @Override -// public void onExecutorAfter(@NonNull Runnable runnable, @NonNull ThreadConfig.TaskType type) { -// //每个任务执行后回调 -// } -// -// /** -// * @param core 线程池的核心数 -// * @param max 线程池的最大线程数 -// * @param active 线程池正在活跃的任务数 -// * @param completed 线程池已完成的任务数 -// */ -// @Override -// public void onExecutorStateChanged(@NonNull ThreadPoolExecutor pool, int core, int max, int active, long completed) { -// //线程池在执行过程,状态变化回调 -// //Log.d("POOL", "core:" + core + ";max:" + max + ";active:" + active + ";completed:" + completed); -// } -// }); -// builder.loggable(false); -// ThreadManager.INSTANCE.init(builder); - } - @Override protected void initCrashConfig() { CrashSystem crashSystem = CrashSystem.getInstance(this); @@ -122,4 +83,4 @@ public class MogoApplication extends MainMoGoApplication { super.initLogConfig(); Logger.init(BuildConfig.DEBUG ? LogLevel.DEBUG : LogLevel.OFF); } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/lancet/CrashFix.kt b/app/src/main/java/com/mogo/launcher/lancet/CrashFix.kt new file mode 100644 index 0000000000..09ae7d1c42 --- /dev/null +++ b/app/src/main/java/com/mogo/launcher/lancet/CrashFix.kt @@ -0,0 +1,32 @@ +package com.mogo.launcher.lancet + +import android.content.ComponentName +import android.content.Intent +import androidx.annotation.* +import com.knightboost.lancet.api.Origin +import com.knightboost.lancet.api.Scope.ALL +import com.knightboost.lancet.api.Scope.LEAF +import com.knightboost.lancet.api.annotations.* + +@Keep +@Weaver +@Group("crash_fix") +class CrashFix { + + /** + * 修正Android8.0及之后,后台启动Service引起的崩溃 + * java.lang.IllegalStateException: Not allowed to start service Intent { + * act=com.zhidao.cosupload.service.UPLOAD_ACTION cmp=com.mogo.launcher.f/com.zhidao.cosupload.service.UploadService }: app is in background uid UidRecord{6443b7b u0a404 LAST bg:+1m15s362ms idle change:idle procs:1 seq(0,0,0)} + */ + @Insert(mayCreateSuper = true) + @TargetClass("android.content.Context", scope = LEAF) + @TargetMethod(methodName = "startService") + fun fixStartServiceCrash(intent: Intent): ComponentName? { + return try { + Origin.call() as ComponentName? + } catch (t: Throwable) { + t.printStackTrace() + null + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/stageone/APMStartup.kt b/app/src/main/java/com/mogo/launcher/stageone/APMStartup.kt index 00d7da6b9e..3e812b590e 100644 --- a/app/src/main/java/com/mogo/launcher/stageone/APMStartup.kt +++ b/app/src/main/java/com/mogo/launcher/stageone/APMStartup.kt @@ -22,6 +22,6 @@ class APMStartup : AndroidStartup() { } override fun dependenciesByName(): List { - return listOf("com.mogo.launcher.stageone.ARouterStartUp", "com.mogo.launcher.stageone.ConfigStartUp") + return listOf("com.mogo.launcher.stageone.ARouterStartUp", "com.mogo.launcher.stageone.ThreadOptStartup") } } \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/stageone/ARouterStartUp.kt b/app/src/main/java/com/mogo/launcher/stageone/ARouterStartUp.kt index 1cab03977a..15c913da9b 100644 --- a/app/src/main/java/com/mogo/launcher/stageone/ARouterStartUp.kt +++ b/app/src/main/java/com/mogo/launcher/stageone/ARouterStartUp.kt @@ -31,4 +31,8 @@ class ARouterStartUp : AndroidStartup() { } override fun waitOnMainThread() = false + + override fun dependenciesByName(): List? { + return listOf("com.mogo.launcher.stageone.ThreadOptStartup") + } } \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt b/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt index c7b454eada..9c5c13cc30 100644 --- a/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt +++ b/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt @@ -168,4 +168,8 @@ class ConfigStartUp : AndroidStartup() { MapAutoApi.init(context, mapParams) } + + override fun dependenciesByName(): List { + return listOf("com.mogo.launcher.stageone.ThreadOptStartup") + } } \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt b/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt index 7429cdc0cb..a189438325 100644 --- a/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt +++ b/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt @@ -70,7 +70,8 @@ class HttpDnsStartUp : AndroidStartup() { override fun dependenciesByName(): List { return listOf( - "com.mogo.launcher.stageone.APMStartup" + "com.mogo.launcher.stageone.APMStartup", + "com.mogo.launcher.stageone.ThreadOptStartup" ) } @@ -377,5 +378,4 @@ class HttpDnsStartUp : AndroidStartup() { MogoAiCloudSocketManager.getInstance(context) .init(context, DebugConfig.getSocketAppId(), lat, lon) } - } \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/stageone/ThreadOptStartup.kt b/app/src/main/java/com/mogo/launcher/stageone/ThreadOptStartup.kt new file mode 100644 index 0000000000..d0043384b8 --- /dev/null +++ b/app/src/main/java/com/mogo/launcher/stageone/ThreadOptStartup.kt @@ -0,0 +1,33 @@ +package com.mogo.launcher.stageone + +import android.content.* +import com.mogo.thread.ext.core.* +import com.mogo.thread.ext.core.config.* +import com.rousetime.android_startup.* +import java.io.* +import java.text.SimpleDateFormat +import java.util.* +import java.util.concurrent.TimeUnit.SECONDS + +class ThreadOptStartup: AndroidStartup() { + + override fun create(context: Context): Boolean { + ThreadManager + .init(ThreadConfig.Builder() + .maxKeepAliveTime(5, SECONDS) + /*.dump(DumpConfig.Builder() + .dumpLogFilePath(File(context.getExternalFilesDir(null), "thread_dump_log_${ SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.ROOT).format(Date()) }.txt").absolutePath) + .dumpPeriod(5, SECONDS) + .threadRunThreshold(10, SECONDS) + .build())*/) + return true + } + + override fun callCreateOnMainThread(): Boolean { + return true + } + + override fun waitOnMainThread(): Boolean { + return true + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index b3c135a6a2..66ec9a72f2 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ buildscript { classpath "com.mogo.cloud:hook:${HOOK_LOG_VERSION}" classpath "com.mogo.cloud:bizconfig:${BIZCONFIG_VERSION}" classpath 'com.volcengine:apm_insight_plugin:1.4.1' -// classpath "com.mogo.thread.opt:plg:${THREAD_OPT_VERSION}" + classpath "com.mogo.thread.opt:plg:${THREAD_OPT_VERSION}" classpath 'com.mogo.cloud:systrace:1.0.1' classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.18' classpath 'com.mogo.sticky:service:1.0.8' diff --git a/config.gradle b/config.gradle index 3433f36bc9..9c6fdcf353 100644 --- a/config.gradle +++ b/config.gradle @@ -183,8 +183,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-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt index bf4df25490..05b6ab8ac8 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt @@ -3,12 +3,12 @@ package com.mogo.eagle.core.function.hmi.ui import android.content.Context import android.os.Bundle import android.text.TextUtils +import android.util.* import android.view.View import android.view.ViewGroup import android.view.animation.AlphaAnimation import android.view.animation.Animation import android.view.animation.LinearInterpolator -import android.widget.FrameLayout import androidx.lifecycle.lifecycleScope import com.alibaba.android.arouter.facade.annotation.Route import com.alibaba.android.arouter.launcher.ARouter @@ -86,12 +86,9 @@ import com.mogo.eagle.core.utilcode.util.ToastUtils import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig import com.zhjt.service_biz.BizConfig import kotlinx.android.synthetic.main.fragment_hmi.* -import kotlinx.coroutines.Job -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import kotlinx.coroutines.suspendCancellableCoroutine +import kotlinx.coroutines.* import record_cache.RecordPanelOuterClass - +import java.util.concurrent.atomic.AtomicReference /** * @author xiaoyuzhou @@ -116,8 +113,7 @@ class MoGoHmiFragment : MvpFragment(), // todo 需要统一数据源 限速 View代理 private var mViewLimitingVelocity: IViewLimitingVelocity? = null - private var lastSpeakJob: Job? = null - + private val lastSpeakJob by lazy { AtomicReference() } private var lastShowV2XJob: Job? = null private var showingV2XTip: IReminder? = null @@ -482,10 +478,7 @@ class MoGoHmiFragment : MvpFragment(), "$M_HMI$TAG", "--- show v2x dialog 1 ---: info -> v2x-type: $v2xType : expireTime: $expireTime" ) - lastShowV2XJob?.safeCancel() - lastSpeakJob?.safeCancel() - lifecycleScope.launch { delay(expireTime) }.also { itx -> @@ -496,10 +489,18 @@ class MoGoHmiFragment : MvpFragment(), } if (ttsContent != null && !TextUtils.isEmpty(ttsContent) && playTTS) { - lifecycleScope.launch { + val last = lastSpeakJob.get() + Log.d("CODE", "---- 0 ------: last: $last") + if (last != null && !last.isCompleted) { + Log.d("CODE", "---- 1 ------") + return + } + lifecycleScope.launch(Dispatchers.Default) { + Log.d("CODE", "---- 2 ------") speak(it, ttsContent) + Log.d("CODE", "---- 3 ------") }.also { itx -> - lastSpeakJob = itx + lastSpeakJob.set(itx) } } } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt index 2c1610c20b..81460a5ce6 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt @@ -82,7 +82,9 @@ import mogo_msg.MogoReportMsg import java.text.SimpleDateFormat import java.util.* import kotlin.math.abs - +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.launch +import com.mogo.eagle.core.utilcode.kotlin.lifecycleOwner /** * @author xiaoyuzhou @@ -1734,18 +1736,20 @@ internal class DebugSettingView @JvmOverloads constructor( * OBU状态回调 */ override fun onObuStatusResponse(obuStatusInfo: ObuStatusInfo) { - tvObuInfo.text = GsonUtils.toJson(obuStatusInfo) + lifecycleOwner.lifecycleScope.launch { + tvObuInfo.text = GsonUtils.toJson(obuStatusInfo) - AppConfigInfo.obuSdkVersion = obuStatusInfo.obuSdkVersion - AppConfigInfo.isConnectObu = obuStatusInfo.obuStatus + AppConfigInfo.obuSdkVersion = obuStatusInfo.obuSdkVersion + AppConfigInfo.isConnectObu = obuStatusInfo.obuStatus - if (obuStatusInfo.obuStatus) { - obuConnectStatus = true - } - //OBU断开连接,提示异常 - if (obuConnectStatus && !obuStatusInfo.obuStatus) { - obuConnectStatus = false - toastMsg("OBU连接状态异常") + if (obuStatusInfo.obuStatus) { + obuConnectStatus = true + } + //OBU断开连接,提示异常 + if (obuConnectStatus && !obuStatusInfo.obuStatus) { + obuConnectStatus = false + toastMsg("OBU连接状态异常") + } } } diff --git a/core/function-impl/mogo-core-function-v2x/build.gradle b/core/function-impl/mogo-core-function-v2x/build.gradle index 5884122465..299bfe9cbf 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,15 +64,18 @@ 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 implementation rootProject.ext.dependencies.mogo_core_data implementation rootProject.ext.dependencies.mogo_core_utils implementation rootProject.ext.dependencies.mogo_core_function_call implementation rootProject.ext.dependencies.mogo_core_res + compileOnly rootProject.ext.dependencies.mogomap } else { implementation project(":foudations:mogo-commons") implementation project(':core:mogo-core-data') @@ -66,7 +83,7 @@ dependencies { implementation project(':core:mogo-core-function-call') implementation project(':core:mogo-core-res') implementation project(':libraries:mogo-adas') - + compileOnly project(':libraries:mogo-map') } } 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 fb67376fdf..d0945dedbf 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 @@ -1,26 +1,19 @@ package com.mogo.eagle.core.function.v2x.events -import android.content.Context -import android.content.Intent -import android.os.Handler -import android.os.Looper -import android.util.Log -import androidx.core.util.Pair -import androidx.localbroadcastmanager.content.LocalBroadcastManager -import com.mogo.cloud.commons.utils.CoordinateUtils -import com.mogo.cloud.passport.IMoGoTokenCallback -import com.mogo.cloud.passport.MoGoAiCloudClient -import com.mogo.cloud.passport.MoGoAiCloudClientConfig +import android.content.* +import android.os.* +import android.util.* +import androidx.localbroadcastmanager.content.* +import com.mogo.cloud.passport.* import com.mogo.commons.module.ServiceConst.CARD_TYPE_ROAD_CONDITION -import com.mogo.commons.network.ParamsUtil +import com.mogo.eagle.core.data.enums.EventTypeEnumNew +import com.mogo.eagle.core.data.enums.EventTypeHelper +import com.mogo.commons.network.* import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_ALIAS_CODE_CLOUD_V2N import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_CLOUD import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_LOG_CLOUD_V2N -import com.mogo.eagle.core.data.enums.EventTypeEnum -import com.mogo.eagle.core.data.enums.EventTypeHelper -import com.mogo.eagle.core.data.enums.TrafficTypeEnum -import com.mogo.eagle.core.data.map.MogoLatLng -import com.mogo.eagle.core.data.map.MogoLocation +import com.mogo.eagle.core.data.enums.* +import com.mogo.eagle.core.data.map.* import com.mogo.eagle.core.data.map.entity.MarkerExploreWay import com.mogo.eagle.core.data.map.entity.MarkerShowEntity import com.mogo.eagle.core.data.map.entity.V2XMessageEntity @@ -28,64 +21,55 @@ import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.V2XMsg -import com.mogo.eagle.core.data.traffic.TrafficData -import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener -import com.mogo.eagle.core.function.api.map.listener.IMoGoMapLocationListener -import com.mogo.eagle.core.function.call.hmi.CallerHmiManager -import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager -import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager -import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager +import com.mogo.eagle.core.data.traffic.* +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.CallerAutoPilotStatusListenerManager +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 import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.TooClose import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager -import com.mogo.eagle.core.function.v2x.events.alarm.V2XAlarmServer -import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi +import com.mogo.eagle.core.function.v2x.events.alarm.* +import com.mogo.eagle.core.function.v2x.events.bridge.* import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi.context -import com.mogo.eagle.core.function.v2x.events.consts.V2XConst -import com.mogo.eagle.core.function.v2x.events.consts.V2XConst.BROADCAST_SCENE_EXTRA_KEY -import com.mogo.eagle.core.function.v2x.events.consts.V2XConst.BROADCAST_SCENE_HANDLER_ACTION -import com.mogo.eagle.core.function.v2x.events.manager.V2XStatusManager -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.AiRoadMarker -import com.mogo.eagle.core.function.v2x.events.scenario.scene.airoad.AiRoadMarker.Marker +import com.mogo.eagle.core.function.v2x.events.consts.* +import com.mogo.eagle.core.function.v2x.events.consts.V2XConst.* +import com.mogo.eagle.core.function.v2x.events.manager.* +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.utils.* import com.mogo.eagle.core.function.v2x.events.utils.MapUtils -import com.mogo.eagle.core.function.v2x.events.utils.TrackUtils -import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger -import com.mogo.eagle.core.utilcode.mogo.logger.Logger +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.utilcode.mogo.logger.* import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_V2X -import com.mogo.eagle.core.utilcode.util.ThreadUtils +import com.mogo.eagle.core.utilcode.util.* import com.mogo.eagle.core.utilcode.util.Utils -import com.mogo.map.marker.IMogoMarker -import com.mogo.map.marker.IMogoMarkerClickListener +import com.mogo.map.marker.* import com.mogo.map.marker.MogoMarkersHandler.Companion.mogoMarkersHandler -import com.mogo.v2x.V2XManager -import com.mogo.v2x.callback.IV2XCallback -import com.mogo.v2x.config.V2XConfig -import com.mogo.v2x.data.* -import com.mogo.v2x.event.V2XEvent -import com.shuyu.gsyvideoplayer.GSYVideoManager -import com.shuyu.gsyvideoplayer.cache.CacheFactory -import com.shuyu.gsyvideoplayer.cache.ProxyCacheManager -import com.shuyu.gsyvideoplayer.model.VideoOptionModel -import com.shuyu.gsyvideoplayer.player.IjkPlayerManager -import com.shuyu.gsyvideoplayer.player.PlayerFactory -import com.shuyu.gsyvideoplayer.utils.GSYVideoType -import com.zhjt.service.chain.ChainLog -import com.zhjt.service.chain.TracingConstants -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.android.asCoroutineDispatcher -import kotlinx.coroutines.cancel -import kotlinx.coroutines.launch -import roadwork.Road.RW_PB -import tv.danmaku.ijk.media.player.IjkMediaPlayer -import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicBoolean +import com.shuyu.gsyvideoplayer.* +import com.shuyu.gsyvideoplayer.cache.* +import com.shuyu.gsyvideoplayer.model.* +import com.shuyu.gsyvideoplayer.player.* +import com.shuyu.gsyvideoplayer.utils.* +import com.zhjt.service.chain.* +import io.reactivex.disposables.Disposable +import kotlinx.coroutines.* +import kotlinx.coroutines.android.* +import tv.danmaku.ijk.media.player.* +import java.util.concurrent.* +import java.util.concurrent.atomic.* -object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallback{ +object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallback { private const val TAG = "V2XEventManager" @@ -95,15 +79,19 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb private val hasInit by lazy { AtomicBoolean(false) } + // 记录历史行驶轨迹,用于车行驶方向计算,只保留两个数据 + private val historyPath = arrayOfNulls(2) + + var v2xEventDisposable: Disposable? = null + fun init(context: Context) { 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) - it.loggable(false) + it.loggable(true) it.distanceForTriggerRefresh(200f) //行驶超过200(包含)米,刷新道路周边信息(短链请求) it.durationForTriggerRefresh( 60, @@ -114,11 +102,9 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb }.build()) V2XManager.start() } - registerListener() V2XManager.forceRefresh() MoGoAiCloudClient.getInstance().addTokenCallbacks(this) - // 注册广播接收场景弹窗使用的 SceneBroadcastReceiver.register(context) } @@ -139,6 +125,7 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb private fun unRegisterListener() { V2XManager.removeCallback(this) CallerMapLocationListenerManager.removeListener(TAG, false) + mogoMarkersHandler.unregisterMarkerClickListener(CARD_TYPE_ROAD_CONDITION) } @@ -199,6 +186,18 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb return null } + /** + * 刷新自车求助状态 + * + * @param isTrue + */ + private fun refreshMeSeekHelp(isTrue: Boolean) { + val entity = V2XMessageEntity() + entity.type = V2XMessageEntity.V2XTypeEnum.ALERT_CAR_FOR_HELP + entity.content = isTrue + V2XScenarioManager.getInstance().handlerMessage(entity) + } + override fun onLocationChanged(location: MogoLocation?, from: Int, isGps: Boolean) { location ?: return BridgeApi.location.set(location) @@ -239,13 +238,16 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb ) if (v2XRoadEventEntity != null) { val distance = v2XRoadEventEntity.distance - val min = if (EventTypeEnum.AI_ROAD_WORK.poiType == v2XRoadEventEntity.poiType) 0 else 5 - Logger.d( - TAG, + val min = if (EventTypeEnumNew.isCloudSocketEvent(v2XRoadEventEntity.poiType)) 0 else 5 + CallerLogger.d( + "$M_V2X$TAG", "--- trigger show before ---:data=>[${location.longitude}, ${location.latitude}, ${location.speed}], distance: $distance, minDistance: $min, poiType: ${v2XRoadEventEntity.poiType}" ) if (distance >= min) { - Logger.d(TAG, "--- trigger show ---:poiType:" + v2XRoadEventEntity.poiType) + CallerLogger.d( + "$M_V2X$TAG", + "--- trigger show ---:poiType:" + v2XRoadEventEntity.poiType + ) TrackUtils.trackV2xRoadProduceEvent(1) val v2XMessageEntity = V2XMessageEntity() v2XMessageEntity.type = V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_WARNING @@ -294,55 +296,19 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb handleWarningTargetEvent(event.data) } is V2XEvent.RoadAI -> { - handleRoadMarkerEvent(event.data.toRoadMarker) + /* + TODO zhongchao 先注掉,编译通过 + if(FunctionBuildConfig.isV2NFromCar){ + return + }*/ + handleRoadMarkerEvent(event.data.toRoadMarker()) + } + + is V2XEvent.RoadEventX -> { + handleRoadMarkerEvent(event.data.toRoadMarker()) } } } - - private val RW_PB.toRoadMarker: V2XMarkerCardResult - get() = V2XMarkerCardResult().also { l1 -> - this.roadwork?.polygonList?.takeIf { it.isNotEmpty() }?.also { old -> - l1.extras = HashMap>>().also { extra -> - extra["polygon"] = old.map { d -> - Pair(d.lon, d.lat) - } - - extra["gps_location"] = listOf( - Pair( - this.roadwork?.center?.point?.lon ?: 0.0, - this.roadwork?.center?.point?.lat ?: 0.0 - ) - ) - } - } - l1.exploreWay = ArrayList().also { l2 -> - l2.add(V2XMarkerExploreWay().also { l3 -> - l3.poiType = this.roadwork?.poiType?.toString() - l3.generateTime = this.roadwork?.detectTime ?: 0L - l3.location = V2XMarkerLocation().also { l4 -> - 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] - l4.angle = this.roadwork?.center?.road?.bearing?.toDouble() ?: 0.0 - } - }) - } - - AiRoadMarker.receive( - Marker( - this.roadwork?.center?.point?.lat ?: 0.0, - this.roadwork?.center?.point?.lon ?: 0.0, - this.roadwork?.center?.road?.bearing?.toDouble() ?: 0.0, - null, - null, - null - ) - ) - } - private fun handleWarningTargetEvent(data: V2XWarningTarget) { val v2xMessageEntity = V2XMessageEntity() v2xMessageEntity.type = V2XMessageEntity.V2XTypeEnum.ALERT_THE_FRONT_WEAKNESS @@ -403,32 +369,34 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb } 1003 -> { // 交叉路口碰撞预警 + /* + TODO xiaopeng 先注掉,编译通过 changeVisualAngle = true - tempAppId = EventTypeEnum.TYPE_USECASE_ID_ICW.poiType.toInt() - tempTts = EventTypeEnum.TYPE_USECASE_ID_ICW.tts - tempContent = EventTypeEnum.TYPE_USECASE_ID_ICW.content + tempAppId = EventTypeEnumNew.TYPE_USECASE_ID_ICW.poiType.toInt() + tempTts = EventTypeEnumNew.TYPE_USECASE_ID_ICW.tts + tempContent = EventTypeEnumNew.TYPE_USECASE_ID_ICW.content*/ } 1004 -> { // 交叉路口碰撞预警 changeVisualAngle = true - tempAppId = EventTypeEnum.TYPE_USECASE_ID_BSW.poiType.toInt() + tempAppId = EventTypeEnumNew.TYPE_USECASE_ID_BSW.poiType.toInt() tempTts = String.format( - EventTypeEnum.TYPE_USECASE_ID_BSW.tts, + EventTypeEnumNew.TYPE_USECASE_ID_BSW.tts, getWarningDirection() ) - tempContent = EventTypeEnum.TYPE_USECASE_ID_BSW.content + tempContent = EventTypeEnumNew.TYPE_USECASE_ID_BSW.content } 1006 -> { // 逆向超车预警 - tempAppId = EventTypeEnum.TYPE_USECASE_ID_DNPW.poiType.toInt() - tempTts = EventTypeEnum.TYPE_USECASE_ID_DNPW.tts - tempContent = EventTypeEnum.TYPE_USECASE_ID_DNPW.content + tempAppId = EventTypeEnumNew.TYPE_USECASE_ID_DNPW.poiType.toInt() + tempTts = EventTypeEnumNew.TYPE_USECASE_ID_DNPW.tts + tempContent = EventTypeEnumNew.TYPE_USECASE_ID_DNPW.content } 1005 -> { // 闯红灯预警 - tempAppId = EventTypeEnum.TYPE_USECASE_ID_IVP.poiType.toInt() - tempTts = EventTypeEnum.TYPE_USECASE_ID_IVP.tts - tempContent = EventTypeEnum.TYPE_USECASE_ID_IVP.content + tempAppId = EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType.toInt() + tempTts = EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.tts + tempContent = EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.content } 2001 -> { // 最优车道100061 @@ -521,6 +489,65 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb } } + fun queryWholeRoadEvents() { + if (v2xEventDisposable != null && !v2xEventDisposable!!.isDisposed) { + v2xEventDisposable!!.dispose() + } + val sn = MoGoAiCloudClientConfig.getInstance().sn + val lineId = getLineId() + if (lineId > 0) { + realQueryV2xEvents(lineId.toString(), sn) + } else { + UiThreadHandler.postDelayed({ + realQueryV2xEvents(getLineId().toString(), sn) + }, 500) + } + } + + private fun realQueryV2xEvents(lineId: String, sn: String) { + /* + TODO fufeng 先注掉,编译通过 + v2xEventDisposable = MoGoRetrofitFactory.getInstance(HostConst.getHost()) + .create(V2XEventServiceApi::class.java) + .queryAllV2XEventsByLineId(lineId, sn) + .map { + if (it.code == 200 || it.code == 0) { + CallerLogger.d(M_V2X + TAG, "请求成功,size为:${it.result?.v2XEventList?.size}") + return@map it.result?.v2XEventList + } else { + CallerLogger.d(M_V2X + TAG, "请求失败,code为:${it.code}") + return@map ArrayList() + } + } + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { + val size = it?.size ?: 0 + if (size > 0) { + val msgBoxBean = MsgBoxBean(MsgBoxType.V2X, V2XMsg("", "查询到当前全程共${size}个事件", "")) + msgBoxBean.sourceType = DataSourceType.SUMMARY + CallerMsgBoxManager.saveMsgBox(msgBoxBean) + } + }*/ + } + + private fun getLineId(): Long { + var lineId: Long = -1 + val parameter = CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo() + .autopilotControlParameters + if (parameter != null) { + if (parameter.autoPilotLine != null) { + lineId = parameter.autoPilotLine!!.lineId + CallerLogger.d(M_V2X + TAG, "lineId为:$lineId") + } else { + CallerLogger.d(M_V2X + TAG, "parameter.autoPilotLine为null") + } + } else { + CallerLogger.d(M_V2X + TAG, "parameter为null") + } + return lineId + } + override fun onFail(msg: String) { CallerLogger.e("$M_V2X$TAG", "Error: $msg") } @@ -538,4 +565,5 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb } } } + } \ 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/events/alarm/V2XAlarmServer.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/alarm/V2XAlarmServer.java index 70a82ab838..0c09db8c20 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/alarm/V2XAlarmServer.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/alarm/V2XAlarmServer.java @@ -9,6 +9,7 @@ import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils; import java.util.Iterator; import java.util.concurrent.CopyOnWriteArrayList; import io.netty.util.internal.ConcurrentSet; +import android.util.Log; /** * @author donghongyu @@ -33,6 +34,7 @@ public class V2XAlarmServer { CopyOnWriteArrayList v2XRoadEventEntityList, MogoLocation currentLocation) { try { + Log.d("RWJ", "getDriveFrontAlarmEvent --- 1 ---" + currentLocation ); if (!showedEvents.isEmpty()) { Iterator iterator = showedEvents.iterator(); while (iterator.hasNext()) { @@ -49,15 +51,18 @@ public class V2XAlarmServer { } } } + Log.d("RWJ", "getDriveFrontAlarmEvent --- 2 ---" + currentLocation); if (currentLocation != null && v2XRoadEventEntityList != null) { // 因为集合是按照距离排序后的所以这里检索出来第一个就发出警告 for (V2XRoadEventEntity v2XRoadEventEntity : v2XRoadEventEntityList) { // 0、道路事件必须有朝向,角度>=0; + Log.d("RWJ", "entity:" + v2XRoadEventEntity.getLocation()); if (v2XRoadEventEntity.getLocation().getAngle() >= 0) { // 计算车辆距离指定气泡的距离 MarkerLocation eventLocation = v2XRoadEventEntity.getLocation(); // 1、判断是否到达了触发距离,20 ~ 500, double distance = v2XRoadEventEntity.getDistance(); + Log.d("RWJ", "distance:" + distance); if (distance <= 500) { if (EventTypeEnum.GHOST_PROBE.getPoiType().equals(v2XRoadEventEntity.getPoiType())) { if (distance > 25) { @@ -68,7 +73,8 @@ public class V2XAlarmServer { double carBearing = currentLocation.getBearing(); double eventBearing = eventLocation.getAngle(); double diffAngle = DrivingDirectionUtils.getAngleDiff(carBearing, eventBearing); - if (diffAngle < 20) { + Log.d("RWJ", "car_bearing:" + carBearing + ",eventBearing:" + eventBearing + ",diffAngle:" + diffAngle); + if (diffAngle <= 20) { // 3、计算当前车辆行驶方向与事件位置之间夹角《20度,保证道路事件在车辆前方 double eventAngle = DrivingDirectionUtils.getDegreeOfCar2Poi( currentLocation.getLongitude(), @@ -77,10 +83,13 @@ public class V2XAlarmServer { eventLocation.getLat(), (int) currentLocation.getBearing() ); + + Log.d("RWJ", "eventAngle:" + eventAngle); if (0 <= eventAngle && eventAngle <= 20) { if (showedEvents.contains(v2XRoadEventEntity)) { return null; } + Log.d("RWJ", "showed---"); showedEvents.add(v2XRoadEventEntity); return v2XRoadEventEntity; } @@ -91,6 +100,7 @@ public class V2XAlarmServer { } } catch (Exception e) { e.printStackTrace(); + Log.w("RWJ", "error: " + e.getMessage()); } return null; } 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..f82f7c4014 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 @@ -4,8 +4,9 @@ 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.IMogoMarker; 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; @@ -37,11 +38,11 @@ public interface IMoGoV2XMarkerManager extends IProvider { /** * 绘制正在预警的道路事件的POI点 - * - * @param context + * @param context * @param roadEventEntity + * @return */ - void drawableAlarmPOI(Context context, V2XRoadEventEntity roadEventEntity, IMogoMarkerClickListener clickListener); + IMogoMarker drawableAlarmPOI(Context context, V2XRoadEventEntity roadEventEntity, IMogoMarkerClickListener clickListener); /** * 清除 道路事件 POI 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 4394184df3..13432dbf4f 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 @@ -32,10 +32,10 @@ import com.mogo.map.marker.IMogoMarkerClickListener; import com.mogo.map.marker.IMogoMarkerManager; import com.mogo.map.marker.MogoMarkerOptions; import com.mogo.eagle.core.data.enums.EventTypeEnum; -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; @@ -55,8 +55,7 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager { // 记录所有的:新鲜事儿的道路事件点、探路事件 private static final CopyOnWriteArraySet mV2XRoadEventEntityArrayList = new CopyOnWriteArraySet<>(); - // 上次的道路事件的预警Marker - private static IMogoMarker mAlarmInfoMarker; + @Override public void drawableLastAllPOI() { @@ -132,7 +131,7 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager { } @Override - public void drawableAlarmPOI(Context context, V2XRoadEventEntity roadEventEntity, IMogoMarkerClickListener clickListener) { + public IMogoMarker drawableAlarmPOI(Context context, V2XRoadEventEntity roadEventEntity, IMogoMarkerClickListener clickListener) { try { IMoGoV2XStatusManager v2xStatus = BridgeApi.INSTANCE.v2xStatus(); if (v2xStatus != null) { @@ -147,7 +146,6 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager { .latitude(roadEventEntity.getLocation().getLat()) .longitude(roadEventEntity.getLocation().getLon()); optionsRipple.anchor(0.5f, 0.5f); - MarkerShowEntity markerShowEntity = new MarkerShowEntity(); MarkerExploreWay markerExploreWay = roadEventEntity.getNoveltyInfo(); markerShowEntity.setBindObj(markerExploreWay); @@ -155,22 +153,21 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager { markerShowEntity.setTextContent(markerExploreWay.getAddr()); markerShowEntity.setMarkerLocation(markerExploreWay.getLocation()); markerShowEntity.setMarkerType(CARD_TYPE_NOVELTY); - optionsRipple.icons(V2XMarkerAdapter.getV2XRoadEventViewGif(context, roadEventEntity)); optionsRipple.period(1); - + IMogoMarker ret = null; if (MogoStatusManager.getInstance().isVrMode()) { - mAlarmInfoMarker = Objects.requireNonNull(CallerMapUIServiceManager.INSTANCE.getMarkerService()).drawMarker(markerShowEntity); + ret = Objects.requireNonNull(CallerMapUIServiceManager.INSTANCE.getMarkerService()).drawMarker(markerShowEntity); } else { optionsRipple.icon(V2XMarkerAdapter.getV2XRoadEventViewPng(context, roadEventEntity)); IMogoMarkerManager marker = CallerMapUIServiceManager.INSTANCE.getMarkerManager(context); if (marker != null) { - mAlarmInfoMarker = marker.addMarker(V2X_EVENT_ALARM_POI, optionsRipple); + ret = marker.addMarker(V2X_EVENT_ALARM_POI, optionsRipple); } } // 当前Marker设置为最上面 - if (mAlarmInfoMarker != null) { - mAlarmInfoMarker.setToTop(); + if (ret != null) { + ret.setToTop(); } // 绘制连接线 IMoGoV2XPolylineManager polylineManager = BridgeApi.INSTANCE.v2xPolyline(); @@ -182,28 +179,30 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager { new MogoLatLng(roadEventEntity.getLocation().getLat(), roadEventEntity.getLocation().getLon() ), context); + + return ret; } else { CallerLogger.INSTANCE.e(M_V2X + TAG, "Location 必须进行初始化!!!!!"); } } catch (Exception e) { e.printStackTrace(); } + return null; } @Override public void clearAlarmPOI() { - - boolean isRoadEventPOIShow = false; - IMoGoV2XStatusManager v2xStatus = BridgeApi.INSTANCE.v2xStatus(); - if (v2xStatus != null) { - isRoadEventPOIShow = v2xStatus.isRoadEventPOIShow(); - } - if (isRoadEventPOIShow) { - v2xStatus.setRoadEventPOIShow(TAG, false); - if (mAlarmInfoMarker != null) { - mAlarmInfoMarker.remove(); - } - } +// boolean isRoadEventPOIShow = false; +// IMoGoV2XStatusManager v2xStatus = BridgeApi.INSTANCE.v2xStatus(); +// if (v2xStatus != null) { +// isRoadEventPOIShow = v2xStatus.isRoadEventPOIShow(); +// } +// if (isRoadEventPOIShow) { +// v2xStatus.setRoadEventPOIShow(TAG, false); +// if (mAlarmInfoMarker != null) { +// mAlarmInfoMarker.remove(); +// } +// } } @Override @@ -220,9 +219,9 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager { @Override public void forceClearAlarmPOI() { - if (mAlarmInfoMarker != null) { - mAlarmInfoMarker.remove(); - } +// if (mAlarmInfoMarker != null) { +// mAlarmInfoMarker.remove(); +// } } @Override diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/MarkerManager.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/MarkerManager.kt new file mode 100644 index 0000000000..1039bbcd30 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/MarkerManager.kt @@ -0,0 +1,193 @@ +package com.mogo.eagle.core.function.v2x.events.marker + +import android.os.Handler +import android.os.HandlerThread +import android.util.Log +import com.mogo.cloud.commons.utils.CoordinateUtils +import com.mogo.eagle.core.data.map.MogoLocation +import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager +import com.mogo.eagle.core.utilcode.util.* +import com.mogo.map.marker.IMogoMarker +import com.mogo.map.overlay.IMogoPolyline +import kotlinx.coroutines.Runnable +import java.util.LinkedList +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicReference + + +data class MarkerWrapper(val id: String, val lon: Double, val lat: Double, val coordinateType: Int, var markers: ArrayList? = null, var lines: ArrayList? = null) { + + fun addLine(line: IMogoPolyline) { + var ll = this.lines + if (ll == null) { + ll = ArrayList() + this.lines = ll + } + ll.add(line) + } + + fun addMarker(marker: IMogoMarker) { + var mm = this.markers + if (mm == null) { + mm = ArrayList() + this.markers = mm + } + mm.add(marker) + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as MarkerWrapper + + if (id != other.id) return false + + return true + } + + override fun hashCode(): Int { + return id.hashCode() + } +} + +object MarkerManager { + + private const val TAG = "MarkerManager" + + private val showedMarkers by lazy { LinkedList() } + + private val toRemoveMakers by lazy { LinkedList() } + + private val isFirstAdd by lazy { AtomicBoolean(false) } + + private val elapsedDistances by lazy { ConcurrentHashMap() } + + private val lastCarLocation by lazy { AtomicReference() } + + private val lastGpsLocation by lazy { AtomicReference() } + + private val checkTask = object : Runnable { + + override fun run() { + + try { + Log.d(TAG, "--- checkTask --- 1 ---") + if (lastCarLocation.get() == null) { + return + } + Log.d(TAG, "--- checkTask --- 2 ---") + if (lastGpsLocation.get() == null) { + return + } + Log.d(TAG, "--- checkTask --- 3 ---") + val toRemove = toRemoveMakers.iterator() + val carLoc = AtomicReference() + while (toRemove.hasNext()) { + val marker = toRemove.next() + if (carLoc.get() == null) { + carLoc.set(if (marker.coordinateType == 0) { + //高德坐标 + CallerMapLocationListenerManager.getCurrentLocation() + } else { + CallerMapLocationListenerManager.getCurrentGpsLocation() + }) + } + val currentLocation = carLoc.get() + val lastLocation = if (marker.coordinateType == 0) lastCarLocation.get() else lastGpsLocation.get() + if (currentLocation != null && lastLocation != null) { + val delta = CoordinateUtils.calculateLineDistance(currentLocation.longitude, currentLocation.latitude, lastLocation.longitude, lastLocation.latitude) + Log.d(TAG, "--- checkTask --- 4 ---:delta:$delta, id:${marker.id}") + var elapsed = elapsedDistances[marker] + if (elapsed == null) { + elapsed = delta.toDouble() + } else { + elapsed += delta + } + Log.d(TAG, "--- checkTask --- 5 ---:delta:$delta, elapsed:${elapsed}, id: ${marker.id}") + if (elapsed >= 200) { + var removeMarkerError = false + marker.markers?.forEach { + try { + Log.e(TAG, "--- checkTask --- remove marker: $it, id: ${marker.id}") + it.setVisible(false) + it.destroy() + } catch (t: Throwable) { + t.printStackTrace() + removeMarkerError = true + Log.e(TAG, "--- checkTask --- remove marker error:${t.message}, id: ${marker.id}") + } + } + var removeLineError = false + marker.lines?.forEach { + try { + it.isVisible = false + Log.e(TAG, "--- checkTask --- remove line : $it, id:${marker.id}") + it.destroy() + } catch (t: Throwable) { + t.printStackTrace() + removeLineError = true + Log.e(TAG, "--- checkTask --- remove line error:${t.message}, id: ${marker.id}") + } + } + if (!removeLineError && !removeMarkerError) { + toRemove.remove() + synchronized(elapsedDistances) { + elapsedDistances.remove(marker) + } + } + } else { + elapsedDistances[marker] = elapsed + } + } + } + val iterator = showedMarkers.iterator() + while (iterator.hasNext()) { + val marker = iterator.next() + if (carLoc.get() == null) { + carLoc.set(if (marker.coordinateType == 0) { + //高德坐标 + CallerMapLocationListenerManager.getCurrentLocation() + } else { + CallerMapLocationListenerManager.getCurrentGpsLocation() + }) + } + val location = carLoc.get() + if (location != null) { + val angle = DrivingDirectionUtils.getDegreeOfCar2Poi2(location.longitude, location.latitude, marker.lon, marker.lat, location.bearing.toDouble()) + if (angle >= 90) { + iterator.remove() + synchronized(toRemoveMakers) { + toRemoveMakers.offer(marker) + } + } + } + } + } catch (t: Throwable) { + t.printStackTrace() + } finally { + lastCarLocation.set(CallerMapLocationListenerManager.getCurrentLocation()) + lastGpsLocation.set(CallerMapLocationListenerManager.getCurrentGpsLocation()) + handler.postDelayed(this, 1000) + } + } + } + + private val handler by lazy { + val thread = HandlerThread("check_marker_expired") + thread.start() + Handler(thread.looper) + } + + + fun addMarker(marker: MarkerWrapper) { + Log.d(TAG, "=== addMarker ====: $marker") + synchronized(showedMarkers) { + showedMarkers.offer(marker) + } + if (isFirstAdd.compareAndSet(false,true)) { + handler.postDelayed(checkTask, 1000) + } + } +} \ 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/events/scenario/impl/AbsV2XScenario.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/impl/AbsV2XScenario.java index cd72feafbd..88baed92e0 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/impl/AbsV2XScenario.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/impl/AbsV2XScenario.java @@ -7,6 +7,8 @@ import com.mogo.eagle.core.data.map.entity.V2XMessageEntity; import com.mogo.eagle.core.function.v2x.events.scenario.IV2XScenario; import com.mogo.eagle.core.function.v2x.events.scenario.view.IV2XMarker; +import java.util.concurrent.atomic.AtomicReference; + /** * author : donghongyu * e-mail : 1358506549@qq.com @@ -17,7 +19,7 @@ import com.mogo.eagle.core.function.v2x.events.scenario.view.IV2XMarker; public abstract class AbsV2XScenario implements IV2XScenario { protected String TAG = "AbsV2XScenario"; private IV2XMarker mV2XMarker; - private V2XMessageEntity mV2XMessageEntity; + private final AtomicReference mV2XMessageEntity = new AtomicReference<>(); protected AbsV2XScenario() { } @@ -26,14 +28,14 @@ public abstract class AbsV2XScenario implements IV2XScenario { @Override public void close() { - clearPOI(); +// clearPOI(); } /** * 释放资源 */ public void release() { - mV2XMessageEntity = null; + mV2XMessageEntity.set(null); mV2XMarker = null; } @@ -46,19 +48,19 @@ public abstract class AbsV2XScenario implements IV2XScenario { } public void setV2XMessageEntity(@Nullable V2XMessageEntity mV2XMessageEntity) { - this.mV2XMessageEntity = mV2XMessageEntity; + this.mV2XMessageEntity.set(mV2XMessageEntity); } public V2XMessageEntity getV2XMessageEntity() { - return mV2XMessageEntity; + return mV2XMessageEntity.get(); } @Override public boolean isSameScenario(@Nullable V2XMessageEntity v2XMessageEntity) { - if (mV2XMessageEntity == null) { + V2XMessageEntity old = mV2XMessageEntity.get(); + if (old == null) { return false; } - return mV2XMessageEntity.equals(v2XMessageEntity); + return old.equals(v2XMessageEntity); } - } diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/impl/V2XScenarioManager.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/impl/V2XScenarioManager.java index 148f2dfa0d..1928101ce5 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/impl/V2XScenarioManager.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/impl/V2XScenarioManager.java @@ -21,6 +21,8 @@ import com.mogo.eagle.core.utilcode.util.Utils; import com.mogo.map.uicontroller.IMogoMapUIController; import com.mogo.map.uicontroller.VisualAngleMode; +import java.util.concurrent.atomic.AtomicReference; + /** * author : donghongyu * e-mail : 1358506549@qq.com 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 1ba5daef53..b653876cc6 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 @@ -1,53 +1,42 @@ package com.mogo.eagle.core.function.v2x.events.scenario.scene.airoad import android.animation.ArgbEvaluator -import android.content.Context import android.graphics.Color import android.os.Handler import android.os.Looper import android.view.animation.DecelerateInterpolator import androidx.core.util.Pair -import androidx.lifecycle.Lifecycle.Event -import androidx.lifecycle.Lifecycle.Event.ON_CREATE -import androidx.lifecycle.Lifecycle.Event.ON_DESTROY -import androidx.lifecycle.LifecycleEventObserver -import androidx.lifecycle.LifecycleOwner +import com.mogo.cloud.commons.utils.* import com.mogo.commons.AbsMogoApplication -import com.mogo.eagle.core.data.map.MapRoadInfo.StopLine import com.mogo.eagle.core.data.map.MogoLatLng import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity -import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationWGS84Listener -import com.mogo.eagle.core.function.api.v2x.OnClearAllMarker -import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager -import com.mogo.eagle.core.function.call.map.CallerMapRoadListenerManager -import com.mogo.eagle.core.function.call.map.CallerMapRoadListenerManager.OnRoadListener -import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager -import com.mogo.eagle.core.function.call.v2x.CallMarkersClearManager -import com.mogo.eagle.core.function.v2x.events.consts.V2XConst.V2X_EVENT_ALARM_POI +import com.mogo.eagle.core.function.call.map.* import com.mogo.eagle.core.function.v2x.events.scenario.scene.road.V2XAiRoadEventMarker -import com.mogo.eagle.core.utilcode.kotlin.lifeCycleOwner import com.mogo.eagle.core.utilcode.mogo.logger.Logger import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils import com.mogo.map.MogoMap import com.mogo.map.overlay.IMogoPolyline import com.mogo.map.overlay.MogoPolylineOptions -import io.netty.util.internal.ConcurrentSet import mogo.telematics.pad.MessagePad import java.util.* import java.util.concurrent.Executors import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.atomic.AtomicReference +import java.util.concurrent.ConcurrentHashMap +import com.mogo.eagle.core.function.v2x.events.marker.MarkerManager +import com.mogo.eagle.core.function.v2x.events.marker.MarkerWrapper /** * Ai云道路施工事件,道路颜色标记类 */ -object AiRoadMarker { +class AiRoadMarker { - private const val TAG = "AiRoadMarker" + companion object { + @JvmField + val aiMakers = ConcurrentHashMap() + } - private val queue by lazy { LinkedBlockingQueue() } - - private val pool by lazy { Executors.newFixedThreadPool(2) } + private val TAG = "AiRoadMarker" private val marker by lazy { AtomicReference() } @@ -59,54 +48,28 @@ object AiRoadMarker { ) } - private val line by lazy { AtomicReference() } - private val START_COLOR = Color.parseColor("#002ABAD9") private val END_COLOR = Color.parseColor("#66FF7A30") + private val roadMarker by lazy { V2XAiRoadEventMarker() } + + private val line = AtomicReference() + private val handler by lazy { Handler(Looper.getMainLooper()) } private val checkExpiredTask = Runnable { val poi = this.marker.get() - val car = this.carLocation.get() + val car = CallerMapLocationListenerManager.getCurrentGpsLocation() if (poi != null && car != null) { - val distance = DrivingDirectionUtils.distance( - car.first, - car.second, - poi.poi_lon, - poi.poi_lat - ) * 10000 + val distance = CoordinateUtils.calculateLineDistance(car.longitude, car.latitude, poi.poi_lon, poi.poi_lat) if (distance < 500) { unMarker(poi) } } } - private val onClearAllMarker = object : OnClearAllMarker { - - override fun onClearAllMarkers() { - Logger.d(TAG, "--- onClearAllMarkers ----") - val marker = this@AiRoadMarker.marker.get() - if (marker != null) { - Logger.d(TAG, "--- onClearAllMarkers ----2") - unMarker(marker) - } - } - - override fun onClearAllMarkers(tag: String) { - Logger.d(TAG, "--- onClearAllMarkers ----: tag: $tag") - val marker = this@AiRoadMarker.marker.get() - if (marker != null && tag == V2X_EVENT_ALARM_POI) { - Logger.d(TAG, "--- onClearAllMarkers ----: tag: -- 1: $tag") - unMarker(marker) - } - } - } - - private val markers = ConcurrentSet() - private val options by lazy { MogoPolylineOptions().apply { zIndex(40000f) @@ -116,257 +79,83 @@ object AiRoadMarker { } } - 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() - 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 - } - } + fun marker(marker: Marker, drawMarker: Boolean, drawRoadLine: Boolean = false) { + val location = CallerMapLocationListenerManager.getCurrentGpsLocation() ?: return + this.marker.set(marker) + val wrapper = MarkerWrapper(marker.id, marker.poi_lon, marker.poi_lat, 1, null, null) + if (drawMarker) { + marker.entity?.apply { roadMarker.drawMarkers(this, wrapper) } } - } - - 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 { - 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 - } - } - this.roadId = roadId - } - - override fun onStopLineInfo(info: StopLine) { - Logger.d(TAG, "--- onStopLineInfo --- info: $info") - if (!hasCrossRoad) { - hasCrossRoad = true - } - } - } - - private val onLocationListener = object : IMoGoChassisLocationWGS84Listener { - - override fun onChassisLocationWGS84(gnssInfo: MessagePad.GnssInfo?) { - if (gnssInfo == null) { + if (drawRoadLine) { + //施工中心点前方的自车行驶方向上300米距离 + val l1 = MogoMap.getInstance().mogoMap.getCenterLineRangeInfo(marker.poi_lon, marker.poi_lat, location.bearing, 300f) + //施工中心点后方的自车行驶方向上300米距离 + Logger.d(TAG, "--- marker --- 3 --- l1: $l1") + val l2 = MogoMap.getInstance().mogoMap.getCenterLineRangeInfo(marker.poi_lon, marker.poi_lat, location.bearing, -300f) + if (l1.points.isEmpty() || l2.points.isEmpty()) { + Logger.d(TAG, "--- marker --- 3 --- return ----") return } - try { - val loc = arrayOf(gnssInfo.longitude, gnssInfo.latitude) - carLocation.set(Triple(loc[0], loc[1], gnssInfo.heading.toDouble())) - } catch (t: Throwable) { - Logger.e(TAG, "error: ${t.message}") + Logger.d(TAG, "--- marker --- 4 --- l2: $l2") + val points = LinkedList() + if (l2 != null && l2.points.isNotEmpty()) { + points.addAll(l2.points.reversed().map { + MogoLatLng(it.second, it.first) + }) } - } - } - - private fun onCreate() { - CallerMapRoadListenerManager.registerRoadListener(TAG, onRoadListener) - CallMarkersClearManager.addAllMarkersClearListener(TAG, onClearAllMarker) - CallerChassisLocationWGS84ListenerManager.addListener(TAG, onLocationListener) - } - - private fun onDestroy() { - CallerMapRoadListenerManager.unRegisterRoadListener(TAG) - CallMarkersClearManager.removeAllMarkersClearListener(TAG) - CallerChassisLocationWGS84ListenerManager.removeListener(TAG) - 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 - if (markers.contains(marker)) { - Logger.d(TAG, "--- enqueue --- cache hit ---") - return - } - synchronized(markers) { - markers += marker - } - this.marker.set(marker) - //施工中心点前方的自车行驶方向上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 - ) - if (l1.points.isEmpty() || l2.points.isEmpty()) { - Logger.d(TAG, "--- marker --- 3 --- return ----") - synchronized(markers) { - markers.remove(marker) - } - return - } - Logger.d(TAG, "--- marker --- 4 --- l2: $l2") - val points = LinkedList() - if (l2 != null && l2.points.isNotEmpty()) { - points.addAll(l2.points.reversed().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 = 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 + 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 = Pair(centerX, centerY) + var min = Long.MAX_VALUE + for (p in it) { + val angle = DrivingDirectionUtils.getDegreeOfCar2Poi2(centerX, centerY, p.first, p.second, location.bearing.toDouble()) + if (angle < min) { + min = angle + find = p + } + } + MogoLatLng(find.second, find.first) + } ?: 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.bearing + 180).toDouble()) < 90L) { + points.add(l.let { MogoLatLng(it.second, it.first) }) + } } } - MogoLatLng(find.second, find.first) - } ?: 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 + 180 - ) < 90L - ) { - points.add(l.let { MogoLatLng(it.second, it.first) }) - } + if (points.size <= 1) { + return + } + val evaluator = ArgbEvaluator() + val interceptor = DecelerateInterpolator(1.5f) + val total = points.size + val colors = ArrayList() + (0..total).forEach { i -> + colors += evaluator.evaluate(interceptor.getInterpolation(i * 1f / total), START_COLOR, END_COLOR) as Int + } + var line = line.get() + options.points(points) + options.colorValues(colors) + Logger.d(TAG, "--- marker --- 7 --- points: ${points.size}") + if (line == null || line.isDestroyed) { + val l = overlayManager?.addPolyline(options) + this.line.set(l) + line = l + } else { + line.setOption(options) + } + if (!line.isVisible) { + line.isVisible = true + } + if (line != null) { + wrapper.addLine(line) } } - if (points.size <= 1) { - synchronized(markers) { - markers.remove(marker) - } - return - } - removeLine() - if (drawMarker) { - marker.entity?.apply { V2XAiRoadEventMarker.drawMarkers(this) } - } - val evaluator = ArgbEvaluator() - val interceptor = DecelerateInterpolator(1.5f) - val total = points.size - val colors = ArrayList() - (0..total).forEach { i -> - colors += evaluator.evaluate( - interceptor.getInterpolation(i * 1f / total), - START_COLOR, - END_COLOR - ) as Int - } - var line = line.get() - options.points(points) - options.colorValues(colors) - Logger.d(TAG, "--- marker --- 7 --- points: ${points.size}") - if (line == null || line.isDestroyed) { - val l = overlayManager?.addPolyline(options) - this.line.set(l) - line = l - } else { - line.setOption(options) - } - if (!line.isVisible) { - line.isVisible = true - } + MarkerManager.addMarker(wrapper) } private fun removeLine() { @@ -380,30 +169,21 @@ object AiRoadMarker { } } - fun unMarker(marker: Marker) { + private fun unMarker(marker: Marker) { Logger.d(TAG, "--- unMarker ---") - markers -= marker this.marker.set(null) removeLine() - V2XAiRoadEventMarker.removeMarkers(null) + roadMarker.removeMarkers() handler.removeCallbacks(checkExpiredTask) } - fun receive(marker: Marker) { + fun receive() { Logger.d(TAG, "receive --- 1 ---") val poi = this.marker.get() - val car = this.carLocation.get() + val car = CallerMapLocationListenerManager.getCurrentGpsLocation() if (poi != null && car != null) { - val distance = DrivingDirectionUtils.distance( - car.first, - car.second, - marker.poi_lon, - marker.poi_lat - ) * 10000 - Logger.d( - TAG, - "receive --- 2 ---:car:[${car.first}, ${car.second}] -> poi:[${marker.poi_lon}, ${marker.poi_lat}] --> distance:$distance" - ) + val distance = CoordinateUtils.calculateLineDistance(car.longitude, car.latitude, poi.poi_lon, poi.poi_lat) + Logger.d(TAG, "receive --- 2 ---:car:[${car.longitude}, ${car.latitude}] -> poi:[${poi.poi_lon}, ${poi.poi_lat}] --> distance:$distance") if (distance < 500) { checkExpired() } else { @@ -422,10 +202,12 @@ object AiRoadMarker { } data class Marker( + val id: String, + val poiType: String, val poi_lat: Double, val poi_lon: Double, val poi_angle: Double, - val polygon: List>?, + val polygon: List>? = null, var farthestPoint: Pair? = null, var entity: V2XRoadEventEntity? = null ) { @@ -434,15 +216,12 @@ object AiRoadMarker { 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 + if (id != other.id) return false return true } override fun hashCode(): Int { - var result = poi_lat.hashCode() - result = 31 * result + poi_lon.hashCode() - return result + return id.hashCode() } } } \ 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/events/scenario/scene/road/V2XAiRoadEventMarker.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XAiRoadEventMarker.kt index 706abccbb8..563aada462 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XAiRoadEventMarker.kt +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XAiRoadEventMarker.kt @@ -1,127 +1,88 @@ package com.mogo.eagle.core.function.v2x.events.scenario.scene.road import android.graphics.* -import android.util.* -import com.mogo.cloud.commons.utils.* -import com.mogo.commons.AbsMogoApplication +import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.data.map.* import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity -import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager -import com.mogo.eagle.core.function.v2x.R import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi.context import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi.v2xMarker -import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils +import com.mogo.eagle.core.function.v2x.events.marker.MarkerWrapper import com.mogo.map.* import com.mogo.map.marker.* import com.mogo.map.overlay.* -import java.util.* import java.util.concurrent.atomic.* import kotlin.Pair import kotlin.collections.ArrayList -object V2XAiRoadEventMarker { +class V2XAiRoadEventMarker { private val current = AtomicReference?>>() private val v2xLocation = AtomicReference() - private val carLocation = AtomicReference() + private val overlayManager by lazy { MogoOverlayManager.getInstance() } - private val timer = Timer() - - private val timerTask by lazy { AtomicReference() } - - private val distance = AtomicInteger(0) - - private val overlayManager by lazy { CallerMapUIServiceManager.getOverlayManager(AbsMogoApplication.getApp()) } - - fun drawMarkers(entity: V2XRoadEventEntity): Pair?>? { - removeMarkers(current.get()) - timerTask.get()?.cancel() - val extra = entity.noveltyInfo.extras.get("polygon"); - if (extra is List<*>) { - val l = extra - if (l.size > 0) { + fun drawMarkers(entity: V2XRoadEventEntity, wrapper: MarkerWrapper) { + val extra = entity.noveltyInfo.extras["polygon"] + v2xMarker()?.drawableAlarmPOI(context(), entity, null)?.also { + wrapper.addMarker(it) + } + if (extra is List<*> && entity.poiType != EventTypeEnumNew.TYPE_SOCKET_ROAD_JINGZHI.poiType) { + if (extra.size > 0) { val polygons: MutableList> = ArrayList() - for (i in l.indices) { - val o = l[i]!! as? androidx.core.util.Pair<*, *> ?: continue - val p = o - val first = p.first - val second = p.second + for (i in extra.indices) { + val o = extra[i]!! as? androidx.core.util.Pair<*, *> ?: continue + val first = o.first + val second = o.second if (first == null || second == null) { continue } if (first !is Double || second !is Double) { continue } - val xx = CoordinateUtils.transformWgsToGcj(second, first) - polygons.add(androidx.core.util.Pair.create(xx[0], xx[1])) + polygons.add(androidx.core.util.Pair.create(second, first)) } if (polygons.size > 0) { - val markers = ArrayList(polygons.size) - for (i in polygons.indices) { - val p = polygons[i] - val options = MogoMarkerOptions().data(entity).latitude(p.second).longitude(p.first) - options.anchor(0.5f, 0.5f) - options.icon3DRes(R.raw.sanjiaozhui) - try { - val marker = CallerMapUIServiceManager.getMarkerManager(AbsMogoApplication.getApp())?.addMarker("road_pyramid_" + entity.poiType, options) - marker?.let { - markers += it - } - } catch (t: Throwable) { - t.printStackTrace() - } + val l2 = entity.noveltyInfo?.location ?: return + v2xLocation.set(MogoLocation().also { + it.longitude = l2.lon; it.latitude = l2.lat; it.bearing = l2.angle.toFloat() + }) + + val options = MogoPolylineOptions() + val colors = ArrayList() + colors.add(Color.argb(204, 237, 172, 21)) + colors.add(Color.argb(0, 255, 255, 255)) + options.colorValues(colors) + val points = ArrayList() + + for (p in polygons) { + points.add(MogoLatLng(p.first, p.second)) } - if (markers.size > 0) { - v2xMarker()?.drawableAlarmPOI(context(), entity, null) - val l2 = entity.noveltyInfo?.location ?: return null - v2xLocation.set(MogoLocation().also { it.longitude = l2.lon; it.latitude = l2.lat; it.bearing = l2.angle.toFloat() }) - - val options = MogoPolylineOptions() - val colors = ArrayList() - colors.add(Color.argb(204, 237, 172, 21)) - colors.add(Color.argb(0, 255, 255, 255)) - options.colorValues(colors) - val points = ArrayList() - - for (p in polygons) { - points.add(MogoLatLng(p.second, p.first)) - } - if (points.size > 2) { - points.add(points[0]) - } - options.points(points) - options.useGradient(true) - options.useFacade(true) - options.setGps(false) - options.width(5f) - options.zIndex(75000f) - options.maxIndex(800000f) - val line = overlayManager?.addPolyline(options) - current.set(Pair(line, markers)) - if (line != null) { - line.isVisible = true - } + if (points.size > 2) { + points.add(points[0]) + } + options.points(points) + options.useGradient(true) + options.useFacade(true) + options.setGps(true) + options.width(5f) + options.zIndex(75000f) + options.maxIndex(800000f) + val line = overlayManager.addPolyline(options) + current.set(Pair(line, wrapper.markers)) + if (line != null) { + line.isVisible = true + wrapper.addLine(line) } } } } - return current.get() } - fun removeMarkers(pair: Pair?>?) { - if (pair != null) { - realRemove(pair) - } else { - val prev = current.get() - if (prev != null) { - realRemove(prev) - val v2xMarker = v2xMarker() - v2xMarker?.also { - it.forceClearAlarmPOI() - } - } + fun removeMarkers() { + val prev = current.get() + if (prev != null) { + realRemove(prev) } } @@ -137,40 +98,4 @@ object V2XAiRoadEventMarker { } } } - - fun onLocationChanged(location: MogoLocation) { - val markerLocation = v2xLocation.get() - carLocation.set(location) - if (markerLocation != null) { - if (isOutOfRange(markerLocation.longitude, markerLocation.latitude, location.longitude, location.latitude, location.bearing.toDouble())) { - v2xLocation.set(null) - this.distance.set(0) - timer.schedule(object : TimerTask() { - override fun run() { - val carLocation = this@V2XAiRoadEventMarker.carLocation.get() - Log.d("XXXXX", "timer do action ---: marker_lon: ${markerLocation.longitude}, marker_lat: ${markerLocation.latitude}, car_lon:${carLocation.longitude}, car_lat: ${carLocation.latitude}") - checkDistanceIsValid(markerLocation.longitude, markerLocation.latitude, carLocation) - } - }.also { this.timerTask.set(it) }, 1000, 1000) - } - } - } - private fun checkDistanceIsValid(x1: Double, y1: Double, location: MogoLocation) { - val distance = DrivingDirectionUtils.distance(x1, y1, location.longitude, location.latitude) - Log.d("XXXXX", "distance: $distance") - if (this.distance.addAndGet(distance.toInt()) >= 100) { - Log.d("XXXXX", "remove marker") - removeMarkers(null) - this.timerTask.get()?.cancel() - } - } - - 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 - } } \ 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/events/scenario/scene/road/V2XRoadEventMarker.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventMarker.java index 7b0637ba7e..4de55a0c84 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventMarker.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventMarker.java @@ -1,16 +1,20 @@ package com.mogo.eagle.core.function.v2x.events.scenario.scene.road; +import android.util.Log; + import androidx.core.util.Pair; +import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import com.mogo.eagle.core.data.map.entity.MarkerExploreWay; import com.mogo.eagle.core.data.map.entity.MarkerLocation; import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity; import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi; import com.mogo.eagle.core.function.v2x.events.manager.IMoGoV2XMarkerManager; -import com.mogo.eagle.core.function.v2x.events.manager.IMoGoV2XPolylineManager; +import com.mogo.eagle.core.function.v2x.events.marker.MarkerWrapper; +import com.mogo.eagle.core.function.v2x.events.marker.MarkerManager; import com.mogo.eagle.core.function.v2x.events.scenario.scene.airoad.AiRoadMarker; import com.mogo.eagle.core.function.v2x.events.scenario.view.IV2XMarker; -import com.mogo.eagle.core.data.enums.EventTypeEnum; +import com.mogo.map.marker.IMogoMarker; import java.util.ArrayList; import java.util.List; @@ -22,30 +26,31 @@ import java.util.Objects; public class V2XRoadEventMarker implements IV2XMarker { - private static AiRoadMarker.Marker mMarker; - @Override public void drawPOI(V2XRoadEventEntity entity) { try { // 清除道路事件 IMoGoV2XMarkerManager marker = BridgeApi.INSTANCE.v2xMarker(); if (marker != null) { - marker.clearAlarmPOI(); if (entity != null) { - if (!Objects.equals(entity.getPoiType(), EventTypeEnum.AI_ROAD_WORK.getPoiType())) { - AiRoadMarker.Marker prev = mMarker; - if (prev != null) { - AiRoadMarker.INSTANCE.unMarker(prev); - mMarker = null; + Log.d("RWJ", "V2XRoadEventMarker:" + entity.getPoiType()); + if (!Objects.equals(entity.getPoiType(), EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGONG.getPoiType()) + && !Objects.equals(entity.getPoiType(), EventTypeEnumNew.FOURS_ACCIDENT_04.getPoiType()) + && !Objects.equals(entity.getPoiType(), EventTypeEnumNew.TYPE_SOCKET_ROAD_JINGZHI.getPoiType()) + && !Objects.equals(entity.getPoiType(), EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGU.getPoiType())) { + IMogoMarker iMarker = marker.drawableAlarmPOI(BridgeApi.INSTANCE.context(), entity, null); + if (iMarker != null) { + Log.d("RWJ", "V2XRoadEventMarker:" + entity.getPoiType() + "--- add Marker"); + ArrayList markers = new ArrayList<>(); + markers.add(iMarker); + String id = entity.getLocation().getLon() + "_" + entity.getLocation().getLat(); + MarkerManager.INSTANCE.addMarker(new MarkerWrapper(id, entity.getLocation().getLon(), entity.getLocation().getLat(), 0, markers, null)); + } else { + Log.d("RWJ", "V2XRoadEventMarker:" + entity.getPoiType() + "--- return empty marker"); } - marker.drawableAlarmPOI(BridgeApi.INSTANCE.context(), entity, null); } else { - AiRoadMarker.Marker prev = mMarker; - if (prev != null) { - AiRoadMarker.INSTANCE.unMarker(prev); - mMarker = null; - } MarkerExploreWay noveltyInfo = entity.getNoveltyInfo(); + Log.d("RWJ", "V2XRoadEventMarker -> noveltyInfo:" + noveltyInfo); if (noveltyInfo != null && noveltyInfo.extras != null) { List> polygons = new ArrayList<>(); Pair gpsLocation = null; @@ -77,14 +82,13 @@ public class V2XRoadEventMarker implements IV2XMarker { if (noveltyInfo.extras.containsKey("gps_location")) { gpsLocation = (Pair) ((List)(noveltyInfo.extras.get("gps_location"))).get(0); } - if (!polygons.isEmpty() && gpsLocation != null) { MarkerLocation location = noveltyInfo.getLocation(); - AiRoadMarker.Marker m = new AiRoadMarker.Marker(gpsLocation.second, gpsLocation.first, location.getAngle(), polygons, null, entity); - mMarker = m; - AiRoadMarker.INSTANCE.marker(m, true); + AiRoadMarker.Marker m = new AiRoadMarker.Marker(noveltyInfo.getInfoId(), noveltyInfo.getPoiType(), gpsLocation.second, gpsLocation.first, location.getAngle(), polygons, null, entity); + AiRoadMarker aiMarker = new AiRoadMarker(); + aiMarker.marker(m, true, isDrawRoadLine(m.getPoiType())); + AiRoadMarker.aiMakers.put(noveltyInfo.getInfoId(), aiMarker); } - } } } @@ -94,19 +98,23 @@ public class V2XRoadEventMarker implements IV2XMarker { } } + private boolean isDrawRoadLine(String poiType) { + return EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGONG.getPoiType().equals(poiType); + } + @Override public void clearPOI() { // 移除线 - IMoGoV2XPolylineManager polyLineManager = BridgeApi.INSTANCE.v2xPolyline(); - if (polyLineManager != null) { - polyLineManager.clearLine(); - } - IMoGoV2XMarkerManager v2xMarker = BridgeApi.INSTANCE.v2xMarker(); - if (v2xMarker != null) { - // 移除事件POI - v2xMarker.clearAlarmPOI(); - // 绘制上次的数据 - v2xMarker.drawableLastAllPOI(); - } +// IMoGoV2XPolylineManager polyLineManager = BridgeApi.INSTANCE.v2xPolyline(); +// if (polyLineManager != null) { +// polyLineManager.clearLine(); +// } +// IMoGoV2XMarkerManager v2xMarker = BridgeApi.INSTANCE.v2xMarker(); +// if (v2xMarker != null) { +// // 移除事件POI +// v2xMarker.clearAlarmPOI(); +// // 绘制上次的数据 +// v2xMarker.drawableLastAllPOI(); +// } } } diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventScenario.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventScenario.java index cf448413a1..5441044185 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventScenario.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventScenario.java @@ -1,12 +1,16 @@ package com.mogo.eagle.core.function.v2x.events.scenario.scene.road; -import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_V2X; + import android.util.Log; +import com.mogo.cloud.commons.utils.CoordinateUtils; import com.mogo.commons.analytics.AnalyticsUtils; +import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import com.mogo.eagle.core.data.enums.WarningDirectionEnum; +import com.mogo.eagle.core.data.map.MogoLocation; import com.mogo.eagle.core.data.map.entity.MarkerExploreWay; +import com.mogo.eagle.core.data.map.entity.MarkerLocation; import com.mogo.eagle.core.data.map.entity.V2XMessageEntity; import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity; import com.mogo.eagle.core.data.msgbox.MsgBoxBean; @@ -14,6 +18,7 @@ import com.mogo.eagle.core.data.msgbox.MsgBoxType; import com.mogo.eagle.core.data.msgbox.V2XMsg; import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener; import com.mogo.eagle.core.function.call.hmi.CallerHmiManager; +import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager; import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager; import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager; import com.mogo.eagle.core.function.v2x.events.consts.V2XConst; @@ -21,13 +26,13 @@ import com.mogo.eagle.core.function.v2x.events.manager.V2XStatusManager; 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.eagle.core.network.utils.GsonUtil; -import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; -import com.mogo.eagle.core.data.enums.EventTypeEnum; - import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.concurrent.TimeUnit; + + /** * author : donghongyu * e-mail : 1358506549@qq.com @@ -45,7 +50,7 @@ public class V2XRoadEventScenario extends AbsV2XScenario imp @Override public void init(V2XMessageEntity v2XMessageEntity) { try { - CallerLogger.INSTANCE.d(M_V2X + TAG, "v2XMessageEntity:" + GsonUtil.jsonFromObject(v2XMessageEntity)); + Log.d(TAG, "v2XMessageEntity:" + GsonUtil.jsonFromObject(v2XMessageEntity)); V2XRoadEventEntity v2XRoadEventEntity = v2XMessageEntity.getContent(); if (v2XRoadEventEntity != null) { if (v2XMessageEntity.isShowState()) { @@ -71,16 +76,23 @@ public class V2XRoadEventScenario extends AbsV2XScenario imp try { if (getV2XMessageEntity() != null && getV2XMessageEntity().getContent() != null) { //只展示不播报 不广播 - boolean onlyShow = getV2XMessageEntity().isOnlyShow(); + V2XMessageEntity entity = getV2XMessageEntity(); + boolean onlyShow = entity.isOnlyShow(); if (!onlyShow) { // 设置TTS - getV2XMessageEntity().getContent().getTts(false); + V2XRoadEventEntity content = entity.getContent(); + if (content != null && !Objects.equals(content.getPoiType(), EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGONG.getPoiType()) + && !Objects.equals(content.getPoiType(), EventTypeEnumNew.TYPE_SOCKET_ROAD_JINGZHI.getPoiType()) + && !Objects.equals(content.getPoiType(), EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGU.getPoiType()) + && !Objects.equals(content.getPoiType(), EventTypeEnumNew.TYPE_SOCKET_ROAD_CONGESTION.getPoiType())) { + content.getTts(false); + } } showWindow(); - String poiType = getV2XMessageEntity().getContent().getPoiType(); - String lat = String.valueOf(getV2XMessageEntity().getContent().getLocation().getLat()); - String lon = String.valueOf(getV2XMessageEntity().getContent().getLocation().getLon()); - String infoId = getV2XMessageEntity().getContent().getNoveltyInfo().getInfoId(); + String poiType = entity.getContent().getPoiType(); + String lat = String.valueOf(entity.getContent().getLocation().getLat()); + String lon = String.valueOf(entity.getContent().getLocation().getLon()); + String infoId = entity.getContent().getNoveltyInfo().getInfoId(); String style = "1"; Map properties = new HashMap<>(); properties.put("dbid", infoId); @@ -100,20 +112,39 @@ public class V2XRoadEventScenario extends AbsV2XScenario imp V2XRoadEventEntity content = entity != null ? entity.getContent() : null; if (content != null) { // //显示警告红边 - if (content.getAlarmContent() == null || content.getAlarmContent().isEmpty() - || content.getTts() == null || content.getTts().isEmpty()) { + String alarmText = content.getAlarmContent(); + String ttsText = content.getTts(); + if (alarmText == null || alarmText.isEmpty() + || ttsText == null || ttsText.isEmpty()) { Log.d("MsgBox-V2XRoadScenario", "alertContent或ttsContent为空!"); } + String poiType = content.getPoiType(); + if (EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGONG.getPoiType().equals(poiType) || + EventTypeEnumNew. TYPE_SOCKET_ROAD_JINGZHI.getPoiType().equals(poiType) || + EventTypeEnumNew.TYPE_SOCKET_ROAD_CONGESTION.getPoiType().equals(poiType) || + EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGU.getPoiType().equals(poiType)) { + MogoLocation carLocation = CallerMapLocationListenerManager.INSTANCE.getCurrentLocation(); + MarkerExploreWay noveltyInfo = content.getNoveltyInfo(); + if (carLocation != null && noveltyInfo != null) { + MarkerLocation eventLocation = noveltyInfo.getLocation(); + if (eventLocation != null) { + double distance = content.getDistance(); + alarmText = String.format(alarmText, Math.round(distance) + ""); + ttsText = String.format(ttsText, Math.round(distance) + ""); + } + } + } + CallerMsgBoxManager.INSTANCE.saveMsgBox( new MsgBoxBean( MsgBoxType.V2X, - new V2XMsg(content.getPoiType(), - content.getAlarmContent(), - content.getTts()) + new V2XMsg(poiType, + alarmText, + ttsText) ) ); - CallerHmiManager.INSTANCE.warningV2X(content.getPoiType(), content.getAlarmContent(), - content.getTts(), TAG, this, !entity.isOnlyShow(), + CallerHmiManager.INSTANCE.warningV2X(poiType, alarmText, + ttsText, TAG, this, !entity.isOnlyShow(), TimeUnit.SECONDS.toMillis(5)); } } @@ -130,10 +161,10 @@ public class V2XRoadEventScenario extends AbsV2XScenario imp @Override public void clearPOI() { - IV2XMarker marker = getV2XMarker(); - if (marker != null) { - marker.clearPOI(); - } +// IV2XMarker marker = getV2XMarker(); +// if (marker != null) { +// marker.clearPOI(); +// } } @Override @@ -144,13 +175,14 @@ public class V2XRoadEventScenario extends AbsV2XScenario imp CallerHmiManager.INSTANCE.showWarning(WarningDirectionEnum.ALERT_WARNING_TOP, TimeUnit.HOURS.toMillis(1)); V2XMessageEntity entity = getV2XMessageEntity(); if (entity != null) { - if (entity.isNeedAddLine()) { - drawPOI(); - } + V2XRoadEventEntity content = entity.getContent(); if (content != null) { + if (entity.isNeedAddLine() && !EventTypeEnumNew.TYPE_SOCKET_ROAD_CONGESTION.getPoiType().equals(content.getPoiType()) ) { + drawPOI(); + } MarkerExploreWay noveltyInfo = content.getNoveltyInfo(); - if (noveltyInfo != null && EventTypeEnum.FOURS_FOG.getPoiType().equals(content.getNoveltyInfo().getPoiType())) { + if (noveltyInfo != null && EventTypeEnumNew.FOURS_FOG.getPoiType().equals(content.getNoveltyInfo().getPoiType())) { CallerHmiManager.INSTANCE.displayEffects(); } } @@ -163,7 +195,7 @@ public class V2XRoadEventScenario extends AbsV2XScenario imp if (content == null) { return true; } - return !EventTypeEnum.GHOST_PROBE.getPoiType().equals(content.getPoiType()); + return !EventTypeEnumNew.GHOST_PROBE.getPoiType().equals(content.getPoiType()); } @Override @@ -172,7 +204,6 @@ public class V2XRoadEventScenario extends AbsV2XScenario imp if (isNeedChangeAngle()) { CallerVisualAngleManager.INSTANCE.changeVisualAngle(new CallerVisualAngleManager.Scene.Default(3, TimeUnit.SECONDS)); } - clearPOI(); release(); } } diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/route/V2XOptimalRouteVREventMarker.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/route/V2XOptimalRouteVREventMarker.java index daac6e2b91..e2e6c77c1f 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/route/V2XOptimalRouteVREventMarker.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/route/V2XOptimalRouteVREventMarker.java @@ -39,13 +39,13 @@ public class V2XOptimalRouteVREventMarker implements IV2XMarker? = null): MarkerExploreWay = MarkerExploreWay().also { - it.items = this.items?.map { itx -> itx.toMarkerExploreWayItem() } - it.userInfo = this.userInfo?.toMarkerUserInfo() - it.distance = this.distance - it.cityName = this.cityName - it.setGenerateTime(this.generateTime) - it.infoId = this.infoId - it.setFileType(this.fileType) - it.setDirection(this.direction) - it.location = this.location?.toMarkerLocation() - it.sn = this.sn - it.canLive = this.canLive != "0" - it.poiType = this.poiType - it.type = this.type - it.infoCheckNode = this.infoCheckNode - it.isFabulous = this.isFabulous - it.uploadType = this.uploadType - it.isCanLive = this.canLive != "0" - it.extras = extras -} \ No newline at end of file +fun V2XMarkerExploreWay.toMarkExploreWay(extras: Map? = null): MarkerExploreWay = + MarkerExploreWay().also { + it.items = this.items?.map { itx -> itx.toMarkerExploreWayItem() } + it.userInfo = this.userInfo?.toMarkerUserInfo() + it.distance = this.distance + it.cityName = this.cityName + it.setGenerateTime(this.generateTime) + it.infoId = this.infoId + it.setFileType(this.fileType) + it.setDirection(this.direction) + it.location = this.location?.toMarkerLocation() + it.sn = this.sn + it.canLive = this.canLive != "0" + it.poiType = this.poiType + it.type = this.type + it.infoCheckNode = this.infoCheckNode + it.isFabulous = this.isFabulous + it.uploadType = this.uploadType + it.isCanLive = this.canLive != "0" + it.extras = extras + } + +fun Road.RW_PB.toRoadMarker(): V2XMarkerCardResult = + V2XMarkerCardResult().also { l1 -> + this.roadwork?.polygonList?.takeIf { it.isNotEmpty() }?.also { old -> + l1.extras = HashMap>>().also { extra -> + extra["polygon"] = old.map { d -> + Pair(d.lon, d.lat) + } + + extra["gps_location"] = listOf( + Pair( + this.roadwork?.center?.point?.lon ?: 0.0, + this.roadwork?.center?.point?.lat ?: 0.0 + ) + ) + } + } + val centerX = this.roadwork?.center?.point?.lon ?: 0.0 + val centerY = this.roadwork?.center?.point?.lat ?: 0.0 + val id = "${centerX}_${centerY}" + l1.exploreWay = ArrayList().also { l2 -> + l2.add(V2XMarkerExploreWay().also { l3 -> + l3.poiType = this.roadwork?.poiType?.toString() + l3.generateTime = this.roadwork?.detectTime ?: 0L + l3.location = V2XMarkerLocation().also { l4 -> + /* + TODO zhongchao 先注掉,编译通过 + val p = MogoMap.getInstance().mogoMap.switchLonLat( + this.roadwork?.center?.point?.lon ?: 0.0, + this.roadwork?.center?.point?.lat ?: 0.0 + ) + l4.lon = p.lon + l4.lat = p.lat + l4.angle = this.roadwork?.center?.road?.bearing?.toDouble() ?: 0.0*/ + } + l3.infoId = id + }) + } + AiRoadMarker.aiMakers[id]?.receive() + } + +fun V2XRoadXData.toRoadMarker(): V2XMarkerCardResult = + V2XMarkerCardResult().also { l1 -> + this.polygon?.takeIf { it.isNotEmpty() }?.also { old -> + l1.extras = HashMap>>().also { extra -> + extra["polygon"] = old.map { d -> + Pair(d.lon, d.lat) + } + extra["gps_location"] = listOf(Pair(this.center?.lon ?: 0.0, this.center?.lat ?: 0.0)) + } + } + + l1.exploreWay = ArrayList().also { l2 -> + l2.add(V2XMarkerExploreWay().also { l3 -> + l3.poiType = this.poiType + l3.generateTime = this.detectTime ?: 0L + l3.location = V2XMarkerLocation().also { l4 -> + /* + TODO zhongchao 先注掉,编译通过 + val p = MogoMap.getInstance().mogoMap.switchLonLat( + this.center?.lon ?: 0.0, + this.center?.lat ?: 0.0 + ) + l4.lon = p.lon + l4.lat = p.lat + l4.angle = this.centerRoad?.bearing ?: 0.0*/ + } + l3.infoId = this.index + }) + } + + AiRoadMarker.aiMakers[this.index]?.receive() + } + +fun MessagePad.TrackedObject.toRoadMarker(poiType: String): V2XMarkerCardResult = + V2XMarkerCardResult().also { l1 -> + this.polygonList?.takeIf { it.isNotEmpty() }?.also { old -> + l1.extras = HashMap>>().also { extra -> + extra["polygon"] = old.map { d -> Pair(d.longitude, d.latitude) } + extra["gps_location"] = listOf(Pair(this.longitude, this.latitude)) + } + } + val id = "${this.longitude}_${this.latitude}" + l1.exploreWay = ArrayList().also { l2 -> + l2.add(V2XMarkerExploreWay().also { l3 -> + l3.poiType = poiType + l3.generateTime = 0L + l3.location = V2XMarkerLocation().also { l4 -> + /* + TODO zhongchao 先注掉,编译通过 + val p = + MogoMap.getInstance().mogoMap.switchLonLat(this.longitude, this.latitude) + l4.lon = p.lon + l4.lat = p.lat + l4.angle = this.heading*/ + } + l3.infoId = id + }) + } + AiRoadMarker.aiMakers[id]?.receive() + } + +fun V2XMarkerCardResult.toV2XRoadEventEntity(): V2XRoadEventEntity = + V2XRoadEventEntity().also { l1 -> + val exploreWayList: List? = this.exploreWay + if (!exploreWayList.isNullOrEmpty() && exploreWayList.isNotEmpty()) { + for (markerExploreWay in exploreWayList) { + if (isRoadEvent(markerExploreWay.poiType)) { + val markerLocation = markerExploreWay.location + l1.location = markerLocation.toMarkerLocation() + l1.poiType = markerExploreWay.poiType + l1.noveltyInfo = markerExploreWay.toMarkExploreWay(this.extras) + l1.expireTime = 20000 + } + } + } + } 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..8622fd1f21 --- /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,257 @@ +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.* +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.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)) + SocketManager.getInstance().registerOnMessageListener(70001, V2XMessageListener_70001(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/V2XRoadXEvent.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XRoadXEvent.kt new file mode 100644 index 0000000000..a692c2dfa7 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/data/V2XRoadXEvent.kt @@ -0,0 +1,59 @@ +package com.mogo.eagle.core.function.v2x.internal.data + +import androidx.annotation.Keep + + +@Keep +data class V2XRoadXData( + val poiType: String? = null, + val center: Point? = null, + val centerRoad: CenterRoad? = null, + val congestionLanes: List? = null, + val coordinateType: Int? = -1, + val id: String? = null, + val index: String? = null, + val obstacles: List? = null, + val polygon: List? = null, + val type: Int? = 0, + val detectTime: Long? = 0L, + val crossId: String? = null +) + +@Keep +data class CenterRoad( + val bearing: Double? = 0.0, + val laneNo: Int? = null, + val roadId: String? = null, + val roadName: String? = null, + val tileId: Int? = 0, + val heading: String? = null +) + +@Keep +data class Congestion( + val laneId: Int? = null, + val level: Int? = null +) + +@Keep +data class Obstacle( + val boundBox: List? = null, + val center: Point? = null, + val id: Int? = null, + val polygon: List? = null, + val score: Double? = null, + val type: Int? = null +) + + +@Keep +data class Point( + val lon: Double? = null, + val lat: Double? = null +) + +@Keep +data class PointX( + val x: Double? = null, + val y: Double? = 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/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..40bf0b65c4 --- /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,75 @@ +package com.mogo.eagle.core.function.v2x.internal.event + +import com.mogo.eagle.core.function.v2x.internal.data.* +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)" + } + } + + + /** + * 长链-道路事件扩展数据结构 + */ + class RoadEventX(val type: Int = 70001, val data: V2XRoadXData): V2XEvent() { + + override fun toString(): String { + return "RoadEventX(type=$type, 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/socket/V2XMessageListener_70001.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_70001.kt new file mode 100644 index 0000000000..cb1b9be044 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/internal/socket/V2XMessageListener_70001.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.V2XRoadXData +import com.mogo.eagle.core.function.v2x.internal.event.V2XEvent +import com.mogo.eagle.core.function.v2x.internal.logger.Logger + +internal class V2XMessageListener_70001(val cbs: Iterable?): IMogoCloudSocketOnMessageListener { + + override fun target(msgType: Int): Class = V2XRoadXData::class.java + + override fun onMsgReceived(msgType: Int, data: V2XRoadXData?) { + if (msgType != 70001) { + return + } + if (data == null) { + Logger.i(V2XManager.TAG, "V2XMessageListener_70001:message is null!") + return + } + Logger.i(V2XManager.TAG, "V2XMessageListener_70001:$data") + cbs?.forEach { + it.onAck(V2XEvent.RoadEventX(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/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/CloudPoiManager.java b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/CloudPoiManager.java index 540ffc7574..7bb1b06c72 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/CloudPoiManager.java +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/CloudPoiManager.java @@ -7,6 +7,7 @@ import android.util.ArrayMap; import com.elegant.network.utils.GsonUtil; import com.mogo.eagle.core.data.R; import com.mogo.eagle.core.data.enums.EventTypeEnum; +import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import com.mogo.eagle.core.data.map.PoiWrapper; import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr; @@ -44,7 +45,7 @@ public class CloudPoiManager { R.drawable.module_common_icon_map_marker_road_block_off2, R.drawable.module_common_icon_map_marker_road_block_off2_white, "封路")); poiWrapper.put(EventTypeEnum.FOURS_ROAD_WORK.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_ROAD_WORK.getPoiType(), R.drawable.module_common_icon_map_marker_road_work2, R.drawable.module_common_icon_map_marker_road_work2_white, "施工")); - poiWrapper.put(EventTypeEnum.AI_ROAD_WORK.getPoiType(), new PoiWrapper(EventTypeEnum.AI_ROAD_WORK.getPoiType(), + poiWrapper.put(EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGONG.getPoiType(), new PoiWrapper(EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGONG.getPoiType(), R.drawable.module_common_icon_map_marker_road_work2, R.drawable.module_common_icon_map_marker_road_work2_white, "施工")); poiWrapper.put(EventTypeEnum.FOURS_BLOCK_UP.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_BLOCK_UP.getPoiType(), R.drawable.module_common_icon_map_marker_road_block_up2, R.drawable.module_common_icon_map_marker_road_block_up2_white, "拥堵")); diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt index cf1d029c1f..7d7aa487b5 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt @@ -33,12 +33,6 @@ enum class EventTypeEnumNew( "注意施工占道", "注意施工占道" ), - //施工-AI云下发 - AI_ROAD_WORK( - "100061", "道路施工", "前方施工", R.drawable.icon_warning_v2x_road_construction, - "前方施工", "道路施工" - ), - //拥堵 FOURS_BLOCK_UP( "10007", "道路拥堵", "前方拥堵", R.drawable.icon_warning_v2x_congestion, @@ -478,6 +472,38 @@ enum class EventTypeEnumNew( //------------车内标牌 end --------------> + TYPE_SOCKET_ROAD_CONGESTION( + "100071", + "交通拥堵", + poiTypeSrcVr = R.drawable.v2x_icon_yongdu_vr, + content = "前方%s米交通拥堵", + tts = "前方%s米交通拥堵" + ), + + TYPE_SOCKET_ROAD_JINGZHI( + "100251", + "前方%s米静止障碍物占道", + poiTypeSrcVr = R.drawable.v2x_icon_jingzhi_zhangai, + content = "前方%s米静止障碍物占道", + tts = "前方%s米静止障碍物占道" + ), + + TYPE_SOCKET_ROAD_SHIGU( + "100321", + "前方%s米道路事故", + poiTypeSrcVr = R.drawable.v2x_icon_shigu_sanjiaopai, + content = "前方%s米道路事故", + tts = "前方%s米道路事故" + ), + + TYPE_SOCKET_ROAD_SHIGONG( + "100061", + "前方%s米道路施工", + poiTypeSrcVr = R.drawable.v2x_icon_shigong_zhandao, + content = "前方%s米道路施工", + tts = "前方%s米道路施工" + ), + TYPE_ERROR( 0.toString(), "未知/错误/异常", @@ -503,7 +529,6 @@ enum class EventTypeEnumNew( TRAFFIC_CHECK.poiType -> TRAFFIC_CHECK.poiTypeStr ROAD_CLOSED.poiType -> ROAD_CLOSED.poiTypeStr FOURS_ROAD_WORK.poiType -> FOURS_ROAD_WORK.poiTypeStr - AI_ROAD_WORK.poiType -> AI_ROAD_WORK.poiTypeStr FOURS_BLOCK_UP.poiType -> FOURS_BLOCK_UP.poiTypeStr FOURS_PONDING.poiType -> FOURS_PONDING.poiTypeStr FOURS_FOG.poiType -> FOURS_FOG.poiTypeStr @@ -525,7 +550,6 @@ enum class EventTypeEnumNew( TRAFFIC_CHECK.poiType -> TRAFFIC_CHECK.poiTypeStrVr ROAD_CLOSED.poiType -> ROAD_CLOSED.poiTypeStrVr FOURS_ROAD_WORK.poiType -> FOURS_ROAD_WORK.poiTypeStrVr - AI_ROAD_WORK.poiType -> AI_ROAD_WORK.poiTypeStrVr FOURS_BLOCK_UP.poiType -> FOURS_BLOCK_UP.poiTypeStrVr FOURS_PONDING.poiType -> FOURS_PONDING.poiTypeStrVr FOURS_FOG.poiType -> FOURS_FOG.poiTypeStrVr @@ -547,7 +571,6 @@ enum class EventTypeEnumNew( TRAFFIC_CHECK.poiType -> TRAFFIC_CHECK.poiTypeSrcVr ROAD_CLOSED.poiType -> ROAD_CLOSED.poiTypeSrcVr FOURS_ROAD_WORK.poiType -> FOURS_ROAD_WORK.poiTypeSrcVr - AI_ROAD_WORK.poiType -> AI_ROAD_WORK.poiTypeSrcVr FOURS_BLOCK_UP.poiType -> FOURS_BLOCK_UP.poiTypeSrcVr FOURS_PONDING.poiType -> FOURS_PONDING.poiTypeSrcVr FOURS_FOG.poiType -> FOURS_FOG.poiTypeSrcVr @@ -569,7 +592,7 @@ enum class EventTypeEnumNew( fun getPoiTypeBg(poiType: String, isVrMode: Boolean): Int { return when (poiType) { FOURS_BLOCK_UP.poiType, FOURS_LIVING.poiType-> if (isVrMode) R.drawable.bg_v2x_event_type_orange_vr else R.drawable.bg_v2x_event_type_orange - TRAFFIC_CHECK.poiType, ROAD_CLOSED.poiType, FOURS_ROAD_WORK.poiType, AI_ROAD_WORK.poiType, + TRAFFIC_CHECK.poiType, ROAD_CLOSED.poiType, FOURS_ROAD_WORK.poiType, FOURS_PONDING.poiType, FOURS_FOG.poiType, FOURS_ICE.poiType, FOURS_ACCIDENT.poiType, FOURS_ACCIDENT_01.poiType, FOURS_ACCIDENT_02.poiType, FOURS_ACCIDENT_03.poiType, FOURS_ACCIDENT_04.poiType, FOURS_ACCIDENT_05.poiType -> if (isVrMode) R.drawable.bg_v2x_event_type_red_vr else R.drawable.bg_v2x_event_type_read @@ -585,7 +608,7 @@ enum class EventTypeEnumNew( FOURS_BLOCK_UP.poiType, FOURS_LIVING.poiType -> R.drawable.bg_v2x_event_type_orange TRAFFIC_CHECK.poiType, ROAD_CLOSED.poiType, - FOURS_ROAD_WORK.poiType, AI_ROAD_WORK.poiType, FOURS_PONDING.poiType, + FOURS_ROAD_WORK.poiType, FOURS_PONDING.poiType, FOURS_FOG.poiType, FOURS_ICE.poiType, FOURS_ACCIDENT.poiType, FOURS_ACCIDENT_01.poiType, FOURS_ACCIDENT_02.poiType, FOURS_ACCIDENT_03.poiType, @@ -602,65 +625,40 @@ enum class EventTypeEnumNew( fun isRoadEvent(poiType: String?): Boolean { return when (poiType) { TRAFFIC_CHECK.poiType, ROAD_CLOSED.poiType, - FOURS_ROAD_WORK.poiType, AI_ROAD_WORK.poiType, FOURS_BLOCK_UP.poiType, + FOURS_ROAD_WORK.poiType, FOURS_BLOCK_UP.poiType, FOURS_PONDING.poiType, FOURS_FOG.poiType, FOURS_ICE.poiType, FOURS_ACCIDENT.poiType, FOURS_ACCIDENT_01.poiType, FOURS_ACCIDENT_02.poiType, FOURS_ACCIDENT_03.poiType, FOURS_ACCIDENT_04.poiType, - FOURS_ACCIDENT_05.poiType, GHOST_PROBE.poiType, AI_ROAD_WORK.poiType -> true + FOURS_ACCIDENT_05.poiType, GHOST_PROBE.poiType, + TYPE_SOCKET_ROAD_SHIGONG.poiType, + TYPE_SOCKET_ROAD_JINGZHI.poiType, + TYPE_SOCKET_ROAD_SHIGU.poiType, + TYPE_SOCKET_ROAD_CONGESTION.poiType -> true else -> false } } - /** - * 是否需要UGC预警 - */ - @JvmStatic - fun isNeedRoadEventUgc(poiType: String?): Boolean { - return when (poiType) { - ROAD_CLOSED.poiType, FOURS_ROAD_WORK.poiType, AI_ROAD_WORK.poiType, - FOURS_BLOCK_UP.poiType, FOURS_ACCIDENT.poiType, - FOURS_ACCIDENT_01.poiType, FOURS_ACCIDENT_02.poiType, - FOURS_ACCIDENT_03.poiType, FOURS_ACCIDENT_04.poiType, - FOURS_ACCIDENT_05.poiType, GHOST_PROBE.poiType -> true - else -> false - } - } - - @JvmStatic fun getTts(poiType: String?): String { return when (poiType) { TRAFFIC_CHECK.poiType -> TRAFFIC_CHECK.tts ROAD_CLOSED.poiType -> ROAD_CLOSED.tts FOURS_ROAD_WORK.poiType -> FOURS_ROAD_WORK.tts - AI_ROAD_WORK.poiType -> AI_ROAD_WORK.tts FOURS_BLOCK_UP.poiType -> FOURS_BLOCK_UP.tts FOURS_PONDING.poiType -> FOURS_PONDING.tts FOURS_FOG.poiType -> FOURS_FOG.tts FOURS_ICE.poiType -> FOURS_ICE.tts FOURS_ACCIDENT.poiType, FOURS_ACCIDENT_01.poiType, FOURS_ACCIDENT_02.poiType, FOURS_ACCIDENT_03.poiType, FOURS_ACCIDENT_04.poiType, FOURS_ACCIDENT_05.poiType -> FOURS_ACCIDENT.tts + TYPE_SOCKET_ROAD_SHIGONG.poiType -> TYPE_SOCKET_ROAD_SHIGONG.tts + TYPE_SOCKET_ROAD_JINGZHI.poiType -> TYPE_SOCKET_ROAD_JINGZHI.tts + TYPE_SOCKET_ROAD_SHIGU.poiType -> TYPE_SOCKET_ROAD_SHIGU.tts + TYPE_SOCKET_ROAD_CONGESTION.poiType -> TYPE_SOCKET_ROAD_CONGESTION.tts else -> "道路事件" } } - @JvmStatic - fun getTtsWithFeedback(poiType: String?): String { - return when (poiType) { - TRAFFIC_CHECK.poiType -> "交通检查" - ROAD_CLOSED.poiType -> "封路" - FOURS_ROAD_WORK.poiType -> "施工" - AI_ROAD_WORK.poiType -> "施工" - FOURS_BLOCK_UP.poiType -> "道路拥堵" - FOURS_PONDING.poiType -> "道路积水" - FOURS_FOG.poiType -> "出现浓雾" - FOURS_ICE.poiType -> "路面结冰" - FOURS_ACCIDENT.poiType, FOURS_ACCIDENT_01.poiType, FOURS_ACCIDENT_02.poiType, - FOURS_ACCIDENT_03.poiType, FOURS_ACCIDENT_04.poiType, FOURS_ACCIDENT_05.poiType -> "交通事故" - else -> "道路事件" - } - } @JvmStatic fun getAlarmContent(poiType: String?): String { @@ -668,7 +666,6 @@ enum class EventTypeEnumNew( TRAFFIC_CHECK.poiType -> TRAFFIC_CHECK.content ROAD_CLOSED.poiType -> ROAD_CLOSED.content FOURS_ROAD_WORK.poiType -> FOURS_ROAD_WORK.content - AI_ROAD_WORK.poiType -> AI_ROAD_WORK.content FOURS_BLOCK_UP.poiType -> FOURS_BLOCK_UP.content FOURS_PONDING.poiType -> FOURS_PONDING.content FOURS_FOG.poiType -> FOURS_FOG.content @@ -677,63 +674,14 @@ enum class EventTypeEnumNew( FOURS_ACCIDENT_03.poiType, FOURS_ACCIDENT_04.poiType, FOURS_ACCIDENT_05.poiType -> FOURS_ACCIDENT.content GHOST_PROBE.poiType -> GHOST_PROBE.content + TYPE_SOCKET_ROAD_SHIGONG.poiType -> TYPE_SOCKET_ROAD_SHIGONG.content + TYPE_SOCKET_ROAD_JINGZHI.poiType -> TYPE_SOCKET_ROAD_JINGZHI.content + TYPE_SOCKET_ROAD_SHIGU.poiType -> TYPE_SOCKET_ROAD_SHIGU.content + TYPE_SOCKET_ROAD_CONGESTION.poiType -> TYPE_SOCKET_ROAD_CONGESTION.content else -> "道路事件" } } - @JvmStatic - fun getTypeSmallRes(type: String): Int { - return when (type) { - TRAFFIC_CHECK.poiType -> - R.drawable.mogo_image_jiaotongjiancha_small - ROAD_CLOSED.poiType -> R.drawable.mogo_image_fenglu_small - FOURS_ROAD_WORK.poiType -> R.drawable.mogo_image_daolushigong_small - AI_ROAD_WORK.poiType -> R.drawable.mogo_image_daolushigong_small - FOURS_BLOCK_UP.poiType -> R.drawable.mogo_image_yongdu_small - FOURS_PONDING.poiType -> R.drawable.mogo_image_jishui_small - FOURS_ICE.poiType -> R.drawable.mogo_image_jiebing_small - FOURS_FOG.poiType -> R.drawable.mogo_image_nongwu_small - FOURS_ACCIDENT.poiType, FOURS_ACCIDENT_01.poiType, FOURS_ACCIDENT_02.poiType, - FOURS_ACCIDENT_03.poiType, FOURS_ACCIDENT_04.poiType, FOURS_ACCIDENT_05.poiType -> - R.drawable.mogo_image_accident_small - else -> R.drawable.mogo_image_shishilukuang_small - } - } - - @JvmStatic - fun getTypeRes(type: String): Int { - return when (type) { - TRAFFIC_CHECK.poiType -> R.drawable.mogo_image_jiaotongjiancha_nor - ROAD_CLOSED.poiType -> R.drawable.mogo_image_fenglu_nor - FOURS_ROAD_WORK.poiType -> R.drawable.mogo_image_daolushigong_nor - AI_ROAD_WORK.poiType -> R.drawable.mogo_image_daolushigong_nor - FOURS_BLOCK_UP.poiType -> R.drawable.mogo_image_yongdu_nor - FOURS_PONDING.poiType -> R.drawable.mogo_image_jishui_nor - FOURS_ICE.poiType -> R.drawable.mogo_image_jiebing_nor - FOURS_FOG.poiType -> R.drawable.mogo_image_nongwu_nor - FOURS_ACCIDENT.poiType, FOURS_ACCIDENT_01.poiType, FOURS_ACCIDENT_02.poiType, - FOURS_ACCIDENT_03.poiType, FOURS_ACCIDENT_04.poiType, FOURS_ACCIDENT_05.poiType -> - R.drawable.mogo_image_jiaotongshigu_nor - else -> R.drawable.mogo_image_shishlukuang_nor - } - } - - @JvmStatic - fun getTypeName(type: String?): String { - return when (type) { - ROAD_CLOSED.poiType -> "封路" - FOURS_ICE.poiType -> "道路结冰" - FOURS_FOG.poiType -> "浓雾" - TRAFFIC_CHECK.poiType -> "交通检查" - FOURS_ACCIDENT.poiType, FOURS_ACCIDENT_01.poiType, FOURS_ACCIDENT_02.poiType, - FOURS_ACCIDENT_03.poiType, FOURS_ACCIDENT_04.poiType, FOURS_ACCIDENT_05.poiType -> "交通事故" - FOURS_BLOCK_UP.poiType -> "拥堵" - FOURS_ROAD_WORK.poiType -> "施工" - AI_ROAD_WORK.poiType -> "施工" - FOURS_PONDING.poiType -> "道路积水" - else -> "实时路况" - } - } @JvmStatic fun getMarker3DRes(poiType: String?): Int { @@ -744,31 +692,17 @@ enum class EventTypeEnumNew( FOURS_FOG.poiType -> R.raw.v2x_nongwu TRAFFIC_CHECK.poiType -> R.raw.v2x_jiaotongjiancha FOURS_ROAD_WORK.poiType -> R.raw.v2x_daolushigong - AI_ROAD_WORK.poiType -> R.raw.v2x_daolushigong FOURS_ICE.poiType -> R.raw.v2x_daolujiebing FOURS_PONDING.poiType -> R.raw.v2x_daolujishui GHOST_PROBE.poiType -> R.raw.v2x_guzhangqiuzhu + TYPE_SOCKET_ROAD_SHIGONG.poiType -> R.raw.v2x_shigong_warning + TYPE_SOCKET_ROAD_JINGZHI.poiType -> R.raw.v2x_zhangai + TYPE_SOCKET_ROAD_SHIGU.poiType -> R.raw.v2x_shigu_sanjiaopai + TYPE_SOCKET_ROAD_CONGESTION.poiType -> R.raw.v2x_yongdu else -> 0 } } - @JvmStatic - fun getTypeNameTTS(type: String?): String { - return when (type) { - ROAD_CLOSED.poiType -> "封路" - FOURS_ICE.poiType -> "道路结冰" - FOURS_FOG.poiType -> "浓雾" - TRAFFIC_CHECK.poiType -> "交通检查" - FOURS_ACCIDENT.poiType, FOURS_ACCIDENT_01.poiType, FOURS_ACCIDENT_02.poiType, - FOURS_ACCIDENT_03.poiType, FOURS_ACCIDENT_04.poiType, FOURS_ACCIDENT_05.poiType -> "交通事故" - FOURS_BLOCK_UP.poiType -> "拥堵" - FOURS_ROAD_WORK.poiType -> "施工" - AI_ROAD_WORK.poiType -> "施工" - FOURS_PONDING.poiType -> "道路积水" - else -> "实时路况" - } - } - @JvmStatic fun getUpdateIconRes(poiType: String?): Int { return when (poiType) { @@ -785,9 +719,10 @@ enum class EventTypeEnumNew( R.drawable.v_to_x_marker_11 } //AI施工 - AI_ROAD_WORK.poiType -> { - R.drawable.v_to_x_marker_11 - } + TYPE_SOCKET_ROAD_SHIGONG.poiType -> R.drawable.icon_warning_v2x_road_construction + TYPE_SOCKET_ROAD_JINGZHI.poiType -> R.drawable.v2x_icon_jingzhi_zhangai + TYPE_SOCKET_ROAD_SHIGU.poiType -> R.drawable.v2x_icon_shigu_sanjiaopai + TYPE_SOCKET_ROAD_CONGESTION.poiType -> R.drawable.v2x_icon_yongdu_vr //拥堵 FOURS_BLOCK_UP.poiType -> { R.drawable.v_to_x_marker_5 @@ -907,7 +842,10 @@ enum class EventTypeEnumNew( TYPE_ERROR.poiType -> TYPE_ERROR.poiTypeSrcVr TYPE_OPTIMAL_ROUTE_RECOMMEND.poiType -> TYPE_OPTIMAL_ROUTE_RECOMMEND.poiTypeSrcVr GHOST_PROBE.poiType -> GHOST_PROBE.poiTypeSrcVr - AI_ROAD_WORK.poiType -> AI_ROAD_WORK.poiTypeSrcVr + TYPE_SOCKET_ROAD_SHIGONG.poiType -> TYPE_SOCKET_ROAD_SHIGONG.poiTypeSrcVr + TYPE_SOCKET_ROAD_JINGZHI.poiType -> TYPE_SOCKET_ROAD_JINGZHI.poiTypeSrcVr + TYPE_SOCKET_ROAD_SHIGU.poiType -> TYPE_SOCKET_ROAD_SHIGU.poiTypeSrcVr + TYPE_SOCKET_ROAD_CONGESTION.poiType -> TYPE_SOCKET_ROAD_CONGESTION.poiTypeSrcVr TYPE_USECASE_ID_IVP_RED.poiType -> TYPE_USECASE_ID_IVP_RED.poiTypeSrcVr TYPE_USECASE_ID_IVP_GREEN.poiType -> TYPE_USECASE_ID_IVP_GREEN.poiTypeSrcVr @@ -966,7 +904,10 @@ enum class EventTypeEnumNew( TYPE_USECASE_ID_LTA.poiType -> TYPE_USECASE_ID_LTA.content TYPE_VIP_IDENTIFICATION.poiType -> TYPE_VIP_IDENTIFICATION.content FOURS_ROAD_WORK.poiType -> FOURS_ROAD_WORK.content - AI_ROAD_WORK.poiType -> AI_ROAD_WORK.content + TYPE_SOCKET_ROAD_SHIGONG.poiType -> TYPE_SOCKET_ROAD_SHIGONG.content + TYPE_SOCKET_ROAD_JINGZHI.poiType -> TYPE_SOCKET_ROAD_JINGZHI.content + TYPE_SOCKET_ROAD_SHIGU.poiType -> TYPE_SOCKET_ROAD_SHIGU.content + TYPE_SOCKET_ROAD_CONGESTION.poiType -> TYPE_SOCKET_ROAD_CONGESTION.content TYPE_ERROR.poiType -> TYPE_ERROR.content TYPE_OPTIMAL_ROUTE_RECOMMEND.poiType -> TYPE_OPTIMAL_ROUTE_RECOMMEND.content GHOST_PROBE.poiType -> GHOST_PROBE.content @@ -1029,7 +970,10 @@ enum class EventTypeEnumNew( TYPE_USECASE_ID_LTA.poiType -> TYPE_USECASE_ID_LTA.tts TYPE_VIP_IDENTIFICATION.poiType -> TYPE_VIP_IDENTIFICATION.tts FOURS_ROAD_WORK.poiType -> FOURS_ROAD_WORK.tts - AI_ROAD_WORK.poiType -> AI_ROAD_WORK.tts + TYPE_SOCKET_ROAD_SHIGONG.poiType -> TYPE_SOCKET_ROAD_SHIGONG.tts + TYPE_SOCKET_ROAD_JINGZHI.poiType -> TYPE_SOCKET_ROAD_JINGZHI.tts + TYPE_SOCKET_ROAD_SHIGU.poiType -> TYPE_SOCKET_ROAD_SHIGU.tts + TYPE_SOCKET_ROAD_CONGESTION.poiType -> TYPE_SOCKET_ROAD_CONGESTION.tts TYPE_ERROR.poiType -> TYPE_ERROR.tts TYPE_OPTIMAL_ROUTE_RECOMMEND.poiType -> TYPE_OPTIMAL_ROUTE_RECOMMEND.tts GHOST_PROBE.poiType -> GHOST_PROBE.tts @@ -1076,6 +1020,17 @@ enum class EventTypeEnumNew( else -> TYPE_ERROR.tts } } + + @JvmStatic + fun isCloudSocketEvent(poiType: String?): Boolean { + return when(poiType) { + TYPE_SOCKET_ROAD_SHIGONG.poiType, + TYPE_SOCKET_ROAD_JINGZHI.poiType, + TYPE_SOCKET_ROAD_SHIGU.poiType, + TYPE_SOCKET_ROAD_CONGESTION.poiType -> true + else -> false + } + } } } \ No newline at end of file diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/map/entity/V2XRoadEventEntity.java b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/map/entity/V2XRoadEventEntity.java index eea9b6b93e..0bd2dab8fd 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/map/entity/V2XRoadEventEntity.java +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/map/entity/V2XRoadEventEntity.java @@ -4,6 +4,7 @@ import android.text.TextUtils; import com.mogo.eagle.core.data.enums.EventTypeEnum; +import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import java.io.Serializable; import java.util.Objects; @@ -37,6 +38,7 @@ public class V2XRoadEventEntity implements Serializable { // 绑定 MarkerView 的数据, 业务需要啥数据就传入啥数据 private Object bindObj; + public MarkerLocation getLocation() { return location; } @@ -84,7 +86,7 @@ public class V2XRoadEventEntity implements Serializable { } public String getTts() { - return tts; + return EventTypeEnumNew.getTts(getPoiType()); } public void setTts(String tts) { diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerVisualAngleManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerVisualAngleManager.kt index c01e0b89d7..75b7b224e5 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerVisualAngleManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerVisualAngleManager.kt @@ -301,9 +301,12 @@ object CallerVisualAngleManager { return@launch } } - + if (prev.priority == current.priority) { + Log.d("${M_DEVA}${TAG}", "--- 9 --- 场景[$prev]正在展示,尚未收到关闭,优先级一致,直接return") + return@launch + } if (prev.priority > current.priority && prev.displayThreshold < 0) { - Log.d("${M_DEVA}${TAG}", "--- 6 --- 场景[$prev]正在展示,尚未收到关闭,场景,依然展示当前场景,直接return") + Log.d("${M_DEVA}${TAG}", "--- 10 --- 场景[$prev]正在展示,尚未收到关闭,场景,依然展示当前场景,直接return") return@launch } doRealVisualAngleChange(triggerTime, current, displayed) diff --git a/core/mogo-core-res/src/main/res/drawable-xhdpi/v2x_icon_shigong_zhandao.png b/core/mogo-core-res/src/main/res/drawable-xhdpi/v2x_icon_shigong_zhandao.png new file mode 100644 index 0000000000000000000000000000000000000000..0a21b49728c53f7ef5e414d26fa7df64f3095e90 GIT binary patch literal 17365 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 literal 0 HcmV?d00001 diff --git a/core/mogo-core-res/src/main/res/raw/v2x_shigu_sanjiaopai.nt3d b/core/mogo-core-res/src/main/res/raw/v2x_shigu_sanjiaopai.nt3d new file mode 100644 index 0000000000000000000000000000000000000000..79c8df21ad6ee2e4e9954d9cfdaefd6f87c074f5 GIT binary patch literal 228665 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%0Dl?j~SAi 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

4s`tO>rx?4kAK0vTK~f%OxK0a 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 z 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 F0RR(2^05E_ literal 0 HcmV?d00001 diff --git a/core/mogo-core-res/src/main/res/raw/v2x_zhangai.nt3d b/core/mogo-core-res/src/main/res/raw/v2x_zhangai.nt3d new file mode 100644 index 0000000000000000000000000000000000000000..a5a7d00b5f6339d6a883085832bb2bdd1732a9ed GIT binary patch literal 498336 zcmeFYc|4Wf_cwka(L|*}re>8XsSM#%DwU#{N<@PSnUeV+Nm3+J#*-$A3`xkGp$s{N z43U{*o`-{TT+hDBzT3C^?(=UGwBd+)W^T6?Xvw{u<1VPnBCZ27=A z-A`C0w$FOl;3^SXSbK7zJ8jxplP`s`K$F~CxVdwrGI8MZBOAd}_9>wwK zvS0G++c@H*j3_5jLGCO#HXazv70*`Ir5_I4BNfVlL_nYCo}7r8|c0 z25X@l6u$=cCG8H_^T6pm0ekvao=nTAzd!fuUvOf7VNB2*M)MZkmw#|(>?5(KPd8y0 zCl|17*Wc|&ZALjLUaW{=^)?tr>;;S=Q47Cn1o#N$X+Kh5$;&8tRPOK^`R(6~1XML^YXT|gq|K1x>4w_4_4-ol7aGKhfI5C%y zk0LMN=9nH&^H`yQODz{>KMPQu5Zxip<8CtB8mJptuFzX%-4(03SHf)8Ug(|5>0@ju1rC=>BSZ9roP*P6*eaVQgOou%Tq^*ju_1o{tw!~8_^ z7UiHg+J_0w_7NPv0Q8{zKXFhT?Hhy*u+~tWf8wAxVH-Sm2tBY)2^r?(%p8Lp6i4ft zm`mgg%x8EGqP+#>p!iRn|I&M5A4YSPkReX=Z8SH2?eDLCPV^|4tAq@D2zu_I927^- zDS`ug1tG(__{jk_6ZbKcgW|t*{yN9uTp~V@Pvjoz3(7%p^xPphuvZW=+%NR*gmO^) zm(E|kh2X$?fih8dGi`<(6oFF(G6a^PhasqhNd>2gQHNNDSc~5qe;+fHuRm zAP2>N+4ifSKwpU1LYb)FnKl!Cq4A%YSEvn8{>}d#!ea-T}~i7kXDgIVeuZ z(StZn^c?hVK-eP@^XqISWY~*lav+Z08Bm?XT-ZaOpa$ zPr`jc^%Hz(55a-^i*isLJzoesR+bgp?DXsY8Lss=4vHgt2WuSq1?R$AhBz93lmqWh#99zXV-EZ3 zPuoxq5?k1Rh_e`;v*@{u-Z4-PiW4&Y&IdiCXY&7zgU%)Fg!P5mfZhiP4y-SfgW{-d z1dit3)9GGB;P7rUlY`=DPSQ^N>Nx}-_98+?a~|cOIJ_gx^abVri34$BE$BNTLtoIC z6F7_^%9)8nABnyMYX{2kY=yM|aU#bE8O328&E%jstc95z6rY*HXgYk#vJx5=;Oa};QqoG&g7stj5)zUWoR3Lqjdyj zwAN|`4!|@^@ zqnw#|)pHzw1m=nW8#*g-d@Zp5)k+*UX~OZ4TR1*v1&)8r#PLDDzjILhxCM?+x#IZA z!#GaZCMFJ^FM>a4+|W3q926(~g>z9~Q2W)vTFY#~cOhUcl!M{{_c3e<;H*6IYcJ?8 zaGb~!BK}ZD{U!G6-|!)@7YD0=-ykMv4x@RC?hDF6addz0w}R(I;QnzZ@bC7cHlrLA zcdNrNqn+SP^}+GQpw^yj!Es$sr@f$Np^W;7a!?%g7tIGR5Vr}ikBdOu&^<*tC{FAP z%pWw*(YiqGM>!~t?j5QhwFlh`l!M~vp8Ea3Fpg&My|W9bEo2{2ohS#zok5&~GH^T$ z#Q6oN1ur2`U!WFH`%#-w4vMpb+9B-#&-DFqoUs7MTh%dag#d=NbK$tkats?d^7r0| za?o5t^M{z5-iqVIT!JqUkK=?+w2n{?ilcq+)CueVDM#ONZ!gzhVx1HHxGAh{g)F8TAq6pg04T<@6$a5Jzr1`ilgTgF&Fj< zf)9HLdM`pbC{E~v_a7s0e!*U051vWD9)kLUa!?#ScWl92qF3Ajy@KGw9)jMTP!5Wt z_rT^J@P5s7uR!fbZALjLj_wN@6EvP^3{eh>qp?Ewh*%f)3SupIe?~bdj_w^AThxBk zW|V{CXv|R?(0I;_A+!_4QQOcv0DA92?eo5L4&EC>jrkAZI4_tx23}C~ z2Xj&RPaFa_N9N9%!f|3QfrD4ra6%_46FUEmgW}kl{GyAI;C1 zGFmS%x6!%mAfK&4P04}U_)~8GiSwWEJ3t?yli)xZ)&D0Ptw&TpD*uTy6Nl>(IP4*W z40{4780tc^P|2(5n8MX6II2zAMpvN5er40N;9y*+9P{s&4+z();&w_Ww2q)zAEC4YUVr)?a^q%m24I zsD5Z0AF$)!WFl_=6aK%$`IG+tgroOcR7UOj6OMBJPh=P?!p?t_3E%%G{C|h@C;k5k zM}J>HWz?QO;V9?-M3xi>&y4KAdvH53EW`@DPp5)mQw|sgaX1zi!>~q2z|qFAu4@>^ ztA$}5M&NnNNet^1`HjPICU_2V6nt+B^}zYrYr!)kL_Zv_0MBmJ!2jid^PryD$1rRg z_~9>7p?>HmKd`$1yaRY2Ji~f!@!Nkm zhJNqn#4y%F7?#D3VG-c-2KZd22L8XzG!DlSU_5aEyd%JcVM1~kwstZ2epw#FN*7{S zp7L)Tj)Or`EeH4$z%}5&Fz65T58`kfCJXin=z?~@^;rPM3iblxaBKqXxd!&C7ua!m zDd<-qRwwy?+W~QCuRri>!M5M~3ilbt1MW8*!}uwHwx1j%vwk{Wa2~|r7_=2kWjlsNf&Yuv333ds57&h_9Df3NI|QEBihz8#0`*k@ zo<(XJ{@xFW!+n79uLsW|$g42SS_9OZFowZ=fjAt)dioB&?=b~=pbq|p02#&`;&2T2 zM|A`E-tq>xH-J7dVfDM7Ar9*s))%y6FUX}uz;~Fp5Qk%E7xWX_3+;qB9MAL{)-m4> z3_B0%7sdmQVZ5Lpa9wB@#NinF5A{O7px+ROW4MkO=sPY4!FQ?C`v>RRQo9 zgZ=@3J`;yyn9s0Zz{(#ySwEo?1ArAWq>^E}&Z}TE>F9h=%k-iUccn-jRxe4^!{3YNV0)1{4 zh%K}O;&2T6iP(CO_pTTgxDxb6aGqta{dFEe9FF06r3U&l@dvIC*M&G7!+1cup?}aX zh{G}T1IDEpoVya>nKC?gAP&bcPS8)dK3o^#a18y1dZB;NFNni2TnF}5*w0}fhd3PX z0e$c!$Ya=Ni8Jiz1@K>@r~5p_;TZN^IFE=a(H~*Igg6|-^`IWOFL2)=4##kPxX-XZ z!@dl0IEMN0<1vOk&cv{{55YSP2^bawJ{#jP4B~KX2Y7p*W0)Q2(Feh&062?mz^CFq zklz8naX1#;k6}FkuTBB?0q~B>jyTW@r9cmj0l5S|Ar8mXWU%+^!0w|f(Yg@buh zAom^uJV*XF4#y)v&sV^+9|YgwYh&2m5%7HD6u5JYg7232`_k=GC)f*a;Au2dsdbhGDnBm^~G|s{!^H;&A*m1K17pEC9S{ zus$D{_Z-~Ad;mTO)`d76=e`Huxt;lKM?n>+N3c!__Oer+6DcD_Ch-$4#&{% zIH2z+umi>k#sT7R{1)&Y13RG|&_C!G#Nim)1^tBjpdN_BG4vbe0o-S}j}V7rm=}2< z-jPbb;|JpgaX7XI@f-v^xKI3GABcOwSAa`{Pl&@Y+&7qKP#@F-aX5x~2lc}Ig?S5c zIEL%YehKa*Aa6#WVOR^;*V~|GK#5@xhvRFJpq_}{0eBBVUT}bUrdr?*3-BrM32`_k z<~4!5uL5@^Q;_!!X5bzQ#@gUB2JAP);rM|u_&pEs+`!Kd0Xyu$JXNrs48T)C9Y7q8 zSpbjtqu~L*YXbJb_2Ie@hvVabw->An?S}qAzaS3B&<_}w)nL9quuBwtf|l}Eyx!j&}`-~*`eG7cv2Yt#`55v}gJ_B($CeE{A3DDcX z?|_qQfB$?Y4#!-E7`7Ggpk6I7uTmDo7vRt2e&cWq*Ma*)0{gXRC5Q`{$6WDy|KJ$z zTM*zmD*oPoxbF~$mQkQlf| zVslLQodRyp<01aBU_l{#AUCl6yLTS9X6a5hEVk^qQJGkneRtVhZ6xy{BGTJUv^`W^xIoIZ0p#aZr6A9(|l)PdCA_%@}!oK&m&V|Hh4Dg`5Ox|i8~dD?s0X{rUOujgH5 zSk{04{x<^u-$x+zI;+TtWY1*5J5tv%6Ut;1sb`cuvw>EpOujiauqEs(o{ig0HugWA&Nh#iJ0oGx1YQ%Wz*N= zV5J?Q5l^GqoEu+A<4EOUcy?|$-&UvBb|I=iI(^sE(c-Pj7MJWhD=5m>Ngx^HlqX7i;V1(WkXpKbS~PTjpcP!~?w))J^xLSCl3-N5M0T|4s(_IJy4 zF?$V%Mg1qq?iY-0$yd314fIFS*HiaD|iYtMKx308(^?b z>%xSjPj4A{Sfq~p$dEQU)i$-b!`;kyZ01(GNwbJ(knWXR?JcA^R`e)2(yi(;dUWZ} zY9dIT?ZfUZo&5HWESr?Ahn?E?m~Bl^wYc{2O6|aebD+jkpRo;|33yBfbLrP6B~eAa zA{o07rg+AUlB#D*#)71^D74rE|JANj`VcZ#T=cyuChB{vcUpS3!Dd zU&x`0LI*7rhCk`q4|<$c)ZCe}c74rIoc6}WeoAN6WUn>ST6hF$OX}4^BGcW=VkLA0 zt~j>8{ltsa56NB=p?{@Ktt>0NTV#$$nhU57y17!?)pxFF&Go(9^ustD7>rWPjA*iJ7gVhcvc*?#<6B zJ*-)1&q>PWZIjP)i&1q6@!Y6r7<+g_8+CcULCHN0=0*zLM?^WOcKJEY(36tqFfGRdvENnpXhz*t57MQ0bU(b5RBQ3(ZB`s&JuzHtk zRMYAucT;`2?uLI{TFJjEiWIimI$Wc}%IU=$t{3A%wk?~K$MYn^q8`^S_U*CJl3eOu z7#8zfAgSMCaE_Y4AXjh`{YYnpOhErt_zuxUtk9Z?F25N^IoQ5X#I z=v%F0^l8Dnm^rdBDVp{cKSqu>xa-EZZ8aHeUaeRuuY7*^s(q`(#TBCa9B%cM_i8-4 zUgoJRWHrn9y5i9Cfvs+%1MHaYta4sflaAOot@G|oG}oHO@`{Z4i=X zp^)kpeNKDlE{Yf8fsaMrU7tMo{C)^`h$#J*QsiXT$mIuRM_dhhmTt^roXVmX2M$E) zw(?LpTv@b<3VA?ONL7RFfwd-PTQ66HrfHakFsoX(~mq;X9$@b`m#thsgmYx z>2G->{4K|(Q#xieay2!DuH2M&yY^gHkZE&}U7l>^Sq=6u`cgxkp>-tX4;G=#GJ9k5 zHS3PfHosY}N>}fhy0u@nr@hQf^~>ImGO>$vE%-8MV$rnI}H%GvZH`tza7S8j)uY7Vh&Dql+8pHg@#Gr z>Za8@#xCn!eZzi9zN!6sio87J4FohW4i%=Kg5=XZ(-4~AtaHj-CZyKWn^s&rn`5^4;7>< z1(e5E=ag$+-7a;0-tYwXMyY}Mg}fw&cF&|dxj$e)jrO%*zS8s9FphIC#TXCG{Sxfe zY{FWvt}96XM2Qg{3X`%@qL#>8g!Rabcnr*|QlJCb% z)U{({bQ{zd?0rV#uKl;_I>byiST*KYORi(wk`MHXjg{FE<{ukYxj|!y-BvHwN8*&j##`#b)H8g7)#@ydz12sYW^BR8M@v@N%bwjN&v}$>Sk_3krWNC8tA5AD~KoU-fu?B4ZlWS+fyW<#h%=EATq+Z|dZS|#oIsCl<2n?#2OMl5H4DjWPZ zq|kaLV~13?VOspXXr_kTmP(pE! z%p!yNAwvB*B5lv>lE)jCM4!9;n(Uve)idT2Gst-(dEWp&{{nmTfDAd`#hBXW9+)1Q z;@)`vP;H})+}&Wl(o&7FwcnK!%T)P4rL-xpi{%?I$Vh$PohjH>wBe&~Qwxt_jF#DV zZ}v+SRz>d*UC2DwqO4xtJXNx_U9Yv6k$Th1zgJW6TDvBV0{_Wr(prk&!k{zzsq9cipzsjY0_>*E$~zupjI4c=;L zr2Hkmjbm_pQ>)wdH6lR?g?BQ$?N^A?RKK|u%Z#evP5oN zLNq|B`An?j;~(8($`*H?_Z22BXl~okcs^Eg+}k3ro-1W2JJqc1vx1f2`4^-k3eq;w z32m`#@{{X-jPnO6R;ya5>2Y^N4XRXbPQf(fWvqHR90$*wni%GZ+9M^VGgq<0q5N)a zX4)fbJFX)>hw5_|uX}gZ^5`ZxYJ(?7eSF~dk=v5y6QK?ZDavXaK2t)P2H0g?LeEWw zre(1!Gkom6>9}%v@imvIJ|bTc)nO{SBuKcK=YMTIa=PoD4C&}$ewB2W%WKFiw*K`k z^EzyjInSnE0^NOiWp`^(3(L>qRg}6VI;^g1qh`YyD}UXnn)?AqkFVoq5lW6sgY$;( zQ8dfKGJ9v8s;(A+6*ZZQ``>$CEB}4U1xq_yweVv0beyX0IOtf%XieBFKQM&(Zw<>W zp(hyY3%@K;eBh^{Lo$kSi@n?GaclN10nha#dZ~=5D_gk7#Eq;OU+k>Co{noZ&^TB# zOdl0JQZ}+aW&ep+U216Q4k7>8>!-WQZ&7RIvJK{0?x2Xp&x%O0k&1gV-_@k0NGf*a zfDDC?tTX(1Gq+8}{nbj8fp3jzeJ%c^+O-xXg5qS>^phezE|W3uvL05jyuW%~XY{ab z$;HXbJHB~HpOJ{r{^An9ZdB!HR6q9W!mT1<(;IS+wjXv8#Y@Gmj7r;l^VXr1%+;OP z86FX2JnDs;E-F~8Dmk{0#`@*#*@xQCDO9QOj+}LSt{HeZ_6p5!)jF4_>Ln9CX^~IP zI(fNG!R6Va=&j>1O*}rgO7!}wH7ZNnrc65B#@in}mfzCjtmFEMCpB1Rf4T73O+|w_ zZgxQvAN*u2I-i_7$@G*EKfvx@(|0%Ut>D<*#uTsTRzfsYZppz?pIKEA8RlFHdW~!4 zT7w1NE7Vr&7YIooG;0?ha~u`<8sHU)Z|=6d!|h^(AIR$3n~L;TQXnV~2bN7FM&__$ zeAC9YB1)W=2RU<&sn$6>&i9T;Bgbvr&aD;d)UTq-a5c8>Y-34^S57`rIB>3}d`M3| zrO7=YheKho?E|;){CV3m^w`dkhO$Y?Yt|UI7U^*=7x`i^pP6>qX5hxc;ENjHN9}fd z(aZA!Q;q1hCfNbZmzjg^eS>0q@Rraa*Y9<{`p0gV(r#{usJzQPQE|}GVPEv*Hc8#i ztnEC7UnoPW_ip8{O&UK~T)*nd!@LuGV`&Xbi#b|cdV7o3N&C9E@H)^N&q%V;t9kkC zRNCyX3)+u<)vmI!oEz!Y?b)GO8k{)n-Dkv8)Yuplm)UYde6nMCOOn9WghylgA#Hv; z&nCy5v=&nyubs?|9opj5ze_QtxhuE)^@^jougB1>k0DA~eKhmoey)3riNw~&hwP(^ z-(A-)Hfmj%>lN){U7T{quD3sjEm4;1+qr+URlC?PQ-lb;LLAK$G@n-kwCawxro+W-OK2L6I)6&*$dq>>qt# zv3cOZ0^za9TQqf%{%0q9@3}Z$amJTs4v$t-#`u$@CSv+Bna{zSjVa9Z0P`F6e_h|t zX*8@3&f4BN51UGKoXRFS(kKSr1B&J;$C?!PwdsXLJUC50T%>Yjyy@DiS=*$9ohmq< zc?L|zyu2oS{LKML-PD)OF5L0#60Xa$X+hMxJzFF4)IT{#p~)$CMWvv? z65Wpe7p_NK_@ug8Y_lafq2H4Fjx1?$M4rOA1@h0oa?k$}Smk0iF3vJ(A{Ftjm(69Yz|QQ?VJ36ZWL@zW8B&wpDS$NteOnrh~s`=Y7Zb z{VSJd^~AyJI_A!O##NpfmGhSP{f$Ol+MEz!wz{-kv3gVf^%j#px`TU?#tua<@HBAc_ms?cd#UJjZ&vwu zzsf^Ci(R)ebtb-iUK_>{n(fhd^*KeMm_x8@_0YMkP5C9-6W+duboR?%5-We!my)GH zvDa@Se@QTLkr2IYzf8Fzuup!w_NX5e#Wu0U;gR0W35d&+qk4`qGdc^Y#){rrY>@m(LKH3 zVfDN<9nUQmim5vnW_Ia)e=Rf5Zky%?k!8lr}6W+Tz4jIbFf}4koEG)sGf3l>Z5gYxotTQc&0bL0FjcB<*f{SAb)1; zkps)JSsBB0@3HW#d#9QY1j!mo3MS6Q@-23B-vdXrRY7{Ux%KPzV}+5g8QGZ*lMR{< zT|KhQ2JRmj8uk7prFH%ClpB+^RQyDe6g}B1-GQNz@0lV@Ia7C9KP(6T1P&29by{&%sN?p3%SWe+Ui-qE|7L5;u zBo&&Q-w>N}a0s`0g)H}GdW?Tngs}N1=a1Z48Uxy9lTN!$Xs&88-wei^L{~h1rf6QA z-nqRfVv~8bPvV9^j_=nFWGc2DQKfJP<>pc*zi=5_oT=fSt^Z)hC6S6Ct(1G-Zebic z^8;kW?FRgXt;XIwRx+qvEs<_*9Idq>>V}KE&HYbTsJU8$d*AUic7LJ@&lZg@UOk_i z!=fM4wUJvPAxieIy7AG#WZ%gE?f0HsA4z7ty1lAOOXT7oPD!|?3g5T#Id`i6lAn@c z{YYhgO9Dk+g%o`%GcdquouGAL-0VS>6ZT=$Z@TBx*PSdmirow3^-7nIVjCFrR_uB- z8N$8SP)WaU>LF=#oz!M2xgZWM+OfuFg;@q^OSQ(8Z4shm-ckYoXaMwHTd%5;tYMdI^V#6XcYHn4$TS4K)dS?y4)V>ho~A{5Mo3r zr$kH?NF=>I9Dhl@R6%N7h(lE3 z`nVC5mp41j^{5v$qAC}?jS*b^)_UZ*D1Pg-f!cZU4>iQQQ=woZn$yD5@ zGf0{AZ(bylo2VG;W+|BC{efGj>yySB<5N4TStf@jtgDK%uPi7O7Y{doc75Q`0ckqt z3Yz5(F2ljuH5slw+5>~@Y=mbubcIwOwv9eKIL`BlN2kW-2#NMG#;4!+(W5Bk;gzS% z!v&71eiun@sghmka6h#((RFslqE(d7m&ly4lV`^&TTPZ-v)eg_F@YBOM;* zvv#Unz0M^$q#!71m&YMH>ZW|$QRWr7dSP&7YiF2o`qb zEasv6>Y7iM$1;tROz5S$c)u(ueYUXi7pKa@)yZ2#bzWxJynaPZlL=Ea^I`ju7A4q3 zQ?!q6*j_M+b$i?@nCj=U8osE-yUo(}Qa8jRRyjV;;G{Ro(x2b4 z?@xPOw6`rk%y6Im`7MD48A~Fi?qp25Oq$$Pl>H!NXK*mfaLl;tcKswi3i4OovClDm z!`H8o+doH5`YP62=lx(_zZ@agK4f}=Y_I&XU}vpg`JV6G{%1AD&T8bUi@eP~RNS4T zpsB21=2h~9nlemrusNS(UEqF8#|Y* zVQo9$B52lQlTm$3smR&B#iTamlxYN;w*G_8LxHDzrIfd|uBuG;ua{!wEON<}8arTo z)XXpzyYp4eCA%RfeWFKeH~RD7yGTmdbwPk8TZ#1*g@2xyl%Axy?Y;Y?lWX+cRsfxr)Ps}cio8vy#P2LvI6J3kM-Rw8wU~UTG1;1=K?x47%pQ)Nmpd8mbZ)EY zXt8uGX(Z4pKWDAFj*-8OrhG2dhOU)e^mR?6y?g&YJkHbi%=-+t>PaGH*fS(B+BwQfVumWpxPbkD_?G zoj(`2fiDAVFi~ZElF_}Zc;f1p^sa9ry_sv@WG=KZ2rC>Kne?|Br!eYjD2)4k4)oE0 z*%bmj`H?CIuL)kfCI=2w6@Ia?({+!IEnY+AHg1XkAmh<4Hix_|?y7%%#=J#BMiYz6 z$9Y7Bl$mslY3aRZ5Dg+%1cOmFhlcX7^eSoZMv|DUh+~Paj@sGB}%iEPBtOeNq*# z)Xpa+$41Lig&Gf+XNM$Kt`VL(>E)nPp8M^&r$wFpgR=8-^AxW=_hYzL$bbBfBf;`RMei~9m~fkW#= z$d~%fZsW&V*;Q1_I?O7gie6`h*AH8>oguIGaS-wcz3_XzDXBOXz6)T^SSUyF7-^gJ zt^J|ECho$C{o=aUic2lnmW#Q6F5-|kwTja3dU5TC+miUvU165Ja$%cFi&E;cO61}; zIu7gR-&?d|TYy8uSmQ%E8|Aq39%tfv-4qQ&EQWn@4uphpSqOd3$(9c+s_v-V+s63D zruaH5`{;}MH>sb?wQcoyOs<5%)nc68-FcfI+-&7#KEP z&MvDuaoPK!+*Mz$q)NS;mY;-=&T4+CR%{sjJv>_L`ZzaT`n>*kw~0+1*xQC;t$@J%bWz`GiK8Ad*O-=M`6B`jb7Lk&jbuqM^ z?}y?*O7Eqk(jQu!#xz2u4Nf1co_NA06K`e9-=**>`}wuz9^=N;s_y$4l~eOLw<-CP zYy%BVR;wR$ESv4s8}i}IJC?2{{VS_!rW0~K$>!$Rv$^Muy%&`^k%GVtyg?4ru>u_5I zZ#{REIATw}RF2g%BHE)yZOabXzKyhvCat2@T6HqRgR8=4iQGCm)wL!%bCTDzYI|?C_qr?W>t^TuHo>(+CghF${OGL4Al~ZE zh-R-+F_B`!O7XGv3qJCjzKfmf9(YSLBdWGTroNWnPMtL7;OaNI@isNcr|Wr0!PcRE zs&>ji6jg4DR?$Gllj`d5&*0fX8?B+QMT>c}%P{CV_L*&uvPxP8a>2YCWPMuE1^CQXm?i$)`r?L_>&d4{~H#9nbTbs|__kHNl z>2BX%9ufIAclnP4IsAgw&Js44M{@kq<=9es+?RmwpW`{CtIsd>W~*)5X<|20uG~L* zdy8Nh@Hw(+Y z0|U$QDHaCYtc6}z!xn3eE@=%HjqC7EYJb4|u+ znK4tv;u4)poza1{T&vbe)~<|ZOFzD8NUX!*{qi+dYo1D_>JK+|^SC6*<;c_pn^6l_v~3l);8 zHkgtLqxj$!P}6jPsCzLd?fJTGoVbbsSX zNo;X;?0j+5o>{P_B%i%rWbQJPn_e~_z6w0PZP_2Ipm#e>mvflMiTSZU{90u6>aCN! z$99s^*6EP@4R6aCp2~L!nOxO7htn~5fG2A0M?Ik%6VXm`7yENa7R!=DqNpD(&2QN< zXR|H)o%nVMyk^h6yFL`Vy+$d_U6)!lyVIf~6dHEwh_ECR;>f&%TUOwY;>eH#+I|=@sTVXZhlqx>wdNQGVU9(K?^) zbM1lKE@>aayEG0l(l2=iv#^bIvI*78sW!SFd(q3GD`B^K(T{+T3WYl&{r&G>2#YAL zcR3bqHr|#I8JMQ9+n{2N=}X?5?=-1G8_np;Y4u@d{%bCh?$490(iwCguw7wfloepo z%JI^2-%uKUviy*5vq+M#5%qxJWbq}-`Qv7!zR@}OFg1mlmf3$csZX%?b%w{fEZuQj z3Ov)(aQN_1h-!Z&UFwa^>qb(IVK8k+wLw5tLVcGEgVw;a)u7}=9s8j|%23nW{0$vk zc6S5Eyg%)?(KLL}L^Y)QD{$VnU8J3X65xBRIwrAN4*qThzofY?6Pa znxbu{wllAJMBv5qG$9Is zu3+0H%@_$v=`24o#?q-Rz~xUK_^vwKaH{Iq1HsV;de!P}+r`{M z@=IPA+>L%Y_=Dj7aVAJ7yVA zjw^555@?pHCg{K?KIf9;uF+TX`KN4M6GT2KIX-ma))gvVD;i}#Ty$D)_}xIDOIg~v zl@e~c4GVL=^_B*Sp6)s;7JmQ>wh2%t`|sv`r={}UaP*Kq_0dBs#D?4{g?3G$O zY3QWAMv`l3!=Yt@DXnT#!vQ8bjxy?jC)l1Y3+bn`>|x|C;*PP?Th`QguDV7~NcH~%Lc{3kWo}Yi ze+;ptH%lj}Q11?(U1|2*NkD?rL9Ji}eB0a4e zl)^Ha)UN5`+sQd}y-n&jX)8)2-0xbH4J^!c$+Lf|P=D{R`vT9jw#pK>kJzMwL{>}S zM61ie))$Fes$1563g$i=ufg|4`Ff1Pp4pVdOM;}GHqVR1^W6@f>ksr`mIn#8&{;EW zH!5j6mCgEkUgF-!nr^xN0(S}a5cdTK`}Gxc+6q}H%vE!S&2`eMU&g*4USk&ZtnpH{ z>ike?uKAIsmu5F~vCE1v1+QjJXvz=XOIov3mtOc~uYQ9Dxyyny;1YGwc+fh~r%Hj( zI_p-fPs5JZ#~DV9XgS-M2Clv!mKTXVkt+js9cC44nUCQVMT<+!wghPHZhN2cN8q-_r^-I8P(?(f8N6l-eJ0~VR^|T2%WNS-SX@keZ%)WCDgMX4 zK@V9ohw>{%qcv;H2mxzY3V#FHF>zMPdxo_iAl-YC(&ACQS}E<3U~ zm`O3@OzGm+W|7I6End>g;cfUlB|hgXJ)!+=GO17IS|9W0qnym4vHG))h30i-8oa4f zmN=Cz<2XD@%V;0!#p6ULDZIzK-uqfrF554pHT5PhX3}%sC3>E@(EAtH>Nw|}8H@5v zO*7YNby8{uzc`(CTN3;(_)A!yw@BDlySEjAa~ySO*yswr&Rsg=^D`7GvOsI4YVJ7W zuAgpCSh2f5fEsx#bV5L4L} zG8AKEZ{e_})`gZ%v9i--9>_W~!JcK{(Ai^w=T`p6IA7f5U1-y=E|^4Tv1uM?YiDm0 zxM<&IsV{dxmYZwniJ{f&?X|3e+@dy{M3iIwe3x(SR#|UmgWt)>wiKg@&59;oU!S-(7_;rh^ElyjT4 zOWcAVZo4-Xi8ME?O*ypC%2v>HX;zSaL*l*hUc>5V`dbbwZc~tUD3ZL`rnTKtgWkVo zXW?7VhOGyDGVH$!q%LolllHIFw3XLhsdb}OZKw6n$J~a13r-jbix6j^>l%!UsuHS*2c8VjNH4rl_56!-;=aBOnQeNj;EM?eH!SIBvjQ) zv$t?RYqtNu1ewhHG`y|I&SFe*?}h~lgL@PGM?WlCuieTywesS(RRLN7RI;MTV90ZA z1JdZ(==^-X({nSO9Au|+G;>6%p4^-{8fAj#hqPKKSSV9%(-#e> zmk-eAwg>B8+flc0BUiC(QbW;xZKDg#UueP0$A_F32K(7xh_=fpzjn`()iBPoIm&j} zfGZCqBvu&SU^X7jaJA-s^P6?x$l=L zZ1{9+9!KUtKJB~s3VHF#LQ4(~Pw%p}rgbElZf-|0kq;#UQv4=-vm&iPWNPo;3zAFK$Yyf5{4r_%1C>dBCz7gOx*WP!ndX1A`#PsvVnOy- z^UlFlKX{T8j7yffWo-CbUDB;Wwx!J@`KNtqPk2p!7{#-G=8Wd!|6r&C%Ywv89O>3$mM_G@ljJWvp<2QOyy(m$xAfBFH`}R zz8_v(z;kH|fu36vf*36=wnB3}Ji=P92`Oe2FBDRhVzQql4=3Kv&gAHqX4ql%>9~^9 zR*Kc5%_K(6cg6aNRjTLCl9u+{jxnVxIUQd|`Bxg(^>J%T3J!UHoxI7)eIs4ky@}z27I;&_#He`TBE(Yy8RIP5V~de@d~-9}60JIa)pN&_U8XpC@xLbm(n8 zXN6#k;h>I-yhZvpT8P!f=HRZ?jbV!Id49Tc=t*6gtmN)c@Zyt62QN0#h}XC1;v{NU zX_(bCI+{Sat-e*5NMrZVg*qi!(Hf(#Sa@S6kVqdiPif6a%{x!-C zVvGl82Gnh;OlTte<%KyGYZ#7vQM@&h?U7L$*1&GS!z1NIlZa#8?r4*@R@30vhxC%w zBPykf)0btKuHmb6E+e%pa`==~+sTsEvO%a!>CR9s{oI#;L+zTG@t$?V8@3O}$qGs2 z=)RYUmu!qYPl=~%HI!5h)#Vn1-&c%PtnwQwE|_njF4QI;Z=_PZd1%(LlHn?4hIky^ zhv%uGzh_7B$^%lZTLKt~cchwi3S8DmnsadaooZ=}9U+m#s~e?t0J7=$%J-Z~c5K zP*msM!?1fc65b+0hdbO|48^bcGc*e1H7@PSQ2TKz&(T2elkO2*cn344l{8V8X*MbH z`Nv?WGz*F0IFUzT*paEBwy*O@I}AuG?LVdA?n26P58aN61yGZ}RBWw{Uv#=M#-{Xq zLN|wFuUp1gdQwH6_Op(JIVaQP8*F`bwTGJ~=a^|SKC??%o|Nk0m?t@~vO3m|%U3(= z{Mv}FMLeRn=jMhd+w1T7T?@To;AmAl>yk>hUb$MGtHa0bL;I8G zh0#^42i+YHgmo1;Z=uz)#aq->XMAW#JuPF^sae&r9rWtlCz(qqbXr^lA0FUj?oh7F zi0UiG@ArVa1tv0;`Bx&N-!|0wMyw<{BkR^B1eSW#Fx0PL}@)wtjkCbf28Ez zj6K?X$*&#iGzU+XIyWoEIWO~=D?ZY~X)yj!eSxJ@Vw2mmk&`NEqw_Aab2Z%c))G^+ zTzFN`Zu|iEA)yD^zN_A8b0ptlisZVt#KnDHBwYGxUz_&(jMd@HT(fd#5uJ*X=#A@Q zX&b9L`$a?*GfMa?L= zCNL~mQ*d+Q+?Tl@ZM?Zj^VFHjd|GaD(gE5AB4+k2@hy8}n7)qRp49g)P`omvqd3_h z|Iy`&r*G@wOzUv98d`{;Dn zh1_I#&AexT^SJ$5OQy;*y;3=mE=9le!LMC;ccWEedLD`v+G%sN9=ZKeziPs~BsELO zfL}gy$!xEeY>$Rk+6}O!i}tQgF0VgHk2M~wZ`>hDclPy-h@?J zPdVw)vuj%$`P4GXH)h)JdRv*^B^+HZ-;n*mtz7x7av0;$Iho3b1!93ZoQp}hE)T;+ zSZJ$C9t>@>+<(>AJMCeV1}2oln|Wc)@ZBi0hIkdN!n56ydOMq*zq52b#2?ln*O5zQ z)~GxlKC|MgVpEW`^rr)6_3h%Z5jn4(I%mi0ug^a-7A8NbSu#f?Gb7=`YH>zJ6W{35 z&)XV`FNRq+8)UvSZz^wn^hk_i_AI5$!1HMBTkyi>-6Cyil?+;Ci%j44K{cnO;dz)c z!*MG1eY(NfgYyTQ@)!>1hgZtT&Q+0MjQ=m1&ikJVH~jx(C7h#_?I7VTE6F&41$N2XBJU*Wv?mywWuj_tY&)4gg z+Ugh%NY1q_qE2zQ(G8-F?d5jj_QBYFIiI;fS@gQfPJjFLb^_`kxHKK?+&qUUFl^DD zqeAx$JnDn0T@NT)3t59{Gd6otVnMBrlRF_6Z~V+xUVWG$M7+`xe&JBw@`qKODhqnJ z-5swz|5Xwo(v(VeoT2tlrriY(DxO-4Xn0Zr3sTXT2RaEL|K(lh(3}`;o-o*~wJA{e zvlheGjmCuGh}oCecG+IZrjWM+e#;LUb~iYx#5k*LHXO-F1}crMLF2sL)@wvkX19nY}NxpF0KLD0_gf z`Od5EgiRe3G-HLvv|`-PwvF{|ZjhP~HeE%sHHuE4jo_i*@R&IQI0t z1f^L~K<3UG|Amfzn--oU%%o2)JM zwNU$F>xNs@OG3p#@~}RQ-4yG)ew~kfHu-Q{jNVr;n?J}AasimuSZ(yCb!R};ueIY4 z4w@6vY|dJjTdFFpCL);y1|UdoZeD7?1cf5DlN`lM-4P}#H)veR|Z z<1~p`Ck4E(btwI2nKFZZfTxX27ucUWE{wFBzGXoPfUuiBo!28C&M>`_nOx0X?)=qm z2XT^HBUkhZZRrYkwi&5ZzWK`T_SasZxkt!)D?P>T{X-$n$x|faSlM9GZXjZ8=L(VE zl6MjzV48Iy6Bhh}vnz-1vT!&cH|)olkgU$?gK_DtsCrO z30IBEirGKGOfdUPtL;|6m;3!8`JmT_twD^T(>dRTK%zCXuR?H6!D~ra)scgU!0XxB z?_<3IPR>3t8sI&;ZdJh3k_F9SvRCg7S9BJXiv#d?baLe{(ppROq}-zl|IB{lOBK=4 zgA9K&KyB&!(HPMUX^~Z`=w`EU^A<-Z#yaTz177z_`COJ%Tmdq}_ls^42a{*2K&ch! zJfIR$PvUjUw+$}eAP36s-sp&_us`}^!K!p=-eR-j!!|9&ZSG)c#BH!jD#$Yh&&>@8 zss!@E@}_2GlN&F@9Y?fV5GyS1m9~2-rags>v?OOEtW$THW7_QILRUruW`EK9BQnqu zI|Y{TneP=Y=C#mwpAj#iuM9WVjHbUR7WN0>mlowV2L41czWuTii~8Z-f7z8|wjH({jmFksk2&H*aFJ4*74|-KR>-j#aR*Xz#U!89y&K%O2PH1WPTk*(=xWz1 zfCj2p9(!H{$N;w9QnhtS}zfT#Jwl|c!>;WaUQJLpNqKMg8Spw<#ImpI9W z_+Ti(X5qbf{eb@^JMm&8F>FXM-l-0#b`csn(nX2zXlx(&CtbmRy?Qt%{GAnt$%OKv zr>b6zQ4@nh3h|^y1fhg@?6SVdvhQNWyg-c(lmunfYvp>icIA|8$-_@R zD!w`I_H6ums}Kup4&M3`pL*!4Z9~3n|ElOEN0lpT_IcJ9$jSC-q}GEi0=vSS>GKQh zG5U(4eib5|e%8U?Y%nv|MeC0p5=d%JQ~`*(f#T`MnUl`OwZ07O7Si$c0jHFgpV>#J zHlq~HQ^4;mYlmM;qlIBcJ%6z0EvF8>9V9tBuVpJtq$`p{!^?CsBeAi@=_FAx8FB=>h}>kuQ9hQ}P_xeydc%IK ziWT3>@7HH=NjW6OjPuL`kr#R!f<93mbFNfZ#?9reb8apW&KnlJd9mk9qB8WH zT+0U_?5XK6kKx6uw%cEk-;4`5m47!tY6@RXzY$A)P@e3yA$#1jy{;irLC(@12iANK zJ0~Y(8zYXe`@KIYk2!qn0r6gmj{*1;!ABL}IF;=fc+OZv$4p4miS&nuMe+VG99pjk z{hdr^=#jDbS7QlQvt&v6!2e?b9*EXB}oyLvW=2jy-`kW!| zq{@7~b@qnGAMl!2`=@X9$dZ=xyr-0MT;0ZU$Jc++I?G9lmwqWCdPBkR=^v=gaH5d_ z9Q|n=Pfd-3P~+-_W7<63Qr_u|QdEIW*rLQomzSs?H4JX3zZ}H{JrvQT=lggWdWcpZ za+Z}Yl$?#6>vU?ObUw=*JGf}q`QaPNC2lQiqq{Ru(?a;&wc6V0)a3`6%ccuo2uvxi zJKWJ)uieULoV43zNI@DgL%t)k@rjo976NW>O1FE3ONpO`<Lhr45s#N=byHE0<auZh)!T&k0D+c$|G z?7AqF^BNrI^gHXtLm~Ds1YV;oQ{PYQ+l#XYC*|CYdj|I4?C*7Uv)?RAu~V_VADUo} zR5m{K%~28kaecq*0Fbt}TJ|0K;TCXj&uRU^wHn^TnE}Lqbzq%S>hzm{gN^AoXPajd zG)htIp|ppZ+u>P+eff9D57!4nYM=dY;ru}BVQmv#=EpbYdoEq=uP5@jO=dQEs&$~^ z_$-*(*>{9x+9j++uRE-dCHOWxEu<>90z>)s zXaX@n+p|g2kXYRahYJ>GMUa6+wy;x*?2aQ+Ylh9^*7guuW-4}{T^c;PUom`PTP)>7 zq_kB*1VSyFyEX!M*$g@GWSd^T)P^d_>^`!yX~WD^8e+&U9r+prJa%;R!!2B=JrM;0 z4trgbF1fkz(Px=y36dGCvP(_(=pl^O{N;eaTgDjl$xjd^zNi07zI7-zVH2tN9SUmq z*a;2cDPj6&UX%SI&DK@3k(!yN_YZ>HY6na)UH1}n?Mj)_aW)^33NtI}Q=+t=p&fBE;3s1=l z9Wr(2vE*--2;?TqM0t?3%CfE~3eT6QD^StgWeBViPUN}*+Wn=m?9J*^UfsagnYok9$eY!Vw<)B* za9sGTJ{$VLv$bnUWrxC*GWlSi3tXYWh8>gf9PL*)YyP}!xGgpRS-$G_1X+Vb1b&e+GNHE2Ypl%py^yk<(C7*(vHPS8Pyi=|HZzj||3Mdr^?pl28qNz} zN+&-Z)KDXnII;~pM2h*i6Nx_V^2k#bsYSW*u3kIc&RZ{iC7J}>!0F!`EmMh#M!QFX@+Y(t?3vjPyOsj7WFO9cdvrY51nbO~vY-MFbjM91z(3If5g!WLY%TE{YFdmtBMC8h!eAQ*u5y^ zIuYF5!k?oMDZH0w)36xk8kB(C-R0S9&ya0s{-e0sl~T(R18j`35lyS{fz&tuU`_Em zUi$ug`+_o^GluOaw=nk8TvZi9ZbKrZ%dS~98)j7azJbtr!8Pb-(wMK~&t4l9gV#sI zTGa$T%+bsTonF6>uQo@cfiW1RcfT!#8FiSI8dOE=ZP589f&aj@k&+s$&H5o{ZPD?ZKLv(Og2SS}D)|0s-Qno9Jl4L9HthY+#*Gk3ND2f+Jbj;! z0f>;5dw%8v@R`lgS=b>RXL4!yJYM}+Zfke-Qc2N=`RfX5miy#E50TgQPI1&~rIS&( z0Q&Z}WV7h;cGZ~$Bju(2%R_lik^@2_CZXn48LWR15~t+rJXODw*U~u$ods56Tyd|R zQ1fzyP%;DwFLLJczuBje+o#q&Ot6AExn$!GlL${i2^CXO6E2CA_u#k#!=OO_Pe8{edc9C+EU=>U-yNlEiChe3NuG4@o-^H5|JZ#y zVi#(nbPscQ+qs@>>+zyI0sR&Hwx(sz{0DWofGNQLG%{dzZC~kZSj>;->Cqur6kCU# zlOAsT?m{$D`(W2^bek*2n%a6X3Y z)hq`8e;ZdcT+?fIg{=b35^!04S>@JMKasm1PM+#L=P~rS09|6^L@^CrpK5FV6z7pe z{-7!RPE+-yi^;5nEP?Kd5CGKFsY4F5m6m@E%hfD6qHS)HV>_KdVdpr=IsgD@M%ZASU67JZR|8Q zDOTIXC0UYKAjza4zmg=fYG;sE3|#+0=!;_PvNUTOT>%@VHCH&3!C?dP4ltmA&%L#7 z45KSE<4-;hWeAt6ZGg)-^Z|RQEV?YdD5%d)FtN!|_rVy)t>Iyi>g0OZWpjTSfsA0r zx67)59?PQ@Ph9Iu64^H1Ca;BgpY1ypUxEC*$k832m}c&T5z&3wn&xku-QatA`CXRs zX`XcrRcp(seWedqE0y|1fo0<{qU&lITkcA+DlSq*xA10rbHuY0?g?PCXBN$bl0%!j za$eL3W!d?-2Mjq`tp8>4R;L7V)~$UIn214FAKigv-FSe~r@cw}JpACV_(a3;SU&Q4sybIvg7sG#HmTQXW6Y-M zc3jI<9mUNr-SMZtdBcn|lNvt6A0}U86CIt=G`|Y=g{rezSTRbLAlv%B>7<>tpY?3L zVA#(nTf_?nJ}U2g($BNv7wPPr#l70!E>WOV6XaN8K@CFeuW7jW7sE=Q$8LY> z+&+}LYr6kJG;ciC>v*w7XECSvqO-$5Z&!^1rYeaaXx!F*Su3)>038dduqcJ!YQIEt z6=ilx`MD3qsi57$l|_pyzLrNZMYd|eU4;KDpJ_jhBP4sLNdPh=feCiy41Zd7{qNxy zfVqHpGMx|8fpIyzj2H9nz9I&-qeQg%Nm(&hgGt@gNQ+ z%MzozA3Yu&TD*(Gnh=*vtsUKi1Qm9l8M$`tDtUJHgN{d@NL5^jqtaKR{ytVALcZet z?>bFWSckmanp+{zHbTdAeMcpRYW)8@!ol*vDcBx?YTQEM8X%rC-6z(AIQ<1<8%IKv)D-`)x`kauw<1s(rlEs66fO(7@*cYSf(Q)f+WZ z@LVKFM35XCN|LfI&l%p_v%0tLeEEj%hcBR*OLL6e_CB)V!!OZ}V$YN8Rb2i&3|PoN zSpC9ybiY|NV^r){3h$Nf*Go-K1wfSioZOQOK7~*IIfNUJxx(Lv3IfW2G6TH6l0>@# zkB5LuZ(qd(&unI$?3QgCo?r$TO*f*oJiDq;;rfA3B3Yw?+AYG!J*oV;{?5+9FL3vg z`4?ujV_c^Y#ln=AvVErrF0Xq?#0PRuweVb-w1Li{)1L~$!z`2o{hSVJxX%mRW-2tz zu@Z~@vliRHfHG@^;yjj|ViX%M%orruyI9gfD}4x#i$9 z4)OCs-}eiJ>_s-0NQOa6eZYnbdfN7c6z7qjHM^YEq;dU2&qQYsT|5R~yGVo5+F9>> zL_?{W^(G8PkV<5$eaz^u_d)u#QC69w+w7~tr_WAJPw#rH|MTY~PP-vnUvG>0QVZPo zm-K_YtXc5FyQhpcZoJ?^hX+z6o5V{t3X+-2tm}WZQLgVPWl)-J1Yd zEKoibNSUgR>&&FR%*;~4Z$1468 zWT(&d<(SqL%yCka0<~$Z;F&o%J?r17$0m~W?4`c5m#_(E>P%-4N?2;u~ME}t%LQp}HLXiYDBg($+8!2@$t zz0f!LnpAS6Hv{cOuTR9@U}GU3d2|i84H%*Ko`6?1BXJKd0$4RUUI+kFt5U`q5(b$GG=U+K*sj$GPyQLpp>b2)l+kn^a;jxwxMTiD z%_}W|D@0?cYVj4JS4Wg!$Sl$q?t`4ooe(PNLtnsD!`ldf>&HgH@ zjyem0YKMPQGgb9W%vqWbL!%V;G#E2$?!88k8n25Hp}C}o+l0&i(eDDXpO7w?QWMyK z@FJ5o(c%k_sQ5F<&a-TfSzN-E#^nHP-Q%UrrSvzfJi$OcmW^L1Iyx+vd z7n5r>^V=pSJFXi3%g?ywN_r}eXKY9QRVUWPe%DcN2`WLB<74#!XQK&siS-=`>VOfi z%5tF7_-5N18O5g~_hYZbCFT)ksamK8MGQ;$!n3e;dkAlh+&ma)91dil%(-L#lzcp4 z^0f-%*V;|aycsu;bS(*D;Woc`EZKcm(Tc(eqCXrs$5^2=v!8fO>2TFawDx!9hDsJ6 zeZe>F&I!8`Y&F0$y?2Wbsza}SeX;&6vWXK8U2LpZjPRNY463rb24QecGu5K6j}|JQ zTxuijeaWaUNMt(eQ85wOm04rAqu+fHw9X-_ND1jdZcKJhtz@Y%;x^7=1NOGiXG?{q zo{@hFNqABSi9>oU)gPWA=4UxhL=r-j%&V^}9QGj{hEB(|* z?MEF(n7L@1ZvMd(a3)OQl9Ky_`0#6j@Fh#uJ(HZftcMC*jt9h#AqvY0$EEVY8r!_tGjy2EtYResmBIN*F7aLHrj zEj{IIt{A;+jOZ;pDm#M)aB=(o$)QUn!`uV2EcPe6W)(S6$`(xr(tEw-`5>Fr9yJ#b zKc=zgllWJJ(=W&O^g&!^;!CQxy0SpB;?+DgB(b#~VOrS`AF^yh znuvYN?yKqYcX7e+Z5K$aB#A$_B0PjiJ9~a6d+W9bad5&kAyr~0sE;346F*R=XewCG zVfNrCJ)&(Z#oLrz9QOH^LCgFLQ2g+(Pn_Eq$s^l>`lco<@r4y z+H3Z8^@^ZC$%XgEpR66QV|?PJ-^0eF?>A7&@52QRM<Do3vlt*dGuk z42#<=SypR;0#>%QBxlE0in5wXxUrLsll)rh*6;-q%O|MX@9hO)^ye+#Y%0pumH9nG z3~IW~)@0{iEPz|9Sxu*WHC#K6f7}MIgm+J+ z;|-cer@t9yGP{lRv@;vpi|CiWm3Q3+l4gZ!>EddK@?DFivx4&xaEg-sMo+wdY!Hz;`YTBSMN!B}Dho5DrRmGtB{s>Jo9>w9 z(z=ua7A^TEdlE%;j54=3K{%x&JBbB8O)ycVP0SVVIyt850bj|0Q&jdRaMNoOkiEn= zcnwF75Qr(k=JCce6?mepSdC-7ID4Pyg_bmVMGs5SZAAISm07&x;k&{hcK~0I-*Mp; z&7LbMIe)hjSAe|U#KW*<`-+8Iwx*CZ<%IsjH?fKS?$O-i{j%M zu-?j)bfeodxusqu=k4cjdRhF|%DoY5imJyUc-YwPC?jV1`jFx4b{n86xV;FswInAH zu#j8A6D#alp0cV;%mLwg_O46%i!{UKaZj*}%}s-6E=94YV^x?gU3s_i#XmcFT36@K zr*cK97$Y4#H@BxQxQ?yHr%=;`U&AfSebj#&X4Vb?OluZo_L{jOVlyKMoj**fyCKe{ z*k&U=(Lw$8xKot@fj+zIl!k|eJ&=#WM$_W~;QraW*(vmPJm|suPM7w8-&Ocf;p3#m zFb4#Q{lDyCQR6t6@$&O8evU$hlc4g0?Zi&u_@$g{N7m5;fM+}H7Bi{$E+-m20j^i? zrCikN-*@a}tNcKVUue>3GAsvbv1po89ezbWwCA!?Ws!NL$jp&u_0zf0_X6KWg>x3! zh}mMLe1AB)Pit;CY@+&7CWq)r>93j=hL0f*La(t~LzPlW+do*@HZCGm78o_Rx>t}% zkPC;InUgjF29yVJ|q2VG^VG^gq?iR}*8vU+=?6+#kKSB@hVI9h-=qGL!)7q9E zlp4ir-TteR!mUl~6&IE5O%`se?sEVM37_ta$ZF5N{0kyb1b#@y?V8=hewY@}?Y;@p zpm}!qeSJZ^h}mSbww(5ek=g=j^;h3qf#2Hui&o}`Rr4XTy! zsmC&{SHZ{DZLD?Xa9h&9lG5z8 znPH_~&<;}Wme_k7uyZy4q05s?BBw`+8p2b|U*&8GA1*#TB!#7S1olGGO*6FY;lC?3 z7d8dYJ&bO zhg&4sxBAUttB(W>v8$^M?+`{8RC**_jswF6r+#12tWeSm9F)ELz=M6`qn!psefw&K z@a(Oo`MJQ-^Yc3z+>n*(6q(r$6RvQ#PbFc;QZ3RQg0p!qssGK#Rsmg48PI20)5X_D zMUhXc>PG;&b#u8owXt8NxnDP}3Tdi50Pn>7ENbN9p=H{m=#&2w+JUO{#zTqHRGpF` zF!h)+d5L*wD^)mMUx&YhMQ?HFP5SV;$TcHqaS1%Z16xu<=7!nL4f$G{iuMLiu!Nm- z8$Jwhk|00`chs70P-F>YS4U?ozHVL^tz-h~{;^btr?&i6)-5@MTWaK;N-$qNIA}?h zKR9kJ@?ovN2CN_vs(1SIDmd+$u;D#jiN3tKPxlmM(QN$w#s^t)M5k8CO z7^)VZZY$)u|AeteTDm5myjm2|&sAQsD56YK-yO4ONiIq9G|z0btnV6ghF{=Ay+b^7 zqep-vS3h~JO9~MTFYP5_0(*>>wtYF+F6Y>j-<2>v`E|utL<5tXwVE^6sx*4_Er)jI zm(l~%ZvkJXVKni12@*|jHDxQ7bEJf^u(qgFXFoU%TVed{b@4o01SL^P;q3pD`TZU} zP0i1KRb_HBvDNLqe9chG)^=EaF6n+jq;kVNzYz$!+NyOtvoSZak-8PJCE68is`F~M z=e=FWPp|hZiI#_pAr(iEu>yN9I6I591%1YDheIIDStW~-t_I$l&XEjwkKEqAlAc*_ zZFS7Vk$ppUUE^KO>yy#8JRP)LK3bchba?rWtNIRm2uHya6PF)OMTudGJ9=r6lXlyR zLSMFOPA>>OG!ncal12})TV>uY zx80wwFy9F+$<*Ss#A_WWvZ2y?n`aU7nH9CEDn&W&`rpkjMs#UIRm<}2M*eR1;+v^w zkyVO*&yu`|B$QN{$!8L8p8X<%YsR$D8{UstW0d=Qumcrp+bp+MYSOc+=5aGzkAyq; zdwk57vUFM~RnWzpM)6wo%XuvsQsW>za~G--J{O6O4mf(Jrn%SM~KfcieF=9=Co#UXIXfp`*T?A$u+%?74l!? z<-c4i>D!Cy)9yU5LKHO|l%UrdG795QwC25|VNrA(U>Z!dgDD)YF;N`zJ_!8+h%4@bhu~Lrlzc2Byr z^J@3Q;w0q1$ICqdT@tY;pJABRQQUuplr6Zz^?l>ZuA~ouG2$RHU8a5`1M#UMDA~iQ z*SN=HCZbDam@4R@Re3;d=uo8GoV&Q%3+o*T+`3rG*5t2}!lQnq8GImw0#771-=n6@ z%$gK8H23d3@lzaZSvk_2Ho9p}`R}Je-0)RA!QC0{`c8<6D+8t0-Mpejn02 zYFb~bo<%4FY#2RR5HZ1Yc%Q8CiLUW>XswK4fxHU3GA|2>&myIz zPs=9M7-_%nmn@Z|bq`d*7!M{)cz~PcCeofxJ6h?uASrZ~+`6)~XYR{gy!G%JfbZcv z;&ua&)qjC$k;KUU%|=sfBW;A0<4>bbmrn0ZDJ!c>c)lNv^Tl`RRonghEv38O}oxC5Izu|I&8S%6;S5chSj?CUNep?`d zbQ_t>l~w*q%Eex4t)iw$vUncGz+&6lG)S;WysC)sL>f@FeL*53D<{<~RsGU*=BbEY zJ=EC&(d>H^ug|(@ozXP^_LaP6mrquiZPgl~QdAo58}IB)SaL?RE}JO=y%y~BGt<$+ z(8AHCJqThB_HXK&IzGT$9Ch~ITef$6=M+ay80dF-g&p1t^`HpX6!^4D2?b>r?R7gM;%~;5 ztfnf05id#CQu-2bWy);Ei>>vPffH_-%?0x09h2A;Z~3__^ew32y{KswhZWKO7pWT6 z!y3-ipWf+7Qqq%Z``5PYWD^oacc2_|+j?)^bzrGUwd+j&G4Et4P%~r#xt;STN$6Op zhB;!Oj_awuuH{Xa*Xo2h`zKlW`m>bmAEsusjyn($g&Lk zhE+#d%vy0k_s=yRd#H_7&$E%oQU9B(-E}})8t=u`dk+4p`9wc zrl$S!Hs_YmA#0u*Cba>t1o!4r(scdVKrR5pRDWLMYt3>`2;uUvhSG1#g$3*mq!SgD zG*U;3vWr6mW6K{sFrT#E<)y3eYR#!MOU7D;sgAT|n*6)E`xqKh)BttbVUJ$VGfkrO z)&$(`fBG0Lf)DNV-Q=#%Xso4I;ww}pbPFRYI)~SBgDv*|`TzM4%F{`S{hJnAj`H#t za?)8mXkvl}$I94w%uKP#<6*B?CnIM@L3gMQ0)9mTo*fBjh!?3p!Dh|iZy)!9MWtZN%wrU~I=jSOg zo_B&bq^(D?pn*lMtfl*fhy=w@tOnogtCzD5aSMX z2ZP`t-wxaF@+JTbqHXhXJM0d* zLm@ve1BKEvlCV`|+yr$Wsy#E}LJ>3#St#oa%CYF?yJ9bB> zdm(M>(2;Mmgg5fX!>_lK_^PIv^wjK~Tdguaxu}A}52nsp^dpxA(}JAa8J8l(vBexF z3{+e+M+sy}+jp8Vq5`zORJBEPv&T?3Mb0T=)7ZU4BN#V6Me}@et#M8%A6Q}LD*aUF zC*2Q{3Y0#*+=}-fOn9_Dd+c_4nGvQS|B*k(;lC#3TGa!_nW=#7;rE@5MpWa{lh0`5 zbGxP!sc~!yFmeN36W2#DefaQ1;M*2GkfuC2TkCjCVKG64yq;ERp7-zSHj3t7t@`Kn zBP%lPN^W=MNY%Lt(Af4kp0m{#L+p>Drs?nK8mg!b`3>2|!!3v|>9)j-eDzhTz&;x` zZ|S}^4%RU(Yzpm~-xxiyiqG#m*_Ey&8IB65^4+E^5#)AlMu{+tI^lZ8O8rj4Waa3x zOz{OgLW2#mg77)aiV)Vzw0to(chchpII2~lnXNV^Zf%cm2&X<+;V~WK z;3FFU)||}!ExP7v=?n%dVlR#ig34^ltJ^Q9CPI#ed!|I9J_26f5)ANC<0(YUiJ}p= z9`C9IYHfEHc&vTM^zh$nU;17!FV+OyY2)6jZ0D)l;YP%g4JD3B#!4Kmy}x&Bl6#(W zsk@9rR4reW=ugJDXL@;pG+C3?l>n>9OOq0`-wki(jv;~e2PF_(R_Vc)hRYj~XFNOE z4P70Z44V#nFRtW4GFum0y+HMZ#Qg<>7=4iUsU|R45dr>s<$JV?6g`P4;rtfb-RnEG z*nJ@Lm_hiPfu?LG`1oxf%4hnMy8XL3JVe~Px9ENhhzyRSAQslvIGPmU1cGC>1S=BG z-ARzf2@q^_am;ojX1L%S8;%3oLi8FRH;rh+Im*AL&viSJ4SnqJm#NWFU1j+8Ly)H4 z`Xtce>#bhuFqp95S=litw8p3S;k`Dw?cSZQXA}>NR^yTE3hrBeNlz2QW-tAK;|9rF zUAbM_XGAb8ZBodSww!8Va`jw1JdkVDdR@W|zt6VX;DaeWkJ5Wd-OhejS3c>@QDloD zA~sO#?i_|5(6yzZY=U|YEO)iB@l)--;{|g2!qlSj4Mc)-7TnApI(J}+U^kIjCtO;E z4)olK{XG+*5^JJ2eMneWsq%4}xpLzR2=ba_krhaflp68h414Y}kmAhX>GavQkhJZ| z$%#MY0Fi-beg}-QxGsH@jOX%#$k&n(qWn!YYQFgGO`8x$ixhn0#kn z$}IMBC$`@~=NF$dTXiK0P)~z4O3eG6%^YR3IoEGs5^7Etu0~{~Rxyh|4}h%F-%mag zw%eH2B%-<3uuIV8kwHwG;AUN(@>`zno^kdJoial5S;rdMza@VJR~TEds}0J268(lN z==|?=)=cpDffdzldtui=?#`LmncI~ojl-=CB|+G4iFXiz^VKGg6I(qRyU4-vtkHMq zMA_$aMW#oq5|3bCBWK2^Gm%FuEL6cwLS{q0OxbL?=-znmQm2gXu{7hmRdvhkB+22* z#@zdXRlLFwm6w3$)J`2`OQ6gAy6~|3nB{A9fp2y#2~!Hfgs~ea%#HBx)ICBoZyVS< z!5zDU8d##V>PQ`r&?UaSo)aA@K%udUQ6Uc#uBkmo3CghVDaRg-Yx>`5I>KX)m%XMV zYh(BA(lM8w?B@cVegaw2{hDT+%UxOpP4zN?QcWSlY#FK5PeEf!H%2a5RIahL#3&^? zrPVLf3un~A_RRuF(udYL;=9F;|MG7VGbg`vzv}CT;>r|aFinq%wq-R-e~@zLc22k- z)HZ5Qc)ESPn@~=<0Ht=cN#}Mw9OtjU5utQ$i>NSF^UHbKKgg9xydEkRR^jl*RKH;6 z!JBR~tAqs+?&S((E&nO-fP~qb-->Q}y{x*`*Gf6NgBw!Q0yQmuSGaV*=FyiE?V@9) zymEVTr&#gutdF_oYPM-Pd8L+9H2kDBdH+6Vp>W&&ZLYb7cfE4&%fB^<(R{~{6H|{0 zvTg%5=L%UO*Kke;saLm&f5v&CN@5H5TPoJl*!MuB!Czx`A* zcghmDaqi76%PE1yL@CiQOJH^+EsRNwUDC(ZUM2TEpR!=)XWQDgKX9|@#>>rIQt7Z+ zPuhZGXv&Q%e}Nkta7lw#z!io|mQJGjxe)|Kpz0t^UDK4P0qX~mt4n6~~>K3o)eCSi%U{@?BCBmMeFO4>sQm*cw2-dwZp_cn?7qw@zPLl57^Iy_G zc4ui>+by>}d$@rsW68{hNr zMq4rs9Lhg7n&rzvMr{r8*sS-x5!KA8_ef21n?i{FqX-hP5}|(YCp2`X!qm8NeJ*1w zzG~ez;_ltp0Jkl7gQJ*#kpq34GjWe= z54CFzWpg8+C?M!T2aAba>CxjOE0iT3IM1@~*=I!*nrj3|| zWu0a3f2}u*{Ci@XzQ=8m9?MfJtw2F4+z?)^$Q*{`Ey;@%#?m@P0n8)WH zvRsygSIX5Cdd{>q7x=g_#X2KUIA1Dt+f=7oTWa^`nbW`pKdO&8d@6r;wNc7IAeETz zr!sS1D@&x#WOB?N>NMPrSHCN7dGfQmpWF@8zFp=q#ZRc$BNJzD!T>T_Z2Xu0o>IbW84{PTF(s`}V!P@_s6{TCu^?pzV|Cw78d|*c$(U z@h8Ntb#Bb)M9iz5+t}Maf%Gs~$k&R7j%)sFJYp2=$KD2m!ae82l@oKOj&5nz5m&*c zGIF2ttumtdU`pefvhbsMbUza~v&&He+ti`6F)NFqI5?JUaqIU#;`%FO3A1YDiJQAf z()vIZaMNfb76DVxumHH0D>0<+;a&t!c=bA5wSTjVl#x9w47ikV`2%!4K9u1ul&unr z4MP$SA136#Fk3Y8Y=1cJ(eDSmf^J&QbsPMSkjSEQlYO1O~ zV%{d8WJt{;OS^wu2vJq#q2tss08cbruNMjsFD^gWkNLY=awd7W@O|U4UpwYgTbMs^ zq4jqp0b_5lHD<$nRv#CEhAsuicW-udvE~UwN#!*+a}%g<^GzP>Qc-Ry=># zubV&;z~nF_8ZlyeF5q50a5Jn{MLmR9U6Cd`gxq6tg%|SRoOy6|O$3W0-HBb!z-6UV z8Cw*6%Xd$wH-LSndoaqL;TQ1A>dH}Vm~w{d(To%yGFxbSifv@rRo?8^*^*%t{a9dP z+%C*_eUBPx*xv4I)#uYBcJrdV1vP`UgSRm6#OtR`RbU~L3|s9Ka$Gfj&CJmF&_Mr> z->tqd@CBIuC7Jb`LeuD%JZL07_)BBo(WvJt_S%MZI+I#lc^ET1N<;bmbmqbX2D!oX zOcP);uT#f5W_Z-$z2R*H4HM9O+nuWDWYR{+uf~k$-v4-^THVIf7;wPevmPC*<<(K8 z171B+m(VmQDi`82EQz_?`fr#NbEDRO9+LIjY3nXu{$*9=1^2`DMyM#}r)&K{MSn{B z3tO@?yBf;4<=O^|MY0+;{+Oe6tQ7$dW}B|-WHv2oZdStTN_GloCr!6}1r8Vu@iLca z!#&ZnC$p|PGP$WQH-yx=vC9qkdt-)B!pa?Jefqz+q}DD3oa$nSew?#*+;&u7dE@w2 z#8YVsCif!UNeH&2K3w4v{$84ITHBWu4%#$krLnT;uTj<|Pg@$YG_gG>4r0FV?1z@0dz+Jo*7M({9~k}IAb&0f z->B@l;cyXF+NY85FKICKwG%a0S)=^vx_=Ax%pj3ZA21<$bt$8%^A$vy39DaN=e)bI zHxpq+^-b?^chGLMtl-%!PZL!3!Hbod#xX^dGlD4{J8#du4ogy0*^2mNp;W zcXnti=uR0rY=N{7r4J9u;kGEzT}Bb}zbHC{6crjr0ogTleD_wW#zU&+F>}T}!1@wW zT}q0JADq8R)1AEvXtJy>t@_~cwzqR%$jFmTG#H<*Q6id2TVRO9W`2)U@_TsOf3<*# zT1Wwg&Rul9_7uIlB!sUWp)j)+=&1f1`ZW*p8Fbop7&jLVSpuiyMX#>{EnSwqq909s zQK#n?gA-RXSq+1cST`r!BRr(g_m9K-ty<%w`hS~yj~JC|j}DEEo>@*UGo1J!%pib` z-)_0xIfM7W8X(*}1vGOwvkjoQ3?(qkpB8-5P;C#E^;w>jSVxbn*Ub&zzVxYn?=g9N z+A`6irDn!Gl3aT>KplJEyOaBf=`NCUS-n7Uemf1@_flTcQ*6z+EXZKKL;5FOxNu8_ z&!P0Cn{3Y?f`URTJUDGvg)Jx$(^#M~eR-1qqKk~_IR_2th-aQoZ4xsPTc^klY!h0v z!o&0BJ3C)SSazCv_BEAtZRH?&1!?~Y-%bKJMbKn*Z38mgeNnktHu7rBqsXzRCNE<~ z+F!=#=3>v2BB}c5?O7lZ&f!i!&L9w+`2=_Ezo&uAse}m9O>*OM$H^1Lsy}qFB z7eQT`_4Uzf<3rmSiinZ?TM8<{Xi65Hl@Yn5v0A1C@$D$QJ=EvgfOGP^tlxUxt;enL zb}o_1(!)56f>fy1ds3RD-(YK+o9{+%Xu6JpHEzXp+;(y}(Eihmy#C_+fHwR`CCqpd ztBKd-bl|#s@3>qo#U`6FQh+c43AS05+@-B@R5Wm8^7w7A9NdQ1ga)Ucvv|RY&eqt; ziQr3592LriL4;gOUiMPF#WJQ0^PS9C?b2d>P3On#A>|9R}C7ajK zV=Xl+dK4?=<)jvdB=^{OJhYcf7v4e>1(j@^W$XBaY3mjId+WD*rYJgwz2-QVAELRj z6T@MwMZHYxr>((%*?KwRn+YB>Zp;6VrgQ&iy8r*UQ%1=l6`?I1$W=}`&S8?G6RTX; zMb3vSc&UMq{+Ck0Xwn5YBv7K|cou z=Bl+A+dlG%EU@Tbsuoe`*j~TY((nNmcjYVo)C!N9vUvTi@s!?M?{m@;UtMoE_X%_j zv}dJuY@aKd0n9=a_Y%|ljxIyYZZ-3wSjW?N!* z^5_78-SYjh69-4)g5qJw%DFwxLV3geGCW$SS33d_(;dA}9ZeQ(UvVnR_fT~TbEru` zE~)sfLu6kBH;(uy240n~HGpfDIB3;9^~ijPKILalI0s!GZ@Dc>u zvQ>F^*89e?-dziU+fR=q>4h4Cb~fY9SD$1evaZaYaqfR!8|8?&^_@{*sjO6L$5o+S z&A1d;GvVuHA3y5~9NXy^tau}*s{Ku=H)+DV^Upw`4&mVBts!QbU z6YGqN#&jAASy7o$XXNXg7e;h5mtqG-?`aKg8+U-xHSveOPsXhS$Tb3%2n-aJYHPLnr*5HFwU2p`IqkO)Q!9FXn$_Z7 z#Ko)b9GI7M&KX6<39As;!vcc=8fZ)wC2_hHrjC;=4_O_bYEarx{dq>k>ifZxItLnd zu`264pqcvsfI756Jn@~CX5ibEW<0b^OLw-#_?ndo0DPS0+xi)Nk0<*&O+X*el)U@g2A^-w8qPQ5oi#o#c(WP}Wi8I7K0KDxf*kV9u~-Kq z{$rCcy9u8`K}- zyDeXkx1gy0_U&4{;?U?PGjr-w`NNiBzObq zI{)&0opHZC~GH$c^!A`Z?l?dz^g& z;k^`6t2q8Z?_i+(P z`Ngx3($HG}dJ8|BqX%$r-;kJCg>5R$59;=lYb~+(jmBjq>IJ2lNLLgh2 z)S((^yIoxew%JqE8E|pk^1(3w-l%E?Q5V0RPR@8W4f4TtNhgvWR+?>!JL+;a~i3Y5F^mRxV?<(Gt8Trh3WoQ%o%wxC?|B7>`uWH$1FWu^C*Jx# zgqOgneY!<7T zKMP2>SLs;-+kc%X?9cA&8;52pXo*F~%32D{tREpc_-0D0%9LXDkuyizUdd-zF9i3Q zh2<3f>T}MEg#8{XjF$XiaHOfT8(t@76jS3YGX9Q%ykzHm(OUffvjDa8GvE`f8W%`R z_u5{Dor)r2 zV1zeWkL}_cWQDBOtK9|t@J7W@h0tSDd#sD{TAWa+?~od3_3r!z$xEZx1j7Kr>i(Dx z`t3@gp%H+Nrl2u8@~)%S3|DEQlTR?jb#GZqMg?9y`6y4;;O562`JN}snG7A7q20q% z;Z4qGu;UL@7lv)rBib9jzA*QRZ;JfP#2o(`N)HQvy+0*}7m1Jx?H!d>eN@uDAj>cj zoD!a;yj9YBJHI_8omjE2i35+75mVelm4<=^L~L6_43D*Lju1a^enzSLm7hlJ-qApA zrhtP99(zEU9+NdIxBtj_&wre9*4Tdq7LI~#NB-k;GJEC81tZeis{%jM;MLY0TT{y! zV=5KL-C0eh)ygc5C`B85G10P+9yNvO9HIol>5Do^xqkF|HtY&0M9SAyc8d_#t&;hk zIjks`7|XC;Z8Y+{1414Q+;2_2Kqz~A7G9{%GX2vz#2#OGmkU@alhhvsyjl)m&zD$l z&)ZJ_5!cyy(*>*FKIb*+vk8ZMbF-P$%j0(B*oV5`JK;p#fUED>zX6 z_u|}Zw#BJOm0dQEg?Gf|vjXbU){Go4SnX^CC^h*_!cxsNF> z&gY$0xtS|n{lLxt;YNYA83MfO)|QD17sLs?JHGQHVG^C%lc7!kiZ_ZgSp`X#B^Ne@ z{!vi$_uS~o&Yy1~rpp4XB-AARC6{gZ1M?R`@BU@>hj0t!2R13T#-FiVoxeu{|4Dq7 zs}Q!*5X8FpR~D>ibYersjL7`(r&Vd7_#pMf^q1CDO2g@03PHuYs?}IdF(#`KX;?{) zifjrh$!ErZCQy$nYcS*QtR6+oRrY|1pIKz~_J^=-vBQ!o37_Jc}kP zn^nO~q)mX$GE;_#-uI~6-U90t7GBg1-ahkAKwgq;-2310jIHkH@h@2u$UC+;C2Dca zt(BWaz}-5bT)*e!iT|BSwBg*ruUY~m$TYJS>Yo5j&Y>`y_1n@veXhvcZSPakD+{UK z#lF%^h0H0p3*&D-lSDpreI-8EuT@&GO4FN(F8=eG+t+8l-j%RDN|jk{ha%`q;#No~ zj(jO}M!TI{l4IymQl#Xo-5y98%JcaxYmki0$WqXrBBZKju9k4xB|)vknbz-HLuV>1 zwMA)xX_E>=7)xU|coMa12uWxBGP&s@$Ii`5{>2mcp(E~pbFC)@8nv?^2)Xp8Q$sjd zg^AQM2}$B+PB)Z@zLrioUaoM8{IzUB?wYvP_p^3C-?nj*uJbzI$0S#1&MAMY{=`Zp z!Ss{_vVUI!)63@*gyg_t-NOfTWm( zB#RM95A;p+YMtX6@sWF<#QY2Ul7xqvnVN#DW*RpWHO)Cm&1M2E`{Hp(&abP#4wj25$48M_RY?|1!4!>M5WeRwq6R0=AvvX8(P5G-POSt@6 zCo`j)E~T^AYkOkjn|CZd(c*xRc!BfM5E?R&xYFh!Z5-C$viFi9(Q|L;OwrrF+4^^2 z-VbdnJaX|movT^vrY90jOmLYq`xlM!bZiaWmWzbjO;uIuOfM@Ff<%J@&qKlG@r`{y z#q0z2W6ox1Uk2eepD}J*uJ$i1dLMTTm!cFV=F4MJm-lY`^0PS+I4*q%VAFOJ3%RlB z++6~H?d|Cc%~%1b0?-7RD}!l3_CH4$fZc`FIAR%*^A_DfbBe$smv``0?6)GLZqZVG ztdh?lmqrG_VaFw*`g!+Id(*_ckgby&os^{xGP~Ume5sSDxA5qflHaSG#}0n{`Nq?o zEA#KOqhP;vEdKVcDsicqe`3Ba5k0?c+<&Asc(5F^I}6`j6$daRqtC}=T}(=k{)Owx z-)ehAPPBau--p)~*kFhkY@!Uai_c9P~JlapQlg{byr&m>(SAI?p z*{ll5_1#}muYh#hwhPW3DGl1$A)ij}cZk|(RZUM+R;?>A{1O7wESAS~u#K=tbV&!G zBh>vuJCZWg-GdH^09AhpnIL>#D=oKCY6uGSzcrK@fbZ0x5dJr-*qRaqS#aDi!=wF3 ziJf^Y;1c%PU3Qw_?uGoAfs5aT7cIo#uHQy+U{<0va8gRSaj%!O#WcX$N9JErcVOI0 zKX9SbUXyo*FO5olu6jFW#O#}&OknIy8({1WsWSbqsB0OW%!}br$knP@r+y%CMR4zn z%|MRQ{SOCUNs#2MqlV%)BlJC&a5dV1ufiXK&If5zlVrCLGQnwpN9JRRI}d`eedf3> z$c%Q2CMCDX{Sm@0h^un8-F`)V#J9-`z1W)01)B z%iM8;7`w#ekPm)Qm@)i*3ezukn!*I}5Be!qn-ziw2fU{O*Xb^Sz0=UzwPo)k(Z%k+E)H8AcFruaK`Eaj0dvye&dHqhcP3O9**ecU(DMr%Zf783 z#Z)K6HzmqCeAT6btWY#QN;1vAM97oN*oK{(iuBy-O_ulQl$5^^I#y{I{p+N7GfHzO z2uxQy>Aks_irxLV+HmAeT(=vuFs;eV;WqrfI6C6&p=a#fEX-&-O^rrTaXJr-wf*u# zUFiXdJIG#@e$(IFm)~yho=baGC+&aU^}=RO?v5!>sI$iPg5KYh1hjZW+$P>8bR!`HM=#J?aMn{Ckv)lx(Djc^vbB3Y2RhC zV+0QLN-YC#FG4y7+H(o_M9x`-^pswp&e0W!a*EP1S6qZ+5~lRe>6=0WJ$dDC@VH8&-Q2ee*c22{0^6Mu;%9!PTmDDZPMxK^wP4_zm8>V23~5{f{z{HnF3Qnjm>O;@93U|%d+TO9kv!^%6W?Gr8M(^joQ<7h za)_~h$jcjfpe!t#O>}Td7r8ek^(X9WkS^B~f#pZ5=LC~r0p6_7%ZnW$4|4S@SZO1q z1ZH$S6aSn=O3W_U97xn~*A>7up7`#L+0T`F6LVzUVeysFT2bHKVFnrAx<{USUw~*@Z z(!kHFn>`0nUQxE!JB8qSVo3FuL${dtuU zNAOGXFH-=ZPoFOm1p{7h=LTbN^wMu|yh z0k^DUhn@Xp?4Wy1a=lZdEv&Uw3ykM@_Ju_t1N_}iR5&(DHGOtZzPfYfUUQIEUrrnA zVY-R*Ez4p}k%M{HH?ha(R$N%SH)6i%z+(2-Tu)BG>nHPxiClbCe&PP^BqEV-8mm8r z<)S#y#X5lvJ3)?e7h^XFl!f9{J!YI=FKO%Zi7K{O1OCb?3rYV@y0^S&68?}VULDnn zZ#?8>=k%&2DfoR#bajWk;Di9ir*PA7-AJ%Q&UsxYg7K9paFy(w)52)+5fdw1Yi|)y zRAb@@w0b_S%iT6>ULlp+d-Oft@~Tyg?hWUJ)hb4Fl5Df6s|$MWtxFaM&L1k}3a9vl zWQ-bkWFTZU2#93h!RJakZ22-Z^(Mu*y{)R5dU#biKaNpxE6V7Aa2gEiPCAT**~Ge2 z^`R8WSO0l~greky#JIQAGiPQk;^$O|(zj&%f@^xbjtdL2{tN1lHk1M;Cb|_KkC?d| zx^}AHh?iwlzL&UnepP_zN1GTKPrXEh3m@if^EokcQNw^^S?tSHjH)Cw7$fK5a>M%S zUby7)_wDV?s|n^E{d<9m{2^2U(gv@DP*GqW|88nw52=_moR-A`_qPPRt_5RP&o zzVy#w-sQ}zD+N~|BUPrA75$58#jJv-fTyeYTrc9IT#rbd5!u!&?sMr0aiF(;!J-O9XN2lqKg^A8; zbH=-((SqVJ{bt(KGZuKt2tGgEe*=qpHKxF8CF6_Sh8?qVZ9BmAEM3uXkjD_ECy}(N zAZ6HcGKv{t+62(6J)?BKS#QIQv9k(UNKHlSmsYrN+=f1<#tPz?W`z&GL=yP5J#yMo z>QXrez*ijP1ibUyS!FAU&Xo-IB~#5UypZb#@9Y$2gZdJpVksG%BGnd&fSg+;YUYb% z1!^=kZfMDl0~CbuW08wSLaLWoRkI-j34W0r1)I1M-Tx%%FMhQi#WKSfuk#4l7 zZrrv=F%%jJE^X6akU{v(2zV_a1nvT7##fB*tt1N@hSrDG`UzzkcD}Pd6Fuw8WjJ{b z6f|^A8uy=JXAf=bHgKt<&UK$3XJ=<{ zpT!;|Vun^6HY8uhvIf5`Wqy(@Hxp|#4Dp@P>|&`H{CbQ|M0@Y9Pf)WvCBMJ4M*QlJ zi0PGD%5;aOjy5|0HwgD_F#olIYD#@RuG~Iuxb|8S>Q2@Ex3~j`T0QOLl)q`iS^Yh0 zrgRB0Z$flysg@lXQuG9_L3V&eB9S-Mp`ODXRHxd4XUuom@&F8A*JGf+vQvxN-Z4PA z;IW8Q>j*vhnCPPJ`zPLoR3wMd(daOwccjP$BpNjO)vqTavBq6U>{hy_jwF9|G+z>$4|BlYcoZpBKNa7}Jabj^FYra^ZG2mb7Tb2A!-u z!aUICqPvaj8leVKEdpJ-Bk5=v-u?+u5qusDHb*cok$d8u788jMd9^e~dFd3>r_#C- z+yR8+dtJ7jTZX}dn7(J5#8Yg=S3hAaHsq?H?_?c z?)#Ws{|JTx#GL{!sW&Q2;J4rcMZ`Vm2doKnqdD0k zTQSyEcEPpJWK?Nre#qw_lOM~*I$;lq1T|H=#<6TBr!1Dn@asy2WeATC?@D1x zuLmz9ds#bPDYZILVU;6tAr+b}-4hn-{euY_8k>NeDV_cyEQ~$XRj2;`=|{F$qIyWv zrbOm5%CYGk=@ECR*3`H?UXByf=N-P_(cKWSxfbm)YnNJ?Y$y~sZ8&#|SSp1ylkKZP z*M%*jM8{>w#7GxYB1Ynj-b@AI!=kW9Z1j!c__)tELGXoM8M$lnkp|(v@~+7R@ZtNi zF3H`w_QFjjCVYLcZ$x;A8QiD}<031YxcRw7eWig={Ps>zJMUbKvxe9{nJ# zQtdBLNNZU;0C(;m6-~`~$2|p0-r4$?qu{0Z%6>@f`MLpcDxe+fxJA;7trNUwW8JAY zL6!Et&PXhp@klRql?DIajMr=OK8Mj>2siVnOGUUfA7{BhNfUh@@RsIvM7|Zz3MNRx-w{(3Aa?2m%Q9oE|_7J-V>1Yj&gLb>#j~kceD3y^8Y?KtjqFUQL&R`KNH^jxjHIToY#)sVsavo zhoYT$K!91-@mKFKvTyy`$r+TG`_6XI9#mRQ{Z{GLhC(}&f4UNj4Ucq}MnIQa!)xw+ zF$GYjjDtK}oG8JK8au&1rd{Ud&)y%x|8nr)JO=1N5jd&HRh;w!$-DOr_2qBP%Ac^% zT>KqfL4SJwPdzAS@yznVpFg+dHa?K;&$|^g|7l4Y6$`8G{B=Hoc;Bg?R`+wT;2l`I zYHiK*m)_eABXfAaMpm7w5V8wqz)M`*F)q$znWbBJqXI0px<;<)K=gw$?Asut7@a{U7%97N+6Y z7^nL?*=0V`8agettTPo)tnD`KyWCl>A{HE5dWxq+%DXrcQy-WA^YSB&@2yt7(Iby6 zq`aS+h|or%D824nPc14qMR_>Gy*hPz07=@4I6iacs=CTY zY~zpcVs^%E2Ir`P6JmJOid(x~uXPEp1q}?8{(4m0(`8%Qy(HA1wf}ds-|cgK8@uVV zkX?1^;no>&6~5*N*1`?%4jb?MST}be8+{G&9N*IuYT`|CSo%qIrnIUCx?f1^ntEMG z)Nd9c88#i^3Z%F(l=`|_lHJ19TSv@UPa+v>DB#P8XE0Y>P>pq~6e`+m31>I~_r>W# zIwL>f4`|R}Ly0ESMV#nnIm{)LT(#HL>3fYAY!6ad8k`1*RZN)n!fJ`Ol z{l(Ku2pW+R*gH-?9|HWUlO68jUndib<8zURvb)f1ucO(`MV7{&HrtKl&GXdaT(=5= zS!TJ1t4@7>HJS%&%BUzl=ot%=Eh3~)9ZhT2wpCC?E2o%NSuju{R zdb3x0`C}Nmy1QR=tTD^80!ixQ9&(_U+alPvST5O@0iCm>Q&M%oVM_1%yLMs6!s zRz`H2dV#bil(z1JTmyX>JK|?cGdoOFs-tRLOzfB6>>Ab8GU1&e*MnBnP>sG69uyqq zWFY^%rKv6TR6qI95IS%<#u+hpn(`(TBr}|orT!A$nQyo5yVs{Vj(F8vPTR08MD_(o z)DWpol~qUj8&^PTHvqSbBf~-jD)5uN1|v^D!rU~4?zi0Qd5SZ`e|=x>K#Hm?Jh+JF ze!~I3!pF|o6@8UoT}Y~97A>tASbMD9JFYFoeK58&GCbR+R^9}=DTj)rUjix!=t$)c z+cF$<;maK|y*GjobkGmVsvFQ0<~>^U!z?p7s-=Y1YTkplLB+?P_gR`6SXxl zQm*T-y_D%Hpil}uxlYPqo!1QXj~q$ja;}Sm;=^cm6}U_0z;Jz_H+iegr%Kpx>wWj*D_2vl;ef3>16QZP@k#c7L>Aa)WdFc=CRm0sOLWdFF}b z?EMlyw}pxP2VIj$+}+UL5ifa=Qshds*~PjEHpg>f&~WF~YM8DHv z!EfR3i7owsnb$^~Z>_SrP^pUHK-hgTR&iD-Y4fvF6FBslnvo&gOR}L>b&yvG;kjd) zEBqPTgVuS?woYfti1lsq&ckSiRkf83t+EH=S6I{${Lf{j(yXnpVp@5V7GXaAT^)a_ zVIWUd8W&YRm{pQkl<~UO{{OQ8TVGvSVU5)kBJE=IS+CqsA4)nWG1|#6BI|~i7WYeT z;yb4mAqaEW^~7sp$RmZ+c6`GF-yzQ+Weg0>_8%U0YTS*6Q|1?t9sL`<>oc_T>oQxx zLsK^E0le{)&S^qEIodOoai-FOHN=@a8M@a_Qh+V|HV%ZY7+3;59UZOiV~qQ!H;fO? zOb4!b&#>0k5VyzA$C#J36JgpoG;zIMPtj`Cjs8udH>!T`(ftj?PaLbXjF6|2v1;e9 z)Y5ello4RIJ9TG z6FHIY=Yz#@X#6ZHql>@C-(Yf}{EeO1uj=!KpPo*>(pMskIXv}`K4}bl)!e+li{)d_ zleVo|5GJsiH<)Mn=@ht<|<14nm@daZC-9ue5HG($GrHh-aqRx_)y? zi-~(`y&d(cPXp@jTgupZr?}>3L6Do@W~6cZPO%rCSZt-N1ZyPuUNu>hl`x&_3&K`? z0!%E=f1@v5O;vU_W=K55*Z2Ob ziJAeI3ut%+1HXk_aT@_FjK6-~42OwEy-R(NRdo2JV0TfVEb=yLk@1y3+)s(v&+eya z@=!!qzqpQC*%9(Q{}EE4s{p%ISf>{*)w4ftkkRhF z4U_kJmna=u!H4sC6eh)NCtaC+hg#8)96PUR2E=NZUEf{9GMJof?0$z0&8-QjydGBC zJ@t8g>r@-dd-F0*%7vB(P;}oPrzrX%LaR}G>ryZY8$=ycX<@imKRL_ROi3VRGV7~# zTELuxCkmc$QnS<*o1X?*Ic(ZzSFBd)qT6-f$QCGk^y?V%gf1(1rVJM2)@=*NPSl>- z+4uqbmDnh5_o>=k8=$@o|{Mb^cWob)i)TNNMVZNbr!-l^Am4Vm|yg0MBZXk{95s_=#{R0_iV20bPj z56S~7ZxOc#*6ttv=UlOuDbQj|#d)GH2DdTShhRk-?Zp zDQ-k4wVNDcv_Dd+3Qf6`{l3FDI&j+iGvkQwn-eY*tPhz^+w=0M=i1NADqaf*X+9%| zh$NTkwJ=W&#YnSZ@|ky^`3YSuMvavNB78i@H8}t4WweRjQ$yp^tgX|;FcUbQ3ZhQE z5}yz_yKp3e^RLoX573Ts+b<|R@o~ec_gOGTJl4|<92pe*CgqejNVf zc#o2`4V$GzTVV;zbM&ijGNHI;5{p)LI<|k|-%4{DZ2eENm|~WC__R7^F??uc!y$vW zbV$zro@KU4_a&odnmPMndm=*^dBo4d2rSNm(sNg`UDK_I`W=gIwiUiPKecxPzO1LT z@H6It+IM$8>srL8P-Lrjy`$W4vWSi{!NPk;>MHG=y|Y%u_w9gy8N%Z8CQDKuP33v* z`_t**uu$N{QO55-A6q`A!WSt*{#V90IB<-Koc zoLnq8L3a7r!QUcR=p$5eE5DA9qc9b>hOx1LgXFE@m7rnJQ+naVnfbk7_auwZ;o6lM zIz$(}ogR69mS_@>UCwjG4sBe7ly_?$P$I-OoVs3AYBCC%M~0~*B_drzW`!UD9y`{E zU+sEe$RDw@=SnTI#dxZ*hp(8y!G1r5kC(FT0I~Leow){O54Cz}c~s9owU*SMcu3s& zeMUkfnJ8Slen(f`@J**(CrDrPb#`WMV?21}4j!)L6Xn_UN8vKNxc5OtgoN+ma_86F z4`Sfn662sfHOs8vNt6@WxF_p;x!ZJdQ4`}sVw(AxC~fLp;~9?Fx+FLac1pzS`gQ_r z4eBCoCR(kYhb?;y!+0bMnGPPh&V592Tf6kDkcJE3QQ!J^CQigLYF*sTM6?kNbB9 zDLy;h$x&N^6nWeURCq15**g{Q)DS~1;=c9+CronHrw$1QLhbB+szELL--V82BV2KW zM+&R&_uJFAHzHe`;`G|nV z)c_gddRw;#QBEWf^Ch{N(Tlr3t!Vu!a;5AD*lsIP`M8~T3Jb8Qp3`At!-COWCI2MPw@1zM#!^`R_Wj@;)C`~E3OIJ>`~ zUDIp*k1Eekj~&eo@K>bY95O_=2T5dfh0*;yY}g$W8M`7Z6lW_75wUrIQ;&%~8#qK) z9_;HFCSBsrZ$*5(4`W<`jt5i@VL z<3UgO(;-XcZs*p;3eDNk00OSx za=v2)=A;DX%IZM5ESL+$Mb2v>;xFC~DB1+W=SQ1xZpERJeoED94*I)t)9TD7yRPD! z;f5Eq*|!1$%~a>+Mjl=9h_-J3`P|CDfNQd`HEjHfM23%uYqXB)S-2A8W3D{Ka~;>x z-Pj~sCrCazL}P0LH$Oj>4G@w7EGVpvmfTs6__w=z3=~l(h^J6)zHA+;fO)%Rf=hx! zsLGiVv!l|Ao|epBmH8P$S;ir>SV1(HF4VxzpR&brx|OL$JsW2%WXXG*Bm|~f)9yOd zui(QYb&Rv{$F+BQ`b6oFKwWKm>ld)BqLN?WW2oFWr;re*6`J7K{s#l4=Dll|@NNsW z?sY&_RNFt%UXx~#0myi*JnneAPTgtHkgK8b99=?|?RV5_q?ZPygfBOaq;hN6P5GbF zgyo+)3qce!LKGw;ak_H;o`y03T2KS$24ZRvV=~mbSo-djvB8q0!Lt>Of($s{O$8eh zDXpubGeex5{7&E4Cq!L-Zzq1P+y1qPax6L|igWc&wcaQz=oIIoqGDI~Z2h9v|KEaWaVnCR$p<}uXT29+PCbTZKrC7&H9rA%d+6~Bw&6CP9?FuZ#Ln7eZ zy5HVd6ibL?ESWicNFE1!YXucU90dLLYcD{HzrgC4+SpA8(hOmNRElMALF9h)AS3`D zE6#fg<9F=ND5ggKOfSubP+{?i>FT{ug+Pzl)mZ7`wu2OcZ4t{*be+vL(xr`jFkAQ zIa1oTk=QLr4)Z)Gc+G;%J8UnAg$ne{aL0aCG5pc(kPTVTKee4wq1mdL&qlQS$VKcJ z;UwNOq@O97$EWdmduIGl=Sk|8)fE3H8v-P6(OnMS8EXf(LFXz0?iI&+zWd$M7N$l8 z2#~X}LK~-CM>nC*7TACdO#u!Oz$$r0>7n^MU0}bE*XOhOSv39up9+or(8LhgvPg|x zHU?(7ay3nXuI$F3mQwsfh702<|hnVaS7!P4npk=xI2 z+;nrN=rk`F{oK?ykU!ahL@yL%3~nXa97pU61-5i)SWxqmDljoRX4wG5Tx$p5 zlLPmqR}CkKB9(AuV3Ce=PBZgj`rA!`0T;H_@z(=uJ4I)z)i#WZHUBNn!F=o@dCD3g zsNIW~pKauxiC{dBINS3(yBcLbK8B=RaH|P$vw?i3{v}|xEWZTU*<}di)$}`=Y0T~> z6);bjv0<;F?CU&8*2?FH>rV~ePqTr4i?z~(-{-ox&Fihh%ws6lR~0{8DpuR^5o!5Q z6WDO)TP)u}`lSv#ctJ78Zswh4>iVs(u((U*v4$s%_0Qpe0}sc3N*r%;1qc+%ztXOo z2yvLoSKdq13`j7}bjHgU>lEx;6|@iKHU8OpCllw2D$;vouyftd*ngo|ImBYG_wY8C zTy=@O>#4M=?GjpBYSLO^RM@gq`(*e??Vq!0oz7aP5(MwDJuX68Wrd%`V^bW%7V<=BOhPBNbh<#ujo$(OY98QX%u&(xus6u)i_ew^ z?2=rGjc?DHw}26)4v9@>Fy*iFKZC9cdNhvw*#z58wF-X;tSh@MHrIOgq_MCxFZ3oc zh#7Vs@9tFmpjRn`n**CYs7hK7Ti9&O{Gj~HOlkYRix~gES&Kqr;7(CezJpW z#Ja+kyRKaUd~k(_=!4@-`&0X0)zy!eOrGeneA&9FFmgu%63TAJ<%H#G+i%lJ|UZRYhD_)_RayX41v*TTR5Yf>ymco-xk52cec5TcNY^s&+73LIP zi`;QkC}Aad4L5}}3R*}@wA{F7$c&gAN50a;Ne*3tGz3pZJA1yOOl@iyG6&e3o3}!r zbGzZ?Euw{O>!l*|YJv0fbRCgdxO!4cjk_IhmmyTdfL3a zLTZ^q1w5CnKPVx%W4m4}EAjGq#^Pd83)i}KzjotykVlR2EzJfeYES!Se!wJ+n9k{d zDO@X&_nJM8OMT{gLU(+GcO`7|Hxu9Foz@uuWTF`r|%w|p!dXQJfIczs1RKQ-$y zc4qso4Odt4L3GOqG1>5F#|FF6Xiy^7Cdu_QD zPAe2Dv0Iq=(3MfEM6@Ncm4QLf3`R^@8aAO@5;vHAm>)+h(UvY0pADrHz0eectgO`* zdu_Re8aim7X?1X8jr%sMO`R0Pj;L=4im?Y!O2VWHhZ<8TJu?6>b9vmqBVbQi=03=T zW35Dqo{SuwTeu|!oR!PQ+1|^1pcZ;!tfduKe5@#cU-=Pl=I^G7B3(h-r{@VvN#I`9 z@p^k+cdOb*lc7>@Q9HBBxOIF|R`$<*Wntd{;*;viD|DA12HQknJF6;jBe-ewp5{#G zO>S)F(L3ro^;ofdyn(*^K@dB3$8^{D0DC32-weA?GU2qp;(m^$Fga`_o6_xiq$^oA zHELK3q78FamEX8%S zqCB*o7qe7j9mo$EaIxZ?4<_~pUigqFO+SZVMMw6&zt{UTbgp?Eit)?;&rftb(%*CM z<20(^VsXxn!JCPn&N`yBwyIm}2c{}nWT&QniEm2Du@aAFJQXW4%DZ+$z<>42yFw`A zmwKndO??R0NANmfeGz#10`T{cbL^=rd!eW8u5y$<|9&@c6o!A9HC&X^SqMEbOS#(| zpZ_`T!!gR$A-Ch&EFxsln$)RjWfP-+Swh(d?8f{zwJVOl+aU5SXemF>(j_Q~Dbb-PbokoXz1n7{%0Qm3?VJ1Ry#o1{9* z1x~Rg^-XHB$|d~w(J`1G+4km|%e~OE^33ZptzKZ_)zrkr4b#hbg&3`gho>mLi+=-2 zf@AL^DYiGOuT4Fse$(`#d*&JMiOW?poasVz$c=7yDT#oujFbMs!~OBX5dND2@VO%@ z0_B~u%ceIZKZtQ`b+i`>R=1E5VXS$asOss%Lc!hWoxZF315<=KsZ66(g&(N}7tp() zV~EbGRbA6UMNH!4xdiI`jdxp+d?#$mg$mGCitAkQ^>kxNP&NqeIfYmpnDwg;lQe9q zjxi+vH%-CcDmK+encB-nebsI(y5n4!B%^)M)OKtKLF%ls7|)9+p7q?on|pEles89X zR!BN39mw5wT9)(q=!ZpUvEBN9uBvjUH1CR1frY9F;I-B2rdB~#8?H&R!*pF=9u~pN zfhxzJ8h@6{P0K&w4K_;J{|ZT|F@mUlC*+~TL+=JH=Iw%4 z-Qn%sa`$=r{7|pMDK@U0ZiEVw%Lnc2?9wH-;L=FUHwiLlXV;U@U!X8Y5Z(ty7KEH9 z&Y|fm4oi=EN?YXihO;a(elDMi{B}I*_sN;HJ#cop>X%mTi?d9T`M&#_Qh5%#WU-wH;23eG*G$Ox=F#M{?H)g7!_wjx?DDAldZ}oBdb%it-32^l)Br3E;si-76L2c>N;UCw_3a^hQ zvd={IUQH#8Zv3xYN}0>teT>Kb#4Q@G*zZ8MBrr~6{YdZG9`4_H6M)@>)$2h?Lz|~N z>uT6{GB+IP$aGz-n!vxFuh1Vo(DAy5Rq4I`>B=^#6~$HszL7$e2r6 zSC_;#W~&rkTuwQsRBlmJuCrWsaVwWxMk?i6sdRBoa=(R*!V;PLFgDCEbJ@(c?>;|# z|A^Q7{klA#&&TQ$T_wWUOL*e*8$lEPCMa#2pjG62Y2J!HLT#Ku;%w<0awkx~l zo+~4~e{G)o-(G1|{`+ zS;pZKXWcA(^~q-xQ2S~1y+e;1dM$T^E-NQmWsMQT($w`p2d=nJ{2IQ=HhQI|qqT{ z|GY*Ejp7IP7#L6^uABj)dQbP7Z5Ac8!+RYSt({BfdSxV%M5iokj&XwXPy1ZfW@~Ej zEZu|N<$1mKQQkV~AS_NwIHJQR`37$7)kKu%UH|$;=HBC*KJzcz5?I2vzOey6%vs0i zan<93`F=5MXzIX0;XJmG&le>y32U38Z2$)~3tlbSf%m~z3dAnM95H!1Kj?PYiDJg{ zwgy~YhG1%Wl@qpwEM1A&W;L(!93>WS%*2;r_U5sVF8+0#DG>18@Xf7cPL`-u@N1Q_ zyNT%@4j0x&MdGt0eGA;y7VAh5x3JtwBd+{uf6CP4F`+LHV&X@ZY2{l08NTnH~n z_?9J+HNYhLxj2;tF26T3Mo7h5%#IoD^vE)*BmcRSkLjMC!@2*keXJO}u|ya~31}9{0*0@HYCa9p{nAX6t*=YnmFTqU9z00`*k=jw4`JE%c}8 zU63&7il+20dfb`X=^-mE=U`3pT#p}BCax`PPjXDoKQs*%MSJ?e0rd`x5)H7vj_q`f z`fL{EN;53DPvPZ8RzyI8QO%69{&n;->rdUq{F{Q{Bit0h;j<8Z>#Ku37q1=xu z8feQFJ=gll)yj6b>Q1|c2ce3ogo6ZS;YCuTOoIzM`ftF*?aY=jO9I>HWAwNQd~)!2 z&3CTDy%g}mK@~%=JrH%AVkL?#hL?MVMIT#jH#5VBzv@pj;<_cfLWKM($p>TV`UBk5 z80&oROzUo!)qN2aUy}6!RPHjf>&RSjk4s5kT{_{EqnC{~sTYeTPekW`5696jj6+ou z6GH~VMtrZxyOXL_-M@$X&ie}|KRa5v3>j5*aXiHakrs3kt*G}Rs*p5^J-h?=;dSaT z*Tl?$(C;IhXYl@A-UropyX>)#e-b2W8I=<%5`x{_rzht)q?!CNOC$XBkWVgtQU~;& z=0V)&%Ns3vwDV`bP)YTYCi4Ha0L|e~rVPqzWo*`NUjsFt0yBmo&N8{`zH2WBol$D+ zV%%!hJ3kK8YV!mJjhBW^vBco{9a=u6_2eTLMp;>m#W>c#JE-4L_vC+ux9!XM2NJrg zcBIcWN6}#M%a?A|s0gWvGQ+5Hzg<^&ULIMd5sd_KK5(0dDCGTUmZGj{G5PP^YlS2$5u#k+=(HBo<9t1IpdyO@?r0s9(T>84HtR~Od*tUJ z*Cq@^X3@F5kaI!*k>!x2SK33nr%NLP+DZ zKWJgp7L#3E{AyN$OStJoF-_)EYV?&dE5yV0+Gv=Vs)$+qrcrM&1?64N zcBKv+dZBnc7U6%wG9Fu^wM=wK8OUtr4Nsx{FNZG9=v;4%h&!{HfB%5X;C*-(VRrhM z687nEop0e+MS2RsZM)^W5~KYM?D5S(KR>YI!bi+UjA1Yg!cwE%BJT=X)UF?dPFUF% zu6+y2{WM;1v{xNjduuuxP_TK{lb=m+DAueQZdr>^j=6xj@u1ZzjD$@8>x0dw_@puB zn!@bd5%k#g?B%hqmA3pPb-X`xwyMhN?4I6@JLKtzSeqJ>WWH@W0B&OO{aKpz@ zbj?f>oCs5U{IG#+=D3@UDKH@x&GO|>(l}dlcK(KA#9}X{?+6>gQ#f6fCbuzA@|eJ? zI6&;grL_+hQcQY)yqFE2c59z27Q9ej4Mbit4?Mi}>x^Cn z`W#_z^FYGHAL$|b+dGxyt=4|Vfyl~p)RQ^^Kb|;qJ|!DM9)MD$WPEeAw>%_u{$M3k zK*c{zL-{8WF^xMs*3Rs1{pLtq@N~%M_U3n*IVw#T*+rsQA=3(eYa#Sb_q2<`QgK0~ zkZVgF1=5uDoIxdT2`sl0TN9sLJ7^MT5+rsM z-4Wfl;{@qQXk>{4xONa~X-G!`Bo0e;#d1w(gE|yhl zWTs<%mrM|7je7f7o?V~1uHWiD&p~(v<7P~iw{rK;^koY~`QQhi_aR;nwNut|DujzO zUwdn9QeUCdv%LiI(+wI$-VBX#;rscU?a|4K^O45hwA@fc`$F!_bfMP-8Q|k9^>Z*H zLv(gx;aap8g{hmj`4VJ0#ISLUO^9avRow|7ML2ZQhSYOauv@cVa8$eU;5`qNcc*k# zkhrZiR{|Kov2}Z8c*TC{{8ZoPeZCz7J(rC=^HKD(MngEeBe0ePUbb}u!F2cek4KbE zQ0>2q4tj@_a}UHNE4qi$2em;Ku=cw1R9TX(A=(^tHh7WblADX<1Eu!r27o*o81sQ~ z@^zcxvzby;vbt8*ZPzVr-JW8UB?U%<3p3K@(;1S`*I=o z9(u}|CA-qwgh4-X{hXOSUbM?g2usnzav1KK+X|i}-IMc$T_%Y%i@LP3UZ(7{P-D~G z0UMI8uyQZ&FSL4@oGM({yaAer2)|`COA2)m!h*1KQ#0zOdOrUAVZb3&ub?>{V%&7X z_vwo!$JJ2YTC1aICuRLh6y9ySx$SNFi*=1xPJ*z4mQQ-(D8if9o{GwSOvI9`Yu&@X)=lcphFs0A#2C;K4?bLvc}kM*nk)pH;yXDT4y- z&M)V{?{){KO8RMzW!Q4xo5S2w$l_l_0pk|A^1*Bw%y&s#ZO0iqlR@MoD|5N$tO9pr zPSG2FG$jF=F}lduo(~Sm>v#R4yb9oRZay=*MJGV`^54rm$C9nWU!%PA-5Q-I#|W8k zesvng;s%M;ESafgBD!h*aYp1ni?Grl-dw?u230_8mTkGfHt1kr>t3{h1D#?+@+A!M`rZVCl({(`bptbeHgf`ZhM-oX^CDljoqhAjGXf^-1v3y+nP&~nuc1I zg zWra_Xb7YU)$^Zx(_a`WIYEP_KQPzDpEYWsY+;Z~DxHNW{S|)hJjI74;3cxQJxSVV+ zsb)bqoZaVB4Ktc6X`~UR8~*tXv3)3`+0a5)PVnu68>^J}io|`an9q~K2T6;X1vJCk&))}vOb#kVbi2n?kx02+#{`p& zAI^*y%eJWSW{{Y@=rk*%PO?oY4+9L+bxO#e@j2I<;lkQ?LZBGMfYfTDgYtkSwyAza zAQDci{MHiJG0NH&9|6(1z3QAvCa%t`EKQ66knaTZ;nlFt%nWXZzRv294yFVSdt5N z_gX?uTM;x=nJ@C#2x_)7Sydt-T!|?~gI%^m(1tegzIpoLezxdu*AJ>cFEm=><@IZ5 z7Qj=hhZD3-EU78Du?uNdS32<)M{0f6P{bU3(uU^ z`Orxi$GFG-U`M3~mG#)`KDU*9?xL10|K~mJmmi!H9_Fe9#%fv$_qk$>oxUp3C&#+<>A7S$b|2BN z`|3VNAtdhn z%A!>xZos#cnHkj=(#WVUrgAI{nMtKLb>Mo%^@`bZnv`P464^mu|8KUP_Rwb;sxJuH=Oz%Zs;$ZivOjp z{tGqWpX>VQrL$iMbJBWIT1(-fpATN(1jvO2`A_H)OGk7jZ`q+~`o|py{Fn$;nz<8my(IXn^tYJv#gR!W@i{6nq??xJt$*$?4xChe$neq% zvOjai`;KvudW4DFgE+=xc-XPuzA?0yw1l+qsEq>!Z4ET5C?#ya)KPndUZgSIXfOfu zmEk0av#nOL$PHRVqy0RK67{FLm(5VnmfIsa5pKtVETV!IQam@z4!G0O&pEhJ96+Hk zrCjVWlx#!kq;;ol=UuHHN!ye^U`QzD=a5-W-OTrpsFfhq(sTEZM_dr>@Hy!4 zTH5QGwlDD5H_y45J6<1U`mrf}d81Or;h5}$VvEP4-(cHdnI3Ljcz%5Tkl3H0a{J*I zS^&6+TOVZa<>bp>$yvUz(xh!d+bkTL(cR1?F2mN_!a#A1V*UNdVB$BJ(afK)v?8Sf zAa@^ji5PFl8E!$%a?}s9^y$mPuair zPHh-woyyf`WG^f|##YzxW9_tcIW6Xaz@dq~E>V~E#qEI!MolD89!q?B{4m5+PEX_0 zU(F-*+}uGUZ#lxV@hEGVuQ%k~dDF+-fsf0RciV9(b--lZ=F85qK^j?bSHuDq|9gYo3_D}Kn&Uf}dJ9B3SGP|6w_F0@$4yFt^n>$XNl8{wu1iIrt`~HQm+r$vg+M#7H z2Z*v#&qH3qgxRIddkkp3X(#t?y|he=^6SmhR+Y%0-(5U#+iuSTvZ*oHqsz~psE~5BR4Afyv#`~tTzuc%pl1u`CnM6V9Thbaj?gP`D^8@E)v+<#|@_HvF3!Cxl%-#o*VK= zU-0VeFni))cU<%yFf8n2c9(9#o}3TOKmUS%xDNQJQM(>d!B(`7cmnj9{~8CF``v{E7G->0qMw#pN7n93! zb9GdV?Q?2iiqrbxX_Y(L1$zS5Qmp}m+=#7fcb=q~;JjE{)2Sv)nUSmFF4jop&Tyj1 zPkr;!97M%(2Ubw&Z8nv0IRKSH9AKR(M%fA`JKi3fbV!LHYOs@>NRCvW(mH1*EW7RS zeyuKc*(BIqrHI^DQwU{c-4|Q;e+~S|ybI%DIC;{Q?iWZ@c{6=Aw9(UdVX3aa)!n$p zg{ldTa>Ac0yTfuif9wGzoT7;eatNa4Df?|M z(zioXsbE{4v%HHpb7oOHC+OtW{u2*;H($z7Y8AZ;?!^J>W$nx(4<)E1)d@mUO7Ou? zr4xEQmP1-Vq@}C_6|DnE$V2Suee(}AJ^ZH6zL@|fx5q3-w7_c9v^gEd@L;9yjVXqu zR>@v=E)GPiqKiX}h;pBR`(0YORZIM%o6$?mA=N^YhojclS8jmnRE^>*pwl$0g0G`T z-*}{(gSPbg?&$@3apwpGZ=uwB9o^m4pAM}oX zbl94Y;`B%}aOykJ9@Kv5vinSS0)HSUio21_=e}f0_kEpWdF|9)D0q3~ru%kKW&Gr= zOz4^KbBzXts`@j)BsFEj=@C{Wjk*zA5@ADXuI(a=VL#^WB+=cH#t?~^V}mmOk$5H1?3z-pC((arsoR!s81-UpuncUDz+?DeHZRYJyvb&V-s(n zLL{n?qUOT~LvK-Dx9+=j-j?7Vpfiy&+hMB-?|QI2)t*1NaiL_j+u1JkTl8YSvE0$H zh?)}CRtWH|Qx*^e^TE+8DC1*6YL-=fzaWBti-hf3T&{&twy4svp_ICItdwcZIlGZC zvph@%@+KObL|H<52yUd{XYv9BZaf^P&3HVH_gQo)#NhjtjlNmoCzl_qi-csVMGbzk z?%Z&N_g})DiF5qbvf9!z;Z}$?@Qu&sH7+8;Ynmd8Wo}&o)gj(QD_7X?39g&%@PNrD z$}cmFeNU(HpkGu|y32`@Nwf01BZ3wWNam(ObA;$T8eS*$Qi@x4oCCDJbhQ1#mG%dw zKg%X~XQ5}6JX80#sv|4Vsr!T2vG);;Ev@SB(V96}!QV<+Zq4$SLsQbHq^`3TpD4=# zw+Cf!+SzzcV&C3Sh?c{jhbPVX*eT(HKAL7H8-8z4&)8~hwYtTz11fwNYX_-v$S=3G zRgHH&@J%h`_1$8~e9|nW_JHihS8$wrQxb<627_r?_G>9Ts|u z4nrjTZ5#EnPw^Ua4rRbD8^)5+U2JTO0$m8yE6U9zTq)?)PryD(ho>}BRMf{O)N$H@ zX(p?`f0F9feETG#@RM?cUm| z3L284W=Fm()oxlanC%jh8$4vkFWS8a`#9sBU)?nwjMgEoThtxrVU9;1!a5Y9n7O>U zd6CT$S~1_M)7GxJ22&tVFA^UM7d+L;2uI`=uD9`oc3P(GXhwr+Kz?BZVTxTFI{CXJ zBe2xsdy^9wkfUN^kfo0we9DHY6p3=bRgTO>*4{%!oZ-u?HFS3AEM-T=c=A0SO=z}9 zt4H4UIfvErya-F2%J~+8rG2#5`Ex+}o{&4WLU)Lb#5igjM_^1X{6Le_BWQ5hz`+~K zI`i8X68Fj@a(n@M-5B3rfMT;-jF0YqTLGz)iD3u0K{mjiyAE!d z?a8)h3>^LVTG~H8mzXBaZEtM*Y;&1g%TePY0wxIKy1cfh8I{1i@q;vv6o{HijkYwI zNM$G>_+wEno}%c^$f}4`Xc}9-L6vSvZcy&clHKwcKhPWa;04Gb*=MHb2?gI8f}^l) zI#lrgKHjjJ;MEB;u~SsXtxjg-DE8G`j>o~?xmsH*++HICB^yu7zl2O76Clom8p5qg z&v(+3&gN&1h0yl&4wbaF+Eg3V&atAli(T=9@R_#`k7Cs8(`d^fX6y|a0}}$eg8O|> z2sGEa7N(ItC0pq`MMO4S?W;GlQaUp(hr0Sa2O>4EpCf+pX1*nOwG*7tH++?wgr9s2 z`zjHkMdq3JaK@73Gby-bebD_0S0#LS1Ld~<26OJ_{k9IeNn1ey;G&(oZEV2n9e!mV zpUFV53nJv~T*}}H9m_3dg%$t`Er}rB^h{i-Hl)ogh5LD8G##cre>~K2v_PeFG^$l6Vj_GHGDfvbGP(# zMcB-k`UMi7LqwBY$fiN{;DxKE=h9BR$m4SI`$kS#gqO2!Zy7vlb0IoG$XiuiNzdwk zS}Rrk(um@F!APj zy4|Gu;DsjGY~YUpt=G&;k}DT*dvi;q>#cV@;AypzBlUAE>&DWw(!;sn5U|P0lm4(JSWX9XJ(T9N9Xy>GD8VKf?DF>B9EdWPa6??~&~Zxh_Rb zZ+*+$8_dObeU>#+zpAQZ-cm3}Pxfjj(SeJ3L$BgMKt#nz$`iyQX`Aa{XtGi_&hTuu zoBr4R!>Z#8RtMwlp#~%3TqCw>^oGkT_q)mgjBK20iHEE@JXA(Dy?@b+nQ^tXRUXK)UpG|J#5^@qAs|NEmN03 zCjV{CxJ%?SJI7{eFaITQ+OgLsK5{wk4HNIuneU0>NEqhUdn8!2Y83dAJKY=zx6=!8 z!PLUFfxEpr6kC{+YbqnY`|}{jnjjQy>WvjE-jDM(2n%ty7kx0(D2qdhCv15P9gR*$ z&G{UZ2_!*ZwjrvMz#fs^?`i5HH*~BD!N`kc_RMGCFDd;yVC}GLg5+~Z(;w)L1Xt?h zR=b%+ZPC~())(}}Ng%6#Y{MfaB`56R%4pWX5az29GcB<4sY&B5D)ZRTv_{fCO=D+% z{pLLQul73_=kV=UrGNVpB7&3texP2G>bUf-02QYl+2NXI3I7l@onI;3p8}Ub)_7L- z6VHIEc78p7)4gc|NGhD}l#W+F)k%O%+8?<5)9I~ytaD$JG{wcaL z4kW6r4pvI>Yl2VfYj0}P*nb_5LuAU(ORA3odkIi;&_xyUzEAC&SRk0;RiS}HL|--x z{#~WPfBE&#V68UjVY@>^$S)+9w1a;KSHOW?FhwajeCw^fBNd@dLaERHi`k$VlmEjUNb zoP+m@-Q99C`V**47W*saT3`7%kTd4X&R`VFxqHsO(M^;3e=UH;IfVtE{3UKLGId1$ zULAJTL)j5?)~7O_Hm{!rxPnbdgoZ5kCxH4$;pF?kW{biN+zDTGBwD*4?H^cLsmuso z)c`ZZ(~Ypw9C2>D5kE518seFx&mEfa9>6OUtf+b}b%ks=#8yCFaFX<>&1n#h^>1o( zPYY2N>(=h#tSv9TPa-=zv_Y_4pKlAe@G=KPaQW0M@gHHzWJLM{yeD^7?+lQ4fqmJP zIGLjs)$RGnqrhR6MX&%PD@JC-+~HYcrW_J|0$ zw*AkG0}4Ry?~e2l0MG78jq=w)Uto87UX{*5oTKNgyn~y~qgKGBl)B2y<>KpD$$OVy zGLBILa9|0LKSOp~O|ZW0+uZQa_xPc#0}-c%Ps$ogse%L!c!y{rq|qAj-)m?X@zn!N zBV|4-KO7}0hDdOqo)+GUMki!_Y9-Z>rz&=?{NNce9QU~uK#sz{??gJeJ%?d`kX$Kb z{{3qA+;HJ1d709`ZWEOSP*%?l+|}ELzLXPICs)0HQZa%MTv(cPLFpt${v+FgHxVBe z#lY(6x-W1)U#BZ3VO8|p&vo83xq5isH?=>Gd8X7?B$~oLc{sj@8Tsd7d(}4|zxCA} z(*NFk7$G;1rYsR|{@7w4sa3N&keFG?xJXY)zj+Dmdukx>!=Vd0)RA^re(!MhLFN}F z!%4d0kx(z|CQOo(U zpfZ?&k;Pt~XEMxpiZRA^e%fZ%4I>ze=o3FP*WrMvcl-a;-f3?t8-=Pr%g8Ijt({rK zyFO8F)sXIY)9ED!={r4w1&&FWNBPknIfzcXE09}vH88)FhT%S$M+V5un5<#J1oR)y zAIxsXWpqtJPpuvi{fntmzbBXcUop+>?*U0O2&0maG1FyvH(;SlnrQLDG(OcWDs;7P zlMYl^-^)ps%<-oj9-cl9swkFa_N(!A**5_{8>LXfU)eZ`)qJZeM0#PsKyZueVxKM8 z^t;tFwc}4Kc$Zm`(4sUh*u9xVie&BF6BNgyjkvnKjo*yS8O@hC_fcQV{L~QlQ|eyO zILQ*bQLox=)){aIdg(JkDj{erbZkerv>N=#=;NpUqaJ%>WXKj<>l#tnqJwIft&c^b z;*zEC!G18IP#u#&fkt@d?^k8se2@c9z_ZZj7#6i=4dW|$VYQGG>(e;BA}N^}vL0U!`ga;mP^%dkZoMUmp5ulpDtLYDy9E$k z2s8kEh;EOJleSj6m?{6z?(OU%d|Jjf#RZ!q?Q=&Q`cKIxde;#4k7>PYYRr$`$jGUf`mMfB`cu%+vJLfjVkEY5w zlfj9`Zk=sUFD&Whnon)7To-THg#S_20qz)A5vib|G;n(mK17$D&(RY>js6wQFx)8w z-U@T8rr;aiO9{DN0w`$ev9D~MVw`!jEHPQlqO!*|QH3k>vebhs&S!K1b!H{M0)HbJ z@>H&PePBJI&V%4rLvVk{O{LXQqkl&Q7FWMEt+|fVe&o{1A)a&E%9Ate5dICCk!XRr z^`n8ky3ZZ$8pU6Br69Q*`}E0bwkzw8@q-DlMm+(l8?n_kxN#elZg#l%0;~Dv__BW3YKX zjjblnNZCWy-KTvM8|^+KP-fmFoTMZn`V5tzNjpYvpShpfe$lLezCaGwrky^zqE11% zNpnArb3R1BGP3B>|Ig8~j&VS-=V7+f(7ZeVVVw3})@kL+gG8dMdQw%Y{cp1&=e^|` zfI9y~7g}!?$5lJ_;);bn#SFZ5HossWHwn4AHI%jB4dP2+(q^EW;RZo&@{Hv7bQuP0 zoS|Z+qK(ZD^bpPmvyx4MTgWmdXIPIi3lAWnCd&P5Ugnsm>l$zrTFhmCvpwa_bG*VRns!7gI7^1y^QC zsY7L4VyhSu_G5x@v9GnlULKQ=GW%y+hSf2Vou%$|s18nCF?E0EdyPYFJF4={h2HqivM%Z~vX#^b1oj@~@(7+(|0SJC!vqF_tD@!D< z!9cb&pC-g=hN<_&6ZlFFdLx`*mT)C^j9y?8Ld4{T3s&;h9kdj{J84NsRuPY7Dh}cI zwr99Bd{WGUMqC^u;D7dSgXt$;Bf|nEa!Kj(&vGQxK24t=k+(3R)Io~WXTtoGQhRz5 zbJR^_yPI0iLCVnR3^CRbSRP&ICgDEGgP_4|P0!g4~&MOHCD2%l*`o=x+s* z+ek&4{E$QUI6ejjTC9fT?(CCKn(jtFni&YoV2=XS7sB$2R2b)8Z_PY3j02NvBlI_% z`5s<|R$EHpe>S#W>rZc;#+(|j)v`+LDC-SOr_PECF$sCh=rBi0Sk35{aNqimcVaDP zWpgzMH;Sw)6|qgrmyt`U9k&D7ufFHU&beHLt?ir&kFThDfqS!Ha!W%2XL!s2KlgN{TRD^)>g4wNvz3!+8x| zI!(rq@)jpUF_9o+j7uOx2cWhuZTV^TrSM08$tt27mFV(-xW$0STP)rBUcNbyA+aRz zasr{AwKXl0DptB8juV0hPXV$RncG~8=J{L42WCC)EVU3ni6g(y0!_7#Eirw*DM5iZhCO?;sZM@PKn{?yolR9(i>wCvjJR*VK}-2S4P#Ox`3$@? zB?M7^dkHO-hgm(6iH^db0-KOQ%*-eFk=(4`xq@}X$qUCqnCZsw0p z2GFro`39OkWh?Dnn~L*${5KRgXKN!t69J-Vdn7+I*hv* zCz|!O*520l!A59fJ)V<-+VkmP3WuwWUVW?TW9@UI)AV|A=vj!TVZ;LXw3`j(hG8vh z3OMx}!Rv9j*Jce#GtxP>3 zXd1sQxH>mETd~n2yGt!8D7|uEqmEUgAYq5?@cxFxkd|EH;{F}82SIKB8TGLlfA)=a9%+V&r}wolz}z=tMs z&M2q31l3&R*vtL^tC{QNt2H-7Z~KepLj+CYABr6A@0Q5u;Jj)+sZDL;R7IfpqewxW zkm(-bx~UVHWmJOnn`oRLl2Eztm+h$}nbE}W{@O1t+H_&s)j&SSu zfpT{QTMVh7(@#qp9n09oXvsstm2R!k>+gbvHJ=NCQlb39u}QB}`F&;vRckYfTm#!B zXi^R}e}}Uxun<2`FZ{`tkZhzE1qN%r9A9D@?x-rQtmeCHRodEAOa`o37+`{nPkdiL zehF`0s@!`fC6f%aDG0h&pmn6Xbz(**WpPAuW8^2#MK|frxu+TteNOA`uM2{QTnSFcBtFnfiivHtojmC?I!4xXt?$);fLi%J{J1sY8xj7!EAWz3174Q(gj zr1@t1N|oI+Cqn&MN12a*@h@s)jW&!%cQu$a3yNTAA_U+!JI|F+w)r++j)c;lM36nd zY{D}W(bBz(TY9P?SX`-z$u7ua*J%ZQU1BRu$sD%r`NrsNt7J;cuTp!bk9z&|6K|E3-f>fYEaYk-FrUAq?R!*8W}UPkcwXm*7Qk10dImGg zh#n`EF(KMLf3>^<)E@5)D;Z6e2)>Xui40*{0`|XVLL1jopRc6U(z8AJLoJr6F&U#b zdnGk-uaz%7&8D~-r`gxcVlKGNOGn&OD(yn@=V-roIHr=gB|RUNlmyTE5h#zBI>Dah zY;^k4dAKlBK92>BKb@b>&uwf0Tm?C|XBXiHEkc;dhup{6GfrW9qeg=FVC-h@9#n3K zC1X)O3VA?JB6+0U-5|n{Dp7MIM;!-<*q;^y9mU6*RBTmpyy=$Z(Ky>@$-lj#^#HZ> z=fE5b#cp-Y)~X1pvkA5tOrf3;RdPYv&Mz>!B&7Y8&vZ?)_5GOts_`!DJho|dq{Ht@ z+lt1nKSSNpO`P~f%*dm?((C_3-B7mj_!SkLRH#g!$PYo>eFQ+^f8E?Jav1Zf6CP_s33Xerigy6cB$zjsikr3Q0)wTKki_IJQMm3`8tWt5hhpKFY&iQ*W zpC0DIZkH<+d5C`VuKwUthxoG5VMmzf6%S4w8ie(7}qe zL7tWJhbPQOB>`Hy1{1ud`7zLqO>e8Fr5y3}#+Y$DC@fgFlEH3^_)Z^1j;r1hnxffg zN4f2iviefw7GrRW%d@GiLk*5|p~V=rfr=b}plf%q@eG-&}HK zpV3XY-Fu=n|5uT6u1lI&Z3(vK1jKrsx+mfBo!d*RL<2_MVmdbJ9!Y8zZz=?Jc-wY| zS1j5@I_9|GR-&&51e2QiyAmyae4*YRQANb+4-S=tlhO+Ee+6a7 zkcb2}?vGTun5BclS~Z)#h{JAAE`*me+dwgujQtUDZOgUt`ymWX!e#oF`uVg?-o|bq z&7KgXQ0+xyPc7x(R7vizm5!7GtZr}E$!k6Bjn{5n4m#bVg`sFP!-80phXcEs)@jv@ ztL+hk)VmS{=yl3dVjrgQhhhL0hu12Y2Vyvj|K$K{LD@OH)}3L-EM<&L0JPJmJZjBC z-E&ectn^J|6-Z$Z=@Z%P1-dz2?%}3IS<%8+8e&BduTgc zmDc>Y=}n#NcTfDagoY`A6wLjlgQi1qja`@XUH-PdP5Fo}Jp1i>r830aKl_9EAMF=6 zUDI5Z7h5sG)EVNO;whIkYE`G4TVqJvCTb601T9S7z z7$?+S#00Q4RnzR7H?bQEN-$1&YQfmX5AH@_7BxO^b-Zc)R~hqi(`p?)O6W4F<%V(vv0Irv(V#qttTPj|2g&UDPPlBb zC;+S8Ni%IM*$b)EnYe7d7`=&-+&w(@)MO&PEJS*AtQ|_Xs-{_z*(^{%aDYSk%b>b z8NDP3XC{F@tcwN9)NSjGod$>FpS==qOM7*a%(n z@~%aW;fW<0oD~dLNjvgZF&%DB-F-6=chs+VyGbY0x;Y|c6tZ4ky)2U!z-qd9+Tl9} z?+1g1^|X@LA`!~eUaipvsVRIm_4M?|8CIR@s1?!ByL`?yXU)4&i*U7ctaCxrt?Udo zv5*(@cOK`S!p<{Jn%yyQ?wPg0kglc9+=X?Hfo6hd51h>}vJU)FM%mDI5EuyjDY z<+Wb1-=#F&`Z|rjGapRf1(4c&mFTGX)d@mO+-=>G=ZxKqXeU=mqUpDDyu|4}y&A}n z@ZFfxWS&#R@vyTw6gaF(YxcMI9m66h#AHBCzYI>Fr-VL|Hd(4^P-db=2CdL!Xq`A> z&my0TIc^e^i1r$wwEU{ZBsWWz8-4WYfhD)eMv0ed{HLt+qv=!oCIP~kfO+4b|xHWc{$&aSE37FzU zL`=tDv)9#ru4T|s>1Y*`5pd{c2CV*Ci59{WF=-5_nA;bv!tlUGTnBMS9Cuzj2f}0g zmv>5wMUz+tO6R-MwduJG(*Px*Q}c44c1xf1MiPl6|6>zF*#6SuSW^nhQd@22D7#Up zysh;gPaBGM)|Qc}A35`q!rbV<((3$>;;xUcIj_5`w~-q=B%+puXOe~)T@kD0hC|ql zDPPWP6qWbPXzx2irdTK5n=Eo~XsUi4W#p*Cv-J%>%AE{UHo58R_wdmOHJ|z;YNS9s z?U`!2FEX}_+HZxDn561H6D3?F_dcvToQ1 z>pegOPMrn%0@o*paEeRuYVMfC;XhvNZqjT6gc)r;J|QQXv1zQ`F$sMS1p)|^ zzzFb;GOLqd^Wa(Q>VHNhci#st9i~4AQQMj1-u3;XE}`u;%`?sr^Y2VYEpd~$lK0l# zowAoEp}pY7Sq0bf0A0fcR+Gn!&uKo9GHHU@R4AP;$w54!$|Pk*1vwHAv?rN_FC%FS z9>1UW;rfe~YQJk6>@AA`D|`5wqx?7>PwE-JmD5-*Urg1;j0palFXWOma?CL>HMJ zmxh2A0~F0$h+dsn!g8lS_3`W+*qOhgpZR`L#u1zvfGulPAF2o$;f(zS&Z}_4x#y

e^(%>F0_;X=OZ{6x+Oq7B9_s#fi^KFwigw2Re=9WYZF*Rd3 zT@sCGI99Kvvq8KiC}mcQ^Mtn0H;R^j22QqG8J#tP$9U1mdQB$^7P$3P@u)hb_+qn1 z6M+qmgUE6pofZoIc0{>Nx~;^0MO-2r+RTPJ+nQ6P?7DH-auv!>Tv^w(6>Z^NL#mcH z3?zZOs#R%by87-l=}4X95AEN|IF^?dzU&yiLXi201uMVx##v^&aj$B#OFM{mN_khX z3$lFI=R-h8P>pI}e)5&i|3}lghco&Af81FmB$cyOili`dW^|$>l}hE9RVwAQ9A+mH z5w=Q2PODVvQ)tO4hoLcY7-4hX7#rra&FsLopYI>Pf9~tLuj~Hve!t)M{d_&2kLNzn zi#|dT%2Lraqu-ho$<@?@hi*2MVJgeDUYIbs_z3XL&@=T)dCd?{aPx$pm%w&*W;NJl z^i)TI>JjMueb>4b$GGg#dtn>!A@exf)L8_jAlM}Eo(byAAuW)idF3V|;HyK!G!%y_ z^lAJvThkK&S+{>8sNU5BLy)3nTUiG6%uFH`9QZg{FM5oU(ii`cm!J6);E~nC-TdH@ zWr%9j#EJjZTah|L-2yQGpG|wqk`0`5J^B4ks4?UE?8Rzw%V<}1$R``u3ke^=joOJCrr zLD2>NaOtM4V2zLwsc`>dZBcCiK{*I6e`;4ouFc_Hb&})wcGvZu%b&Z+(>W2!@X2cT zMIhhynn*5v8=h32-Lxwtv%GMWk$$f^0xRf$SQhf|hl!G}2Ig>;O1ct5kd1X{HRR$iX9zm>g|qEs#&e+YN6X*Tzdh*?c%YDlEUmIL zK-BlhD`7C1{uT@!7(}H}F91hKuuc5kAH9jX-cirD%YR9LGI)26Dbbvo z1}b#$J90{gO2>i~n!{xio|-FE3BU6LRAe++_D+=OjTW}$VJ~8PMGPRPu1R5W*o7T= zwR-O=IbdJF`}!q6;;>-U+0%96-X{qH-RLkWZ){xiU~)c7D{(!&fhy?O_~;W0>wb{1 zif{xd040qTMOkq);v{MXS}$FB#1e?kq9M37$g^OB%`}O%lMTR9FZU@otMoJgpKE>n zTX^hMp2O28_b=~O4l4<8FGR&81J7^Q(| zs~IC+@87lx^@n=mVtj*-sCzsjxt`vz1x0tl;=-kZCz6Y(xwns!?^t` zn+(8TDN=_zcfvDTD6g2bf%WY)`gRl7~csXwS1^NkZD*4W{V`%=GCGe%^9^ z_*7)cc8-4Eh5KqV}2Krf^7bTyB(oXw()CPoe`qke#{P`neA~A_lh8eoj zHpR6V{^)%gU*NQ?_U1j$N|dm<>M;hD$!ELT;P)fDq7i?K%TQ(f0+QgcowR$&TiPhn zTl2w(=UjSXc*Cl;^lawz@fIRg#4Xzd8z&Oe&yOeAGxutVUt70N^;w0VTP_huXKK?x zrt5dseAaz^q|?+9#(Bl4T)pH_*`$epXV#XdS5jHNoQqPbXpOTu4L(OJnP`!UM}NFs zbM4rGBE2=D0vg$CQ}+}c{@)AGfr233(wyq8HdfV9Zt`R3aas~2L(ngS&8Ow?{MvK# zL!Y4ktf_Z4OVCB2&9VVm5y7h^{CS|5c>>R;~@@+98V}po>ZPe1!Aj`a-03B-DPQJ z;a={yf>pC0IVek>pWUjVXH&fPdCqZLVfAIsJcKG!)4M=*7Vxs2t2c}rI61>mjPFAJ zz6=)xBhETc^mBxHBqxn8$yvL{HSwvhVE`xH)MT7f!K9K}eVXX&)6(b4$vMNdJ;%oA z?76I1JLQX<8l`yGwm6TfQ%ijL4@lEBt1Aq5pm_MzlJK_v|>f{Yr zREGwD8|oQz92Z&I)cOp&S5Msz_u!NRGcs}`2#dG>;p7S6s8#yS@727aR0;2$7z_QS zQFP(lIDIrC?4(AOsY(IJZP-N3A1OB3W#9nhK>nQkwZv1x{)AmEu|Bz2{)Q`K$L!fC z_E}FwSg>MHtvzFIFT&412yVOXD@OXY5g{24g>?ejvE`8@(7LEQfK5$znZOeZf%FVM z5^j-Hcakb&Pg%VVSx82ycQ;3AtlfGXeFs<3%PzP_tIFK&w$R(c-Tg!ShgBQT%i59? zsqb9#pM`BHsNF1KEDOFenW?efbND+tqq~5W$Xy~7*oihIVTLb=1S?-u{W3%I7dE#WfD$*8*bwr3|m@_}-War*QkF?Z3VzTUz;ur`Rs?_=P@lp4!Gigw?uP_yGQu7JCa# zeNJD82EK&swpgd`5C0&bDhkvR`Q5R%A^Gc1WLN~<$S*t5hgs7%V!Bi(@#%Iuwns81 zT(Nb3@6~7KO*&zn5xq?s)_8hQM$zrP5^4b*qWN4UG}U2#;$$v35l0h13z&781&1@3u@h( zq=6_mC35SB^ym_`zrlg?0gRpY=mBs+#Cp8zsps@9&QI%!6%@oHQeZG-%V@rQ*Xc{7 ziXdm7X8@Dvzw)u>g&-w&kEuZN&w=`-Lgs(W)gkpbdsu^K6l`HJv2WZtaN;LvwPot{ zlr6%NvEAL3;sMy~OnH*kRnwG|8Ry@0@f_U5P8%m)If!<8QMI_o!b6|1>UZoBIc7ZQ zb-6lpY0Z@E2%N%Q<)-|AY>B}qI&PGj{08n7z(%jF%}f{Gm>$Ts3=6%25kJ{#fvkS< zdoZ(JU)5!{mKayA?Ah7Om%IW7qw_9|`3@zAp^l_Qxd8cR5zt$p^Ky0sF==I+{VTr>QEdBr;%B4QQ}NlQt{Sn@PwWXLS| z5T(?>dgoMDQgov2WVe8$zm@=RREi~UyS+4+sa{%t(r!H7yB~@+9av1h!T%?sXLHA6 zMFZ3K4vU&z7}PA~YbD@mA!QcN*ZSeQv~+whVxFq+5#Wp*59}iTmCi?tM_dtNat^%O zvAOE56KC&Bls^&wAJ-rO@RIrr?go-=^x!p#o_t2MCYEharb@WJtnfJTACV67wxqU+ zBs85}3z?=)oODeN*tRy=um#B62a3s@K%;1gtO+k^3rm!5aZQ?{KI4jMzENKJ0FFO~ zcctZVmQ-C)i1)jt4eTP^sC@FoJ2P~aY$$3w$=2=iHo^!3?2@i zUDCmkYF@KWJuq|_S_F@3ZEjO`s}~zruBAXWO(kk-c$YfP?P_qy%)&f+^`NFz=g+WC z0khS_xg;FDnrSUpI+(F?*HC*!q(A^o6IkKhYBL3fG<|aqjeettd`#pSj&1C^KM~eR z8-XX$U80$q-vx2lKMdGTyUq|<;Ldfo(yhA1(Msj$s;S$A86Z}lSCE1Y;^=^q#n|UC;6vG31 z47p4as!|X|ww{@claY&rZspCChX)J|V!F~CrQE76<3;6k`+55OQT>e-pYhCVORkm) z4~D+wjG$Ff2bY)c$w=JSt0Y7U59Ye|Thhbgl<=uQV$(4l>CFa&1hoccB~M`BU82K4 zo+Gnn&$T2&p@Iyci*K}Er;|W}R$ui<`|no^krK$yE?n1^nEhjUt+6RQGgpvQ%>pYo z)82H#$odz+K=i}ku5AB9@-mC-{%5H@+rWy5dhrC@c%vNQGrmnghNBv@QM_mbnOTZ5 z66UH`mtxxUWY=R8)lodr-cyCYL@6?%(}>UU0()b~{fT&c!wLpm$BmTC#wIaS=*VNb zND_b@w2`%GxmvSft$$po%&!x91pt|XK|dapwEX+sPRO^Bk$r=DT$iP!Mn4r^ZU0W? z?2<=Ak)@PwG%;p<`Yp@mj^ftF)k;7403|k&LG#l#i?T$kjCY%Wk*m>dQ292$;8ZBj z%M)`{u2dF>SW;2SbGCox()wkmSgt8oUIwjs{2b0aX3fzZ@+=K7Zg;goU{+SgTRm3z zbSJGk5)G57ax~epDullyitSHdh9Tpkj@rqREZn>O%Ob^0hc~|lJbp~4-y6TD_2!0P zkoLUTX7YH(Vb)CxN|MQ-c4s;6Eio+#&)V^he_+vCkedxt(f&9)RFOHa&3B2MOjy>^ z`?MYr_vg$x*`h%}5idqv_Qg1;_w+~4IA0ZUTPWM@;I7kf670ut|8ZA`;L?iNe0}>a z$i6@|m~zOy-2Om6B=n!4f5V~5o(Rf5-Qla%uxAW8Z=9g*fM{)H(re4C&(-L3In0d_ zfHZofvIYi?Juhor!Fri>QB24q-d$g5_c{lpUUV(851z|#d2f}QM5=D6uFMy1RKn{c zIKi5=Bqs!6G4x(-*m7I@sfN63mUDz{3%6aS?qYLb^J!2O7HLdRX6;z5?QF-t zTx?xj+oSm24{+hW%gUHw*>mR3^5?m_ih9FgZ>xOkWIrEp&$r{H{()NZOWWaO8Rctv z8gXKsUc~Ot#-XRqZ56DU$ZZa9DBtBwGw{-f97gS6R;p~w!Uu+T0Gd3!>b}7E8`dEy zjalL)zpjpbVL@BV<%Kgn=k4HJ5h#Jm3FRzsn)=l9L-`lvyEojf|0DWv?Pj3XvJ+M9 z>rO{WMo}-&eR{Soh|s8p{oO>WL{~KV2!zfgb%Qapxcq)Z;Gm1=yHLaRnpI!**0o~iX+z|A z+`@1WfT>WQ6vDmcWKlx`{-`Gx#Kv~ScDEbm>p{J;@a)*Ad$(aX){~`cP(?2vcM&Y^UnuDIZmA%3R2i;zzN7ot03oJFvz$~NU0iSWYVX?10sq^ zxq=;+Y}Ss2>#5f;rmcqIg0_=&%#IP(OIK>>u|4Yi=S}qJ^XaF?$nAshwcYl(-|kC& z^7`P8qu$GdXV>}*fyeWdkC)WTRB!&d|0)`1dgZl&6}x=bB7<}ajo6mu^=$RbZn>)t z4!XN16bOf&N(h~%PY2WNKC8Puil1eh_ilUKWJuMtSkH8|HD35?g_sxI^D1ejxhSrU z$1eG`@1sEeN8^rBEM~;ulo%M#|Wijx|@2dp~cdB zAQ@_*2H`T^42^}a&3-j?4RdE1~# zdymU47s^~VwZ(y&`u)eXgB%*_ZQHu8!VOd&)^l=CnWImwJp<%*fzozbIdG1coa|cK z^f{58rH$QiPA#0)C6*5C^^TqM4LzoQE%lL_vN>Zt2dn+h;e}nz))n%@+()2DS7!}_ zt!|U+PId}o61&)S=O3KiP-((}J7-D+-`_)$ee~n=iZ1ql^=hb~f&gEoJ|M?H0bfGl z)k=G!*|@ldE8|*wkVm9^3448)gjq`6q&~(li;Y=Xmnn774#j zEsa)7WvUb1#NQR(X#cBg4=mhCk9UroY-;@4bzp-!U>Ts?(5{h0g~%hg8EExGh(}04 zq+xLP#D6zj#emIZ;()}>-SiH_E%Ec#FWf`)=1EX!^N@p^_6v$=f029erybessXg}Z z@6lvYNqU6?x1wVH9bAO-U|yeWA@3=xz*TWBp&mUF^vS{;H$2onks4?Yk?C9eGgY*~ zY0YOQaQnxhW(#S~U%FmE-eJ@>_!br$sO6dFb+-+uCW*Gh&Z{Q=G**sPkapD^k^Cz^ zn-6iHt=Z;FQ4Mzkm2y|M^nhZGWovDSrG{Vl?>}pR_2wCk2CkJLZu{{wu&HKW>XumZ z@p3k-?Df)TCV|b*eV={qKL_vP3OX?jtD2R+nr0Edq^Izs{C#2gxg)O(a23a)w4>nx zF%0_g7^!yDE6Yj&I~KidcaVEo?$~*%hdKN2i==wtB;Q^JSIpRvGj=@`&gg&jN0<0z ziw7!+)V?!hZ5sC)+=+XuTcG!GQ1nCN!KR&bKD~cXFhqav`7f31EK0*T0Sn zifnECVCKcuL%nTfE~+M!{?Xq=DYLUvS4&WcKd0?tFWSC(^r(5*HpGQQ%Xo{alisDj zr*GYSNyi;YED!$IrRGtjTz?8|bVv(rEDikwXT#&DY+6xHY*dIZ=!&e2#k2f0ASYAg2 zk7TIg#>kMaHMxkHCCt-R=mQ>be6*@L(ZY2EvjLsY&?Tq?n43Vr^1ND1M-J!htHzAk0K~uAu_z9L}JUy%N z!uZ&^A{OxO*U-Y&i5$PyyqbMvWa5I`R`S*|z7#u(2x#N}k~4IT|F2v4ms^OtI5{UY zZp|uYdQ46USCS#k%&0=w>6aFCq3LVHxB>zCv`dKEl3xu!w7>&iyZ#SUodo zV4gaphl4EgS_Z&!S~(A1D`aN7%CfduWH)3mqWd=;#k54&lud2Bm5vu%{dCXwVyF?; zg7ca@);sGvPOn^T_J12mNiX*k{Gt3@0gjs8YpE>VYf>4%IXG`)qgQbr{Q4Bu(H>bw z-6%+P-au{<%gsSQ_>Ti+!%^r~gOZbI(4)`^O|YNdsA((vt#t4U$?xF?_>?$}$mvJ} zDy>cdeX#cAbB977kAgF>$VY_8>lP!D!y=_dC;Xq+REUf3Z}Xu@qlsjGfXSnE;^u0K z7HVtQT|wN3&eZ30MYGT9Y6^;pdRcj!B_?6FA}QGS`C$HFQsBgZ#jU}OvMhFizDh-u zPxGX4nZuu>TSp{cKiP+bGxQ++AYt1dki)Xe#c;TIZLNPbu@kf}K_zlD5}xVY?-V+p zCrRk8+pzHSlK<4b4?WCAhae&t+To={w-2?wc2<>6E`l&eFlG4k!yZTKmp|m_GxM)E zK&4orCIzJ;C_qJsL!FT-=dkc2`6$&k>I&BvIc$Zgu1EE#`+IFlCi$gyxpy(RX+z@`iG29X0Z+GAgNYpc(Aj*N?E)#b` z55JmP#mPwr?ffFVx}W$2di^>6_DQLRWA*%uCi{HodaBVgp3kiZ8SVbJ+yQ9cHQl{R zaq#av{q23aNiW)wxB;CPjKdXOxn-;t!G>n-lJDXWrR_3t&qX;0oY_G{qH)ZoLIaay zADJf~E$IZ;7uKcJo4W)OfH6tmGFZdA!_PiC2Z^sHXGREwTC>T$7WnYG5TOJaF#6$j&jF2LV|>RY<#{ ztG5ZXn|uA}(Yt^NGp(Hk5n_HEIM{&QQ50sL!#&FHyy!}wGHRv071pv9SYj@w<5}bpOzgL{!Ry0lyebjKDvH{k+caY z?5PLFfkT~TIB*{vJ%4n3>laG?OPOxck->mB=`;UjU;9J*nb_-&!%S|zd|e(WQl@Ov z&lx=MBKU{OwdyQx{|I%eAU^G-MddoKUdOsp+4Au3xkSw*SlQV}YX?EqrJBd9+q^rg zVgQd`?)&_;&)R{O(f;1cmHuiJazka%_9`;&L6;S|Ey1$eqOATp^c5@+Pxbs+(S**$}BsEJYE~=~Hi0V!g`1TQM>?I{s z9D0xR{&QC?+Ib^#a`a^WOk{2g&EE9NkO6Tm0~R=6VWmCEv^k{J(Is5`{S6k-28$Bz z-JwRR;hguHxv~di_2+RA08Q=?T`T6Fcxgm06oCZm@Qgf_gE3 zczEdiz0POR%eBaE9e}Xwz0#CXNmc@g$WSl}uW2(qz1+Io65)T}w)*|FaX>dAMm7EU zljmA&iSwPBg`_yx>C&Pj!^>Z+4@M1s1Bxf%&OJyVNNV;2vxf*;*Z}&|BMa?S&@haP ziCU!GP-08+EBV{{^3rfXG@>eM)8;4TdnTUC@7w0~ zTw&YJP0ETLd-4yq$iJ&dDj6of9hUUsM?9VA=cHdc2g&5wUykU{J8sYI2FnkA0Po+V zu=U!@ya{k)O`T2TkXF&N9tR%E#NmLr`&!2EuFJulS zzgFSTd-+NSqT!RL04sj{AOb{Z1MYmBe+Mw`>K*#&4&d5CPY}e*=u*;hzvot)7;)5{ zt(E((WyX=iNS_e1IEcInZeQJ}X&`2jFc%m+U+pP;@))uw<(416b0EU+^j}>Y56gl) zn|pewkB=-KGP2jgZ*F7VE2>}0YY3%(alRCCJ}Rs|U}TFZr%~AK_d4RXkD<-cbo%jr z5w9yUA$Dl2d7`$($<)294{`fXWO@kak5LLe4N+FuS^vq*CaMblxWC$GiR|+iN+O%fV&dvEL1%tgD{lnmE0sz+X+n9lcYGhAYY^_7jB#|-N11C=r#9*?<1ues?AF(4I1{@r6w7-41oiJr-V`#Ye=TDu2zIYAv(imPc>LVp|o@AYT5B zL40`_xbLItUXTXwfB(=w!ASTx#CYHo zCf@q&vRWw7AGwA_RA1%c&5_v*}_GZmh^TH0xZtp-2;3_DMV z?OlFtf#BP0a;C&E-yiF9Uj!^b5Z`4F51wK!MLLXB0B39R`>?JD+}`0I+24QqIfUbU zRW%b3*vbv?SL6H~SD4t`JK6Y}ejT*t217yoHyf+_jr8nBFZGz|kH7lmwpO$~;Ug>Q zMfJJ(^j{cV>+#-nxo`<#?l{ZCtk2|4P8|7a9Vn9FXiNeTCXegqmDg!W?=@`pjSa?? zm}K7=?O##n>li&1>w1KC$ZtGqGiYiZI}Abgd6j~HeOU6#2Kphol^1jJt(9eJ?i@-} z5ApHR0c1G8#!LFr>{7lZ`K4D_IPUs7tC0WyUVws@Z>oKH$2pF_wBE)&oIh0)?OkEW z4gwC7Lo)jh^$0iXr`00&UnlC>IG@kk+xoR!JUqQgD}SM5RMt%C{?<2+S(-TxtI1w@ zIZHX7DDqcUlELkSlciyz)_J^1tQOrtNwAbuhZ28U z+s`w78ZP3{1s_NtHA%-YMoZR#XQ<2dGl<9*{8Vh2GzKHRm}n;_X~$6V{M$-mX=G)?-`vDWaD|q zCGQFQoksw1oU^{3AfgXNwOTDz1+`F0_9%|_AWdDg+q0f|WvM?Vf!OJoS9KKj_nSrP z(2bYA?Xwkda@*k1*_r@ymb~htOSMWOoh)S~Jrub_+@x7{zIJ!5#XONSQz}E`6*kKP zCWTK%xO;DQCt5AT4Bt&-yh@{t-O)0qw2PkZD{B@0^1R1Q2qNM5)_>dRQ0SFn$b=<2 zGe5GUR#5H9uYV`!No4J*kC|A0Z2ElF^MJI0@$eTscKK1Ftm);==w}+98M@9&%Q?@= z=**gr_-^a#VbLPh)BN$(R;>u|LB@K*$p_CISFU&-NfBF~m<(hDV0L~%P-d5-VuKl* z0pprzT>&KjcUZjg!Af9zGX2fGvD2on@bA_etXI9?f$yA@irbn7>&i*EVZRDE1G^US zK$SfM=`?xDyuk$eO*zKWXJ+MNcUgMhS$wOhA1ON4X`_sF0UHIAXRHc0x|Y{@?|DTU z_XkJbKCO;>xZ=Gt)cMMKZ2~MPTn0W_6v$yuy8|h&{i`1{dkz+?lWebuk@wF!}AVTFZiv@JgxIDehg|0 zxKu13rOj;71~4UzvTGaHbQIlw4*%0pGD&qtODA2gNo|6cXaY>3DB7b|9WJL& zIJ~9%h5pqo?<;F{ErSHL+Lxt5a-4~luc0O907&$7!_|WaOmr{849&wAOjGBY+gXvt z#)bYj6QJjZFks8sPnvo0{Fjj})ufTYsKGr`(U(Lektqvj>ow7PCSE)<`w7V-=1zop zCgiMk=`tjzJqwtGMka1^t!;j9&@cnHT@QH21wL`FYY_Z;ec$(WT5jy>uTwq&uZJsU zZ2YjjHvy-))nM<(}|7cyL9HXSWO7 zz~mmrblc-Ar$L-$Ob;UyE8}eT(B?7XZk)fI{pH2JpeRBFaN3=ktG%~M*YL+(NJqv@?1Szp<2$87^Z)}} zA^2Ld$KnQ+&}DCX%w@`t0u((+dP>pF0DN%%VJA~Krw=JQ5K;K?#buQiMGR_fIU7^4 zzp$b+=%x+6CX8 zQT8NqV!|@T%pr3C)%xgdN3O+xJ=nmle_z~4u8ya-4Uc(j>aLw@$q%d1SGg6~Z<(_6 zmM8Z{Dp{~tub~URQLm%g#SL^pr4J<#&q{W(NZA?C$(2LvS8n<({Bs?=;>1ecP1TY9 z=c7*qNdEEUpjedRDP7&7O5q1%=irTkt8_cyyp>GOBRV2}rXy3_t)s9?<>(u%( zD2vx!diDLU(C_JyCp^H*xWekhFFNxu^LN|PL#@xf>6xy?tjPLu6WHl6cAIHD+647% zXX^Tj-_dvldXBcR7N`3$JYR7XE*i1pHXWGwTk1j!%{Xg5@AoZwD+Hz2zM>hJ*yO+$ zM9?5U+J?5yhASoe$`Z)?PUpd)E#KHodzUeIjM?Z32~W+5a@? z;qp{KQ}w=@Pa*zryBF24XbfRD&|&R^H88voVQHO%n>

    ^ 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

    34y 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 literal 0 HcmV?d00001 diff --git a/gradle.properties b/gradle.properties index 1cad441c1f..f2137c890c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -145,8 +145,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 + ################# 旧版本架构模块版本 ################# diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/AMapViewWrapper.java b/libraries/mogo-map/src/main/java/com/mogo/map/AMapViewWrapper.java index 681c4241e8..80f9e2a682 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/AMapViewWrapper.java +++ b/libraries/mogo-map/src/main/java/com/mogo/map/AMapViewWrapper.java @@ -878,7 +878,7 @@ public class AMapViewWrapper implements IMogoMapView, case 5: return MAP_STYLE_VR_ANGLE_CROSS; default: - throw new IllegalStateException("mode is unCorrect"); + return MODE_MEDIUM_SIGHT; } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/AMapWrapper.java b/libraries/mogo-map/src/main/java/com/mogo/map/AMapWrapper.java index 77fe42cd29..5e092f589e 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/AMapWrapper.java +++ b/libraries/mogo-map/src/main/java/com/mogo/map/AMapWrapper.java @@ -277,12 +277,17 @@ public class AMapWrapper implements IMogoMap { @Override public CenterLine getCenterLineRangeInfo(double lon, double lat, float angle, float distance) { - com.zhidaoauto.map.sdk.open.road.CenterLine info = MapDataApi.INSTANCE.getCenterLineRangeInfo(lon, lat, angle, distance); - CenterLine ret = null; - if (info != null) { - ret = new CenterLine(info.id, info.tile_id, info.road_id, info.lane_id, convert(info.points), info.angle == null ? 0f : info.angle); + try { + com.zhidaoauto.map.sdk.open.road.CenterLine info = MapDataApi.INSTANCE.getCenterLineRangeInfo(lon, lat, angle, distance); + CenterLine ret = null; + if (info != null) { + ret = new CenterLine(info.id, info.tile_id, info.road_id, info.lane_id, convert(info.points), info.angle == null ? 0f : info.angle); + } + return ret; + } catch (Throwable t) { + t.printStackTrace(); + return null; } - return ret; } @Override From d3cd1bf0f961c4e77cf09cad6ff9eaf46befac4f Mon Sep 17 00:00:00 2001 From: renwj Date: Mon, 30 Jan 2023 10:27:18 +0800 Subject: [PATCH 05/48] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0]=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E7=BC=96=E8=AF=91=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eagle/core/data/enums/EventTypeEnumNew.kt | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt index 7d7aa487b5..920e2203c0 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt @@ -454,21 +454,6 @@ enum class EventTypeEnumNew( ), //------------车内标牌 obu end --------------> - TYPE_SOCKET_ROAD_CONGESTION( - "100071", - "交通拥堵", - poiTypeSrcVr = R.drawable.v2x_icon_yongdu_vr, - content = "前方%s米交通拥堵", - tts = "前方%s米交通拥堵" - ), - - TYPE_SOCKET_ROAD_JINGZHI( - "100251", - "前方%s米静止障碍物占道", - poiTypeSrcVr = R.drawable.v2x_icon_jingzhi_zhangai, - content = "前方%s米静止障碍物占道", - tts = "前方%s米静止障碍物占道" - ), //------------车内标牌 end --------------> From 4e8f8f086492cbbaa0ec4bc8f2a45f0deaf19fef Mon Sep 17 00:00:00 2001 From: renwj Date: Mon, 30 Jan 2023 10:27:18 +0800 Subject: [PATCH 06/48] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0]=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E7=BC=96=E8=AF=91=E5=92=8C=E8=BF=90=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mogo/launcher/MogoApplication.java | 2 ++ .../eagle/core/data/enums/EventTypeEnumNew.kt | 15 --------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/mogo/launcher/MogoApplication.java b/app/src/main/java/com/mogo/launcher/MogoApplication.java index 5170e83c20..d0d8b1fe4c 100644 --- a/app/src/main/java/com/mogo/launcher/MogoApplication.java +++ b/app/src/main/java/com/mogo/launcher/MogoApplication.java @@ -13,6 +13,7 @@ import com.mogo.launcher.stageone.APMStartup; import com.mogo.launcher.stageone.ARouterStartUp; import com.mogo.launcher.stageone.ConfigStartUp; import com.mogo.launcher.stageone.HttpDnsStartUp; +import com.mogo.launcher.stageone.ThreadOptStartup; import com.rousetime.android_startup.StartupListener; import com.rousetime.android_startup.StartupManager; import com.rousetime.android_startup.model.LoggerLevel; @@ -63,6 +64,7 @@ public class MogoApplication extends MainMoGoApplication { .addStartup(new APMStartup()) .addStartup(new ConfigStartUp()) .addStartup(new ARouterStartUp()) + .addStartup(new ThreadOptStartup()) .setConfig(config) .build(this) .start() diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt index 7d7aa487b5..920e2203c0 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt @@ -454,21 +454,6 @@ enum class EventTypeEnumNew( ), //------------车内标牌 obu end --------------> - TYPE_SOCKET_ROAD_CONGESTION( - "100071", - "交通拥堵", - poiTypeSrcVr = R.drawable.v2x_icon_yongdu_vr, - content = "前方%s米交通拥堵", - tts = "前方%s米交通拥堵" - ), - - TYPE_SOCKET_ROAD_JINGZHI( - "100251", - "前方%s米静止障碍物占道", - poiTypeSrcVr = R.drawable.v2x_icon_jingzhi_zhangai, - content = "前方%s米静止障碍物占道", - tts = "前方%s米静止障碍物占道" - ), //------------车内标牌 end --------------> From 6d3eeaca509cf4d54dd7c54faf53a25af7f32e37 Mon Sep 17 00:00:00 2001 From: zhongchao Date: Mon, 30 Jan 2023 10:38:30 +0800 Subject: [PATCH 07/48] [2.13.0-arch-opt] merge --- .../src/main/res/layout/bus_base_fragment.xml | 21 +++ .../src/main/AndroidManifest.xml | 3 +- .../com/mogo/och/noop/MoGoOCHNoopProvider.kt | 63 +++++++- .../java/com/mogo/och/noop/OchNoopFragment.kt | 21 --- .../main/res/layout/taxi_base_fragment.xml | 21 +++ .../com/mogo/launcher/MogoApplication.java | 1 - .../com/mogo/launcher/stageone/APMStartup.kt | 2 +- .../mogo/launcher/stageone/ARouterStartUp.kt | 2 +- .../mogo/launcher/stageone/ConfigStartUp.kt | 19 +-- .../mogo/launcher/stageone/HttpDnsStartUp.kt | 3 +- .../badcase/BadCaseManager.kt | 81 ++++++++--- .../badcase/biz/InitiativeBadCaseWindow.kt | 1 + .../core/function/hmi/ui/MoGoHmiFragment.kt | 135 +----------------- .../function/hmi/ui/tools/ToolsImageView.kt | 4 + .../core/function/hmi/ui/widget/CameraView.kt | 15 ++ .../hmi/ui/widget/SingleTrafficLightView.kt | 77 ++++++---- .../src/main/res/layout/fragment_hmi.xml | 39 +---- .../collect/MoGoMapDataCollectProvider.kt | 31 +++- .../eagle/core/data/config/HmiBuildConfig.kt | 18 --- .../eagle/core/data/enums/EventTypeEnumNew.kt | 3 - .../api/hmi/view/IViewControlListener.kt | 1 + 21 files changed, 282 insertions(+), 279 deletions(-) diff --git a/OCH/mogo-och-bus/src/main/res/layout/bus_base_fragment.xml b/OCH/mogo-och-bus/src/main/res/layout/bus_base_fragment.xml index 5536384f8a..6186719077 100644 --- a/OCH/mogo-och-bus/src/main/res/layout/bus_base_fragment.xml +++ b/OCH/mogo-och-bus/src/main/res/layout/bus_base_fragment.xml @@ -32,6 +32,27 @@ app:marginStart="@dimen/dp_640" app:marginTop="@dimen/dp_80" /> + + + + + + + package="com.mogo.och.noop"> - / \ No newline at end of file diff --git a/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/MoGoOCHNoopProvider.kt b/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/MoGoOCHNoopProvider.kt index 9d04c6c036..1abf670a2e 100644 --- a/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/MoGoOCHNoopProvider.kt +++ b/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/MoGoOCHNoopProvider.kt @@ -4,6 +4,10 @@ import android.content.Context import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import com.alibaba.android.arouter.facade.annotation.Route +import com.mogo.commons.module.status.IMogoStatusChangedListener +import com.mogo.commons.module.status.MogoStatusManager +import com.mogo.commons.module.status.StatusDescriptor +import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d /** * @author congtaowang @@ -15,15 +19,70 @@ import com.alibaba.android.arouter.facade.annotation.Route @Route(path = OCHConstants.PATH) class MoGoOCHNoopProvider : IMogoOCH { + companion object { + private const val TAG = "MogoOCHNoopProvider" + } + override val functionName: String - get() = "MogoOCHNoopProvider" + get() = TAG + + private var fragment: OchNoopFragment? = null + private var containerId = 0 + private var activity: FragmentActivity? = null override fun init(context: Context) { + MogoStatusManager.getInstance().registerStatusChangedListener( + TAG, StatusDescriptor.VR_MODE, statusChangedListener + ) + } + private val statusChangedListener = + IMogoStatusChangedListener { descriptor: StatusDescriptor, isTrue: Boolean -> + if (descriptor == StatusDescriptor.VR_MODE) { + // 进入vr模式默认显示网约车小巴fragment + if (isTrue) { + showFragment() + } else { + hideFragment() + } + } + } + + private fun showFragment() { + activity?.let { + if (fragment == null) { + d(TAG, "准备add fragment======") + val fragmentByTag = it.supportFragmentManager.findFragmentByTag(TAG) + fragment = if (fragmentByTag is OchNoopFragment) { + fragmentByTag + } else { + OchNoopFragment() + } + if (!fragment!!.isAdded) { + it.supportFragmentManager.beginTransaction() + .add(containerId, fragment!!, TAG).commitAllowingStateLoss() + } + return + } + d(TAG, "准备show fragment") + fragment?.let { noopFragment -> + it.supportFragmentManager.beginTransaction().show(noopFragment) + .commitAllowingStateLoss() + } + } + } + + private fun hideFragment() { + if (fragment != null) { + d(TAG, "准备hide fragment") + activity?.supportFragmentManager?.beginTransaction()?.hide(fragment!!) + ?.commitAllowingStateLoss() + } } override fun createCoverage(activity: FragmentActivity?, containerId: Int?): Fragment? { - + this.containerId = containerId!! + this.activity = activity return null } diff --git a/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OchNoopFragment.kt b/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OchNoopFragment.kt index ac540cf7e9..3dcf55be4f 100644 --- a/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OchNoopFragment.kt +++ b/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OchNoopFragment.kt @@ -3,12 +3,9 @@ package com.mogo.och.noop import android.view.View import com.mogo.commons.mvp.MvpFragment import com.mogo.eagle.core.data.config.FunctionBuildConfig -import com.mogo.eagle.core.function.call.biz.CallerFuncBizManager import com.mogo.eagle.core.function.call.hmi.CallerHmiManager import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager -import com.mogo.eagle.core.function.hmi.ui.setting.CameraLiveView.Companion.cameraLiveView import com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugView -import com.mogo.eagle.core.function.hmi.ui.setting.ToolsView.Companion.toolsView import com.mogo.eagle.core.function.hmi.ui.widget.DemoModeView import com.mogo.eagle.core.function.hmi.ui.widget.StatusBarView import com.mogo.och.bus.R @@ -33,7 +30,6 @@ class OchNoopFragment : MvpFragment(), return OchNoopPresenter(this) } - override fun initViews() { //设置StatusBar初始状态 @@ -44,23 +40,6 @@ class OchNoopFragment : MvpFragment(), DemoModeView(requireContext()) ) - ivCameraIcon?.setOnClickListener { - cameraLiveView.showCameraList( - context, - CallerFuncBizManager.bizProvider.getCameraList - ) { liveStatus -> - if (liveStatus) { - ivCameraIcon.setBackgroundResource(R.drawable.icon_camera_selected) - } else { - ivCameraIcon.setBackgroundResource(R.drawable.icon_camera_nor) - } - } - } - - ivToolsView?.setOnClickListener { - toolsView.showToolsFloat(context) - } - viewShowDebugView.setOnLongClickListener { ToggleDebugView.toggleDebugView.toggle(requireContext()) true diff --git a/OCH/mogo-och-taxi/src/main/res/layout/taxi_base_fragment.xml b/OCH/mogo-och-taxi/src/main/res/layout/taxi_base_fragment.xml index abd64b352c..18d4ade230 100644 --- a/OCH/mogo-och-taxi/src/main/res/layout/taxi_base_fragment.xml +++ b/OCH/mogo-och-taxi/src/main/res/layout/taxi_base_fragment.xml @@ -90,6 +90,27 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/> + + + + + + () { } override fun dependenciesByName(): List { - return listOf("com.mogo.launcher.stageone.ARouterStartUp", "com.mogo.launcher.stageone.ThreadOptStartup") + return listOf("com.mogo.launcher.stageone.ARouterStartUp") } } \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/stageone/ARouterStartUp.kt b/app/src/main/java/com/mogo/launcher/stageone/ARouterStartUp.kt index 15c913da9b..c539080df1 100644 --- a/app/src/main/java/com/mogo/launcher/stageone/ARouterStartUp.kt +++ b/app/src/main/java/com/mogo/launcher/stageone/ARouterStartUp.kt @@ -33,6 +33,6 @@ class ARouterStartUp : AndroidStartup() { override fun waitOnMainThread() = false override fun dependenciesByName(): List? { - return listOf("com.mogo.launcher.stageone.ThreadOptStartup") + return null } } \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt b/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt index 9c5c13cc30..d2093e3b5c 100644 --- a/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt +++ b/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt @@ -93,13 +93,6 @@ class ConfigStartUp : AndroidStartup() { // 配置BuglyAppID:MoGoEagleEye CrashReportConstants.buglyAppID = "ac71228f85" - if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode) || - AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) { - //控制HMI展示元素 将不用手动调用setXXXXXViewVisibility - HmiBuildConfig.isShowAutopilotStatusView = false - HmiBuildConfig.isShowPerspectiveSwitchView = false - } - if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) { HdMapBuildConfig.currentCarVrIconRes = R.raw.chuzuche } else if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) { @@ -112,21 +105,13 @@ class ConfigStartUp : AndroidStartup() { if (AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) { if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) { - //是否显示 红绿等 - HmiBuildConfig.isShowTrafficLightView = false //是否显示 限速UI HmiBuildConfig.isShowLimitingVelocityView = false - //是否显示 路侧监控 - HmiBuildConfig.isShowCameraView = false //白天模式 FunctionBuildConfig.skinMode = 1 } else if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) { - //是否显示 红绿等 - HmiBuildConfig.isShowTrafficLightView = false //是否显示 限速UI HmiBuildConfig.isShowLimitingVelocityView = false - //是否显示 路侧监控 - HmiBuildConfig.isShowCameraView = false } } @@ -169,7 +154,7 @@ class ConfigStartUp : AndroidStartup() { } - override fun dependenciesByName(): List { - return listOf("com.mogo.launcher.stageone.ThreadOptStartup") + override fun dependenciesByName(): List? { + return null } } \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt b/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt index a189438325..8c4aa9dc6c 100644 --- a/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt +++ b/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt @@ -70,8 +70,7 @@ class HttpDnsStartUp : AndroidStartup() { override fun dependenciesByName(): List { return listOf( - "com.mogo.launcher.stageone.APMStartup", - "com.mogo.launcher.stageone.ThreadOptStartup" + "com.mogo.launcher.stageone.APMStartup" ) } diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/badcase/BadCaseManager.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/badcase/BadCaseManager.kt index 6888a1fde6..62501383b7 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/badcase/BadCaseManager.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/badcase/BadCaseManager.kt @@ -11,10 +11,19 @@ import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope +import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.data.msgbox.MsgBoxBean +import com.mogo.eagle.core.data.msgbox.MsgBoxType +import com.mogo.eagle.core.data.msgbox.RecordBagMsg +import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener +import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager +import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager import com.mogo.eagle.core.utilcode.kotlin.lifecycleOwner +import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger +import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA +import com.mogo.eagle.core.utilcode.mogo.toast.TipToast import com.mogo.eagle.core.utilcode.util.* import com.zhjt.mogo_core_function_devatools.badcase.biz.* import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig @@ -27,7 +36,7 @@ import record_cache.RecordPanelOuterClass import java.lang.ref.WeakReference import java.util.concurrent.TimeUnit -internal object BadCaseManager : LifecycleEventObserver { +internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordListener { const val TAG = "BadCase" @@ -96,6 +105,8 @@ internal object BadCaseManager : LifecycleEventObserver { * 主动采集BadCase */ fun initBadCase(view: View) { + CallerAutopilotRecordListenerManager.addListener(TAG, this) + val activity = view.context as? FragmentActivity ?: throw IllegalStateException("please ensure context is FragmentActivity.") view.setOnClickListener { @@ -193,24 +204,62 @@ internal object BadCaseManager : LifecycleEventObserver { } } + override fun onAutopilotRecordResult(recordPanel: RecordPanelOuterClass.RecordPanel) { + super.onAutopilotRecordResult(recordPanel) + CallerLogger.d("$M_DEVA$TAG", "recordKey=${recordPanel.key},stat=${recordPanel.stat}") + if (BadCaseConfig.recordKeyList.contains(recordPanel.key)) { + if (recordPanel.stat == 100 || recordPanel.stat == 101) { + //成功结束录制 + TipToast.shortTip( + "${ + TimeUtils.millis2String( + System.currentTimeMillis(), + TimeUtils.getHourMinSecondFormat() + ) + } bag录制成功" + ) + } + if (recordPanel.stat == 200) { + //录制失败 + TipToast.shortTip( + "${ + TimeUtils.millis2String( + System.currentTimeMillis(), + TimeUtils.getHourMinSecondFormat() + ) + } bag录制失败" + ) + } + return + } + //在工控机taxi2.3.0版本和Bus2.4.0版本上不支持被动录包,不进行被动录包的弹窗 + BadCaseConfig.dockerVersion?.let { + if (it.contains("taxi") && it.contains("2.3.0")) { + return + } + if (it.contains("bus") && it.contains("2.4.0")) { + return + } + } + //处于非美化模式下弹窗;是地图数据采集任务时即type=2时,不弹窗 + if (!FunctionBuildConfig.isDemoMode && (recordPanel.stat == 100 || recordPanel.stat == 101) && recordPanel.type != 2) { + //只在司机屏生效,乘客屏不生效 + if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { + CallerMsgBoxManager.saveMsgBox( + MsgBoxBean( + MsgBoxType.RECORD, RecordBagMsg( + recordPanel.key, recordPanel.stat, recordPanel.id, + recordPanel.type, recordPanel.filename, recordPanel.note + ) + ) + ) + } + } + } + override fun onStateChanged(source: LifecycleOwner, event: Event) { } } - - -internal fun RecordPanelOuterClass.RecordPanel.toRecord(): AutoPilotRecord = - AutoPilotRecord().also { - it.id = this.id - it.stat = this.stat - it.key = this.key.toString() - it.note = this.note - it.type = this.type - it.total = this.totalSize - it.fileName = this.filename - it.duration = this.duration.toDouble() - it.diskFree = this.diskFree - it.consumed = false - } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/badcase/biz/InitiativeBadCaseWindow.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/badcase/biz/InitiativeBadCaseWindow.kt index 4ab9e49463..ed8dc2da88 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/badcase/biz/InitiativeBadCaseWindow.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/badcase/biz/InitiativeBadCaseWindow.kt @@ -373,6 +373,7 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList override fun onAutopilotRecordResult(recordPanel: RecordPanelOuterClass.RecordPanel) { CallerLogger.d("${M_DEVA}${TAG}", "-- 收到工控机录制任务回调 -- $recordPanel") + ThreadUtils.runOnUiThread { if (recordKey == null) { recordKey = recordPanel.key.toString() diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt index 05b6ab8ac8..a0ac521b3a 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt @@ -40,6 +40,7 @@ import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion. import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.PerspectiveSwitchView_TAG import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.SpeedPanelView_TAG import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.ToolsView_TAG +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.TrafficLightView_TAG import com.mogo.eagle.core.function.api.hmi.view.IViewLimitingVelocity import com.mogo.eagle.core.function.api.hmi.view.IViewTrafficLight import com.mogo.eagle.core.function.api.hmi.warning.IMoGoHmiProvider @@ -99,8 +100,7 @@ import java.util.concurrent.atomic.AtomicReference class MoGoHmiFragment : MvpFragment(), IMoGoHmiProvider, IMoGoHmiViewProxy, - MoGoHmiContract.View, - IMoGoAutopilotRecordListener { + MoGoHmiContract.View{ companion object { private const val TAG = "MoGoHmiFragment" @@ -119,29 +119,10 @@ class MoGoHmiFragment : MvpFragment(), private var showingV2XTip: IReminder? = null override fun initViews() { - initViewShowWithConfig() //设置StatusBar初始状态 CallerHmiViewControlListenerManager.updateStatusBarRightView(StatusBarView.TAG,FunctionBuildConfig.isDemoMode, "demoMode", DemoModeView(requireContext())) - ivCameraIcon?.setOnClickListener { - cameraLiveView.showCameraList( - context, - CallerFuncBizManager.bizProvider.getCameraList - ) { liveStatus -> - if (liveStatus) { - ivCameraIcon.setBackgroundResource(R.drawable.icon_camera_selected) - } else { - ivCameraIcon.setBackgroundResource(R.drawable.icon_camera_nor) - } - } - } - - viewShowDebugView.setOnLongClickListener { - toggleDebugView.toggle(requireContext()) - true - } - //todo 新超,封装至消息盒子 cbMsgBoxDriver.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { @@ -204,14 +185,10 @@ class MoGoHmiFragment : MvpFragment(), override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - CallerAutopilotRecordListenerManager.addListener(TAG, this) - - // 首次初始化使用默认视图 - setProxyTrafficLightView(viewTrafficLightVr) + //todo 确认使用方 taxi bus 乘客/司机 setProxyLimitingSpeedView(viewLimitingVelocity) } - /** todo ----------------------------------------------**/ /** * 设置 红绿灯 代理View @@ -227,109 +204,6 @@ class MoGoHmiFragment : MvpFragment(), mViewLimitingVelocity = view } - /** - * 根据配置文件初始化视图显示 - */ - private fun initViewShowWithConfig() { - // 控制 自动驾驶状态 展示 - if (HmiBuildConfig.isShowAutopilotStatusView) { - setAutopilotStatusViewVisibility(View.VISIBLE) - } else { - setAutopilotStatusViewVisibility(View.GONE) - } - - // 控制 切换视角 展示 - if (HmiBuildConfig.isShowPerspectiveSwitchView) { - setPerspectiveSwitchViewVisibility(View.VISIBLE) - } else { - setPerspectiveSwitchViewVisibility(View.GONE) - } - - // 控制 红绿灯 展示 - if (HmiBuildConfig.isShowTrafficLightView) { - setTrafficLightVrVisibility(View.VISIBLE) - } else { - setTrafficLightVrVisibility(View.GONE) - } - - // 控制 远程摄像头图标 展示 - if (HmiBuildConfig.isShowCameraView) { - setCameraViewVisibility(View.VISIBLE) - } else { - setCameraViewVisibility(View.GONE) - } - } - - /** todo----------------------------------------------- **/ - - override fun onAutopilotRecordResult(recordPanel: RecordPanelOuterClass.RecordPanel) { - CallerLogger.d("$M_HMI$TAG", "recordKey=${recordPanel.key},stat=${recordPanel.stat}") - if (BadCaseConfig.recordKeyList.contains(recordPanel.key)) { //todo InitiativeBadCaseWindow - if (recordPanel.stat == 100 || recordPanel.stat == 101) { - //成功结束录制 - TipToast.shortTip( - "${ - millis2String( - System.currentTimeMillis(), - TimeUtils.getHourMinSecondFormat() - ) - } bag录制成功" - ) - } - if (recordPanel.stat == 200) { - //录制失败 - TipToast.shortTip( - "${ - millis2String( - System.currentTimeMillis(), - TimeUtils.getHourMinSecondFormat() - ) - } bag录制失败" - ) - } - return - } - //在工控机taxi2.3.0版本和Bus2.4.0版本上不支持被动录包,不进行被动录包的弹窗 - BadCaseConfig.dockerVersion?.let { - if (it.contains("taxi") && it.contains("2.3.0")) { - return - } - if (it.contains("bus") && it.contains("2.4.0")) { - return - } - } - //处于非美化模式下弹窗;是地图数据采集任务时即type=2时,不弹窗 - if (!FunctionBuildConfig.isDemoMode && (recordPanel.stat == 100 || recordPanel.stat == 101) && recordPanel.type != 2) { - //只在司机屏生效,乘客屏不生效 - if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { //todo 数据中心控制来源 - CallerMsgBoxManager.saveMsgBox( - MsgBoxBean( - MsgBoxType.RECORD, RecordBagMsg( - recordPanel.key, recordPanel.stat, recordPanel.id, - recordPanel.type, recordPanel.filename, recordPanel.note - ) - ) - ) - } - } - if (!FunctionBuildConfig.isDemoMode && recordPanel.type == 2 && ( //todo CallerMapDataCollectorManager - recordPanel.stat == 101 || //工控机采集完成-被动完成 - recordPanel.stat == 100 || //工控机采集完成-主动完成 - recordPanel.stat == 102 || //工控机达到最大采集时长 - recordPanel.stat == 103) //工控机磁盘满了 - ) { - CallerMapDataCollectorManager.finish( - recordPanel.id, recordPanel.stat, "", recordPanel.filename - ?: "", recordPanel.note ?: "" - ) - } - } - - override fun onDestroyView() { - super.onDestroyView() - CallerAutopilotRecordListenerManager.removeListener(TAG) - } - /** * ok * 工控机重启返回结果 @@ -410,9 +284,8 @@ class MoGoHmiFragment : MvpFragment(), DisplayEffectsHelper.getInstance().display() } - /** todo----------------------------------------------- **/ override fun setTrafficLightVrVisibility(visibility: Int) { - mViewTrafficLight?.visibility = visibility + CallerHmiViewControlListenerManager.invokeVisible(TrafficLightView_TAG,visibility) } override fun setToolsViewVisibility(visibility: Int) { diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt index 6d89368329..84400ca732 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt @@ -6,6 +6,7 @@ import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.ToolsView_TAG import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.hmi.R +import com.mogo.eagle.core.function.hmi.ui.setting.ToolsView.Companion.toolsView class ToolsImageView(context: Context, attrs: AttributeSet?) : androidx.appcompat.widget.AppCompatImageView(context, attrs), IViewControlListener { @@ -15,6 +16,9 @@ class ToolsImageView(context: Context, attrs: AttributeSet?) : setBackgroundResource(R.drawable.module_ext_check) setImageResource(R.drawable.icon_tools_nor) scaleType = ScaleType.CENTER + setOnClickListener{ + toolsView.showToolsFloat(context) + } CallerHmiViewControlListenerManager.addListener(ToolsView_TAG, this) } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/CameraView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/CameraView.kt index 8e90c54e8c..70e5ae0f35 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/CameraView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/CameraView.kt @@ -4,8 +4,10 @@ import android.content.Context import android.util.AttributeSet import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.CameraView_TAG +import com.mogo.eagle.core.function.call.biz.CallerFuncBizManager import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.hmi.R +import com.mogo.eagle.core.function.hmi.ui.setting.CameraLiveView.Companion.cameraLiveView class CameraView(context: Context, attrs: AttributeSet?) : androidx.appcompat.widget.AppCompatImageView(context, attrs), IViewControlListener { @@ -13,6 +15,19 @@ class CameraView(context: Context, attrs: AttributeSet?) : override fun onAttachedToWindow() { super.onAttachedToWindow() setBackgroundResource(R.drawable.icon_camera_nor) + setOnClickListener { + cameraLiveView.showCameraList( + context, + CallerFuncBizManager.bizProvider.getCameraList + ) { liveStatus -> + if (liveStatus) { + setBackgroundResource(R.drawable.icon_camera_selected) + } else { + setBackgroundResource(R.drawable.icon_camera_nor) + } + } + } + CallerHmiViewControlListenerManager.addListener(CameraView_TAG, this) } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SingleTrafficLightView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SingleTrafficLightView.kt index 12842094df..36af0aad3d 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SingleTrafficLightView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SingleTrafficLightView.kt @@ -8,7 +8,10 @@ import android.widget.ImageView import android.widget.TextView import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.data.config.HmiBuildConfig +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.TrafficLightView_TAG import com.mogo.eagle.core.function.api.hmi.view.IViewTrafficLight +import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils import com.mogo.eagle.core.utilcode.util.UiThreadHandler @@ -20,7 +23,7 @@ class SingleTrafficLightView @JvmOverloads constructor( context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0 -) : IViewTrafficLight(context, attrs, defStyleAttr) { +) : IViewTrafficLight(context, attrs, defStyleAttr), IViewControlListener { private var mLightIconIV: ImageView? = null private var mLightIconBG: ImageView? = null private var mLightTimeTV: GradientTextView? = null @@ -28,17 +31,26 @@ class SingleTrafficLightView @JvmOverloads constructor( private var mLightSourceDivider: View? = null private var mCurrentLightId = 0 - init { - init(context) - } - - private fun init(context: Context?) { + override fun onAttachedToWindow() { + super.onAttachedToWindow() LayoutInflater.from(context).inflate(R.layout.hmi_view_traffic_light, this, true) mLightIconIV = findViewById(R.id.hmi_traffic_light_iv) mLightIconBG = findViewById(R.id.hmi_traffic_light_bg) mLightTimeTV = findViewById(R.id.hmi_traffic_light_time_tv) mLightSourceTV = findViewById(R.id.hmi_traffic_light_source) mLightSourceDivider = findViewById(R.id.hmi_traffic_light_divider) + + CallerHmiViewControlListenerManager.addListener(TrafficLightView_TAG, this) + } + + override fun visible(v: Int) { + super.visible(v) + visibility = v + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + CallerHmiViewControlListenerManager.removeListener(TrafficLightView_TAG) } /** @@ -47,11 +59,11 @@ class SingleTrafficLightView @JvmOverloads constructor( * @param checkLightId 0-都是默认,1-红,2-黄,3-绿 * @param lightSource 1:云端下发;2:自车感知 */ - override fun showWarningTrafficLight(checkLightId: Int,lightSource: Int) { - super.showWarningTrafficLight(checkLightId,lightSource) + override fun showWarningTrafficLight(checkLightId: Int, lightSource: Int) { + super.showWarningTrafficLight(checkLightId, lightSource) mCurrentLightId = checkLightId - if(!HmiBuildConfig.isShowTrafficLightView){ - updateTrafficLightIcon(checkLightId,lightSource) + if (!HmiBuildConfig.isShowTrafficLightView) { + updateTrafficLightIcon(checkLightId, lightSource) } } @@ -70,24 +82,28 @@ class SingleTrafficLightView @JvmOverloads constructor( super.disableCountdown() UiThreadHandler.post { // 小巴车的司机端需要展示红绿灯信号来源 - if(AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) - && AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)){ + if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) + && AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode) + ) { val lp = this.layoutParams as MarginLayoutParams lp.width = context.resources.getDimension(R.dimen.dp_325).toInt() this.layoutParams = lp mLightSourceTV!!.visibility = VISIBLE mLightSourceDivider!!.visibility = VISIBLE mLightTimeTV!!.visibility = GONE - mLightSourceTV!!.setPadding(0,0,75,0) - mLightIconBG!!.layoutParams.width = context.resources.getDimension(R.dimen.dp_310).toInt() - }else{ + mLightSourceTV!!.setPadding(0, 0, 75, 0) + mLightIconBG!!.layoutParams.width = + context.resources.getDimension(R.dimen.dp_310).toInt() + } else { val lp = this.layoutParams as MarginLayoutParams - lp.width = context.resources.getDimension(R.dimen.hmi_traffic_light_icon_size).toInt() + lp.width = + context.resources.getDimension(R.dimen.hmi_traffic_light_icon_size).toInt() this.layoutParams = lp mLightTimeTV!!.visibility = GONE mLightSourceDivider!!.visibility = View.GONE mLightSourceTV!!.visibility = View.GONE - mLightIconBG!!.layoutParams.width = context.resources.getDimension(R.dimen.dp_124).toInt() + mLightIconBG!!.layoutParams.width = + context.resources.getDimension(R.dimen.dp_124).toInt() } } } @@ -176,7 +192,7 @@ class SingleTrafficLightView @JvmOverloads constructor( * @param lightId 0-都是默认,1-红,2-黄,3-绿 * @param lightSource 1:云端下发;2:自车感知 */ - private fun updateTrafficLightIcon(lightId: Int,lightSource: Int) { + private fun updateTrafficLightIcon(lightId: Int, lightSource: Int) { UiThreadHandler.post { when (lightId) { 1 -> { @@ -193,7 +209,7 @@ class SingleTrafficLightView @JvmOverloads constructor( } else -> this@SingleTrafficLightView.visibility = GONE } - when(lightSource){ + when (lightSource) { 1 -> { mLightSourceTV!!.text = "云端下发" } @@ -207,26 +223,31 @@ class SingleTrafficLightView @JvmOverloads constructor( } } - private fun resetView(){ + private fun resetView() { // 小巴车的司机端需要展示红绿灯信号来源 - if(AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) - && AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)){ + if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) + && AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode) + ) { val lp = this.layoutParams as MarginLayoutParams - lp.width = context.resources.getDimension(R.dimen.hmi_traffic_light_bus_layout_width).toInt() + lp.width = + context.resources.getDimension(R.dimen.hmi_traffic_light_bus_layout_width).toInt() this.layoutParams = lp mLightTimeTV!!.visibility = View.VISIBLE mLightSourceDivider!!.visibility = View.VISIBLE mLightSourceTV!!.visibility = View.VISIBLE - mLightSourceTV!!.setPadding(0,0,0,0) - mLightIconBG!!.layoutParams.width = context.resources.getDimension(R.dimen.hmi_traffic_light_bus_bg_width).toInt() - }else{ + mLightSourceTV!!.setPadding(0, 0, 0, 0) + mLightIconBG!!.layoutParams.width = + context.resources.getDimension(R.dimen.hmi_traffic_light_bus_bg_width).toInt() + } else { val lp = this.layoutParams as MarginLayoutParams - lp.width = context.resources.getDimension(R.dimen.hmi_traffic_light_layout_width).toInt() + lp.width = + context.resources.getDimension(R.dimen.hmi_traffic_light_layout_width).toInt() this.layoutParams = lp mLightTimeTV!!.visibility = View.VISIBLE mLightSourceDivider!!.visibility = View.GONE mLightSourceTV!!.visibility = View.GONE - mLightIconBG!!.layoutParams.width = context.resources.getDimension(R.dimen.hmi_traffic_light_bg_width).toInt() + mLightIconBG!!.layoutParams.width = + context.resources.getDimension(R.dimen.hmi_traffic_light_bg_width).toInt() } } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml index 4755ef046f..b2dd4a6f0a 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml @@ -6,14 +6,6 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - - - - - - - + + + app:layout_constraintTop_toTopOf="parent"/> + + itx.init(it, @@ -64,13 +73,27 @@ class MoGoMapDataCollectProvider : IMoGoMapDataCollectProvider, OnTaskListener, } override fun onDestroy() { - CallerMapLocationListenerManager.removeListener("$M_MAP$TAG", false) CallerLogger.d("$M_MAP$TAG", "--------- onDestroy --------") + CallerMapLocationListenerManager.removeListener(TAG, false) + CallerAutopilotRecordListenerManager.removeListener(TAG) executor.get()?.setOnTaskListener(null) listeners.clear() map.clear() } + override fun onAutopilotRecordResult(recordPanel: RecordPanelOuterClass.RecordPanel) { + super.onAutopilotRecordResult(recordPanel) + CallerLogger.d("$M_MAP$TAG", "recordKey=${recordPanel.key},stat=${recordPanel.stat}") + if (!FunctionBuildConfig.isDemoMode && recordPanel.type == 2 && ( + recordPanel.stat == 101 || //工控机采集完成-被动完成 + recordPanel.stat == 100 || //工控机采集完成-主动完成 + recordPanel.stat == 102 || //工控机达到最大采集时长 + recordPanel.stat == 103) //工控机磁盘满了 + ) { + finish(recordPanel.id, recordPanel.stat, "", recordPanel.filename ?: "", recordPanel.note ?: "") + } + } + override fun registerOnMapCollectTaskListener(listener: IMoGoMapDataCollectProvider.OnMapCollectCmdListener?) { CallerLogger.d("$M_MAP$TAG", "--------- registerOnMapCollectTaskListener --------") listener ?: return diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/HmiBuildConfig.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/HmiBuildConfig.kt index 1f4090e56a..24fd2fe73e 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/HmiBuildConfig.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/HmiBuildConfig.kt @@ -7,18 +7,6 @@ package com.mogo.eagle.core.data.config */ object HmiBuildConfig { - /** - * 是否展示 自动驾驶 按钮 - */ - @JvmField - var isShowAutopilotStatusView = true - - /** - * 是否展示 切换视角 按钮 - */ - @JvmField - var isShowPerspectiveSwitchView = true - /** * 是否展示 转向灯ui */ @@ -43,12 +31,6 @@ object HmiBuildConfig { @JvmField var isShowTrafficLightView = false - /** - * 是否显示摄像头图标 - */ - @JvmField - var isShowCameraView = true - /** * 是否展示 sn绑定的弹框 */ diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt index 920e2203c0..6de86e6a02 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt @@ -454,9 +454,6 @@ enum class EventTypeEnumNew( ), //------------车内标牌 obu end --------------> - //------------车内标牌 end --------------> - - TYPE_SOCKET_ROAD_CONGESTION( "100071", "交通拥堵", diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewControlListener.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewControlListener.kt index 5e426155bc..4a1c67310f 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewControlListener.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewControlListener.kt @@ -10,6 +10,7 @@ interface IViewControlListener { const val PerspectiveSwitchView_TAG = "PerspectiveSwitchView_TAG" const val CameraView_TAG = "CameraView_TAG" const val ToolsView_TAG = "ToolsView_TAG" + const val TrafficLightView_TAG = "TrafficLightView_TAG" } /** --------- View --------- **/ From a353fcb025c0f7c0e01366b9421cb30c3dbee128 Mon Sep 17 00:00:00 2001 From: renwj Date: Mon, 30 Jan 2023 11:01:13 +0800 Subject: [PATCH 08/48] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0]=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E4=BC=98=E5=8C=96=E7=9B=B8=E5=85=B3=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E4=BB=A3=E7=A0=81=E5=9B=9E=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/mogo/launcher/stageone/APMStartup.kt | 2 +- .../main/java/com/mogo/launcher/stageone/ARouterStartUp.kt | 2 +- app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt | 4 ++-- .../main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt | 3 ++- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/mogo/launcher/stageone/APMStartup.kt b/app/src/main/java/com/mogo/launcher/stageone/APMStartup.kt index 23f7730be5..3e812b590e 100644 --- a/app/src/main/java/com/mogo/launcher/stageone/APMStartup.kt +++ b/app/src/main/java/com/mogo/launcher/stageone/APMStartup.kt @@ -22,6 +22,6 @@ class APMStartup : AndroidStartup() { } override fun dependenciesByName(): List { - return listOf("com.mogo.launcher.stageone.ARouterStartUp") + return listOf("com.mogo.launcher.stageone.ARouterStartUp", "com.mogo.launcher.stageone.ThreadOptStartup") } } \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/stageone/ARouterStartUp.kt b/app/src/main/java/com/mogo/launcher/stageone/ARouterStartUp.kt index c539080df1..15c913da9b 100644 --- a/app/src/main/java/com/mogo/launcher/stageone/ARouterStartUp.kt +++ b/app/src/main/java/com/mogo/launcher/stageone/ARouterStartUp.kt @@ -33,6 +33,6 @@ class ARouterStartUp : AndroidStartup() { override fun waitOnMainThread() = false override fun dependenciesByName(): List? { - return null + return listOf("com.mogo.launcher.stageone.ThreadOptStartup") } } \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt b/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt index d2093e3b5c..2350e3440c 100644 --- a/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt +++ b/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt @@ -154,7 +154,7 @@ class ConfigStartUp : AndroidStartup() { } - override fun dependenciesByName(): List? { - return null + override fun dependenciesByName(): List { + return listOf("com.mogo.launcher.stageone.ThreadOptStartup") } } \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt b/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt index 8c4aa9dc6c..a189438325 100644 --- a/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt +++ b/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt @@ -70,7 +70,8 @@ class HttpDnsStartUp : AndroidStartup() { override fun dependenciesByName(): List { return listOf( - "com.mogo.launcher.stageone.APMStartup" + "com.mogo.launcher.stageone.APMStartup", + "com.mogo.launcher.stageone.ThreadOptStartup" ) } From 982fa018c9d50d7196e6ac225097790beea5bf4e Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Fri, 6 Jan 2023 10:43:16 +0800 Subject: [PATCH 09/48] =?UTF-8?q?[Opt]=E4=BC=98=E5=8C=96=E8=80=97=E6=97=B6?= =?UTF-8?q?=E5=92=8C=E9=99=8D=E9=A2=91=E5=88=B7=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/function/hmi/ui/setting/DebugSettingView.kt | 10 +++++----- .../core/function/hmi/ui/widget/SpeedChartView.java | 2 +- .../core/function/hmi/ui/widget/SpeedPanelView.kt | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt index 81460a5ce6..cb59e84424 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt @@ -217,7 +217,7 @@ internal class DebugSettingView @JvmOverloads constructor( logInfoView!!.onEnterForeground() } // 开启定时查询速度 - Timer().schedule(timerTaskRefresh, Date(), 100) + Timer().schedule(timerTaskRefresh, Date(), 300) if (AppConfigInfo.isConnectAutopilot && (AppConfigInfo.plateNumber.isNullOrEmpty() || AppConfigInfo.iPCMacAddress.isNullOrEmpty())) { //查询工控机基础配置信息 CallerAutoPilotManager.getCarConfig() @@ -1688,10 +1688,10 @@ internal class DebugSettingView @JvmOverloads constructor( }" ) - - tvAutopilotInfo.text = GsonUtils.toJson(mAutoPilotStatusInfo) - tvIpcInfo.text = GsonUtils.toJson(mAutoPilotStatusInfo) - tvIpcInfoKey.text = GsonUtils.toJson(mAutoPilotStatusInfo) + val autopilotJson = GsonUtils.toJson(mAutoPilotStatusInfo) + tvAutopilotInfo.text = autopilotJson + tvIpcInfo.text = autopilotJson + tvIpcInfoKey.text = autopilotJson tvCarInfo.text = "GPS时间:${(mGnssInfo?.satelliteTime?.times(1000))?.toLong()}\n" + diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedChartView.java b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedChartView.java index f6d69a53ee..47a53c4ce8 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedChartView.java +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedChartView.java @@ -178,7 +178,7 @@ public class SpeedChartView extends View { setAnimation(lastAngle, currentAngle, 1000); lastAngle = currentAngle; //重新绘制 - postInvalidate(); + invalidate(); } } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedPanelView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedPanelView.kt index 3d5b7cac37..46dda6467e 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedPanelView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedPanelView.kt @@ -80,7 +80,7 @@ class SpeedPanelView @JvmOverloads constructor( } } this.timerTask = task - timer.schedule(task, Date(), 100) + timer.schedule(task, Date(), 200) } override fun onChassisLocationGCJ02(gnssInfo: MessagePad.GnssInfo?) { From 62909feccbf9806d9de297eaf89f395cd7c4739e Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Fri, 6 Jan 2023 13:00:34 +0800 Subject: [PATCH 10/48] =?UTF-8?q?[Opt]=E6=B6=88=E6=81=AF=E7=9B=92=E5=AD=90?= =?UTF-8?q?=E4=B8=AD=E6=95=B0=E6=8D=AE=E5=8C=BA=E5=88=86=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=9D=A5=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mogo/eagle/core/data/msgbox/DataSourceType.kt | 5 +++++ .../main/java/com/mogo/eagle/core/data/msgbox/MsgBoxBean.kt | 1 + 2 files changed, 6 insertions(+) create mode 100644 core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/DataSourceType.kt diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/DataSourceType.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/DataSourceType.kt new file mode 100644 index 0000000000..60561f77de --- /dev/null +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/DataSourceType.kt @@ -0,0 +1,5 @@ +package com.mogo.eagle.core.data.msgbox + +enum class DataSourceType { + DEFAULT, OBU, TELEMATIC, AICLOUD +} \ No newline at end of file diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/MsgBoxBean.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/MsgBoxBean.kt index 7a08d71212..9c370be85d 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/MsgBoxBean.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/MsgBoxBean.kt @@ -3,4 +3,5 @@ package com.mogo.eagle.core.data.msgbox data class MsgBoxBean(val type: MsgBoxType, val bean: Any) { var timestamp: Long = 0 var bean2Json: String = "" + var sourceType: DataSourceType = DataSourceType.DEFAULT } From dc50835178a8bd0c1a2b309367fb5deabb12474d Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Mon, 9 Jan 2023 16:40:59 +0800 Subject: [PATCH 11/48] =?UTF-8?q?[Opt]=E6=96=B0=E5=A2=9E=E5=85=A8=E8=A7=88?= =?UTF-8?q?V2X=E4=BA=8B=E4=BB=B6=E7=9A=84=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/function/overview/vm/OverViewModel.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/vm/OverViewModel.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/vm/OverViewModel.kt index eb67733969..9250e8fd6e 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/vm/OverViewModel.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/vm/OverViewModel.kt @@ -8,6 +8,8 @@ import com.mogo.eagle.core.function.overview.OverviewDao import com.mogo.eagle.core.function.overview.remote.OverViewServiceApi import com.mogo.eagle.core.function.overview.remote.V2XEvent import com.mogo.eagle.core.network.MoGoRetrofitFactory +import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger +import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable @@ -22,6 +24,10 @@ class OverViewModel( private val _V2XEvents = MutableLiveData>() private var disposable: Disposable? = null + companion object { + const val TAG = "OverViewModel" + } + val infStructures get() = _infStructures @@ -90,8 +96,10 @@ class OverViewModel( .queryAllV2XEventsByLineId(lineId.toString(), sn) .map { if (it.code == 200 || it.code == 0) { + CallerLogger.d(SceneConstant.M_MAP + TAG, "请求成功,size为:${it.result?.v2XEventList?.size}") return@map it.result?.v2XEventList } else { + CallerLogger.d(SceneConstant.M_MAP + TAG, "请求失败,code为:${it.code}") return@map ArrayList() } } @@ -121,7 +129,12 @@ class OverViewModel( if (parameter != null) { if (parameter.autoPilotLine != null) { lineId = parameter.autoPilotLine!!.lineId + CallerLogger.d(SceneConstant.M_MAP + TAG, "lineId为:$lineId") + } else { + CallerLogger.d(SceneConstant.M_MAP + TAG, "parameter.autoPilotLine为null") } + } else { + CallerLogger.d(SceneConstant.M_MAP + TAG, "parameter为null") } return lineId } From ce2fdf57ded3ec80fbce3382a6e6f0861f830a24 Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Tue, 10 Jan 2023 19:25:21 +0800 Subject: [PATCH 12/48] =?UTF-8?q?[v2.13.2][Fix]=E8=A7=A3=E5=86=B3Room?= =?UTF-8?q?=E5=B4=A9=E6=BA=83=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mogo/eagle/core/function/main/MainMoGoApplication.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java index 075c51f3b5..5468dfa427 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java @@ -70,6 +70,7 @@ public abstract class MainMoGoApplication extends AbsMogoApplication { initKoom(); } clearMessageBoxTable(); + checkMonitorDb(); CallerMsgBoxManager.INSTANCE.queryAllMessages(this); } upgradeProgressListener(); From 13cebf3b06c8879928c99500c8fde843d3cc756b Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Wed, 11 Jan 2023 14:05:07 +0800 Subject: [PATCH 13/48] =?UTF-8?q?[2.13.2][feat]=E6=96=B0=E5=A2=9E=E5=85=A8?= =?UTF-8?q?=E8=A7=88V2X=E4=BA=8B=E4=BB=B6=E7=9A=84=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eagle/core/function/msgbox/DataManager.kt | 1 - .../overview/remote/V2XEventResult.kt | 4 +-- .../core/function/smp/AMapCustomView.java | 6 ++-- .../eagle/core/function/smp/V2XMarkerView.kt | 34 ++++++++++++++++-- .../src/main/res/layout/layout_v2x_maker.xml | 2 +- .../drawable-xhdpi/icon_v2x_obstacle.png | Bin 0 -> 16798 bytes .../icon_v2x_road_accidents.png | Bin 0 -> 15743 bytes .../icon_v2x_road_congestion.png | Bin 0 -> 16210 bytes 8 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 core/mogo-core-res/src/main/function-hmi-res/drawable-xhdpi/icon_v2x_obstacle.png create mode 100644 core/mogo-core-res/src/main/function-hmi-res/drawable-xhdpi/icon_v2x_road_accidents.png create mode 100644 core/mogo-core-res/src/main/function-hmi-res/drawable-xhdpi/icon_v2x_road_congestion.png diff --git a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/msgbox/DataManager.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/msgbox/DataManager.kt index c394ba105c..4e0cb392df 100644 --- a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/msgbox/DataManager.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/msgbox/DataManager.kt @@ -3,7 +3,6 @@ package com.mogo.eagle.core.function.msgbox import android.content.Context import android.os.Looper import com.mogo.eagle.core.data.msgbox.* -import com.mogo.eagle.core.data.notice.NoticeNormalData import com.mogo.eagle.core.data.report.ReportEntity import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxListenerManager import com.mogo.eagle.core.function.msgbox.db.MsgBoxDb diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/remote/V2XEventResult.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/remote/V2XEventResult.kt index e57241ae53..38dcae72a6 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/remote/V2XEventResult.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/remote/V2XEventResult.kt @@ -38,8 +38,8 @@ data class V2XEvent( @SerializedName("radius") var radius: Double, - @SerializedName("type") - var type: Int + @SerializedName("poiType") + var poiType: String? ) @Keep diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/AMapCustomView.java b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/AMapCustomView.java index 18134d8151..0eceebdb66 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/AMapCustomView.java +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/AMapCustomView.java @@ -263,7 +263,7 @@ public class AMapCustomView LatLng latLng = MarkerDrawerManager.INSTANCE.coordinateConverterWgsToGcj(mContext, center.getLat(), center.getLon()); markerOption.position(latLng); markerOption.anchor(0.13f, 1f); - markerOption.icon(BitmapDescriptorFactory.fromBitmap(getV2XBitmap())); + markerOption.icon(BitmapDescriptorFactory.fromBitmap(getV2XBitmap(event.getPoiType()))); markerOptionsList.add(markerOption); } } @@ -276,8 +276,8 @@ public class AMapCustomView currMarkerList = mAMap.addMarkers(markerOptionsList, false); } - private Bitmap getV2XBitmap() { - V2XMarkerView marker = new V2XMarkerView(getContext()); + private Bitmap getV2XBitmap(String poiType) { + V2XMarkerView marker = new V2XMarkerView(getContext(), null, 0, poiType); marker.measure(View.MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 229), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 96), View.MeasureSpec.EXACTLY)); marker.layout(0, 0, marker.getMeasuredWidth(), marker.getMeasuredHeight()); diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/V2XMarkerView.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/V2XMarkerView.kt index a776a29073..687ec34f1b 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/V2XMarkerView.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/V2XMarkerView.kt @@ -3,14 +3,16 @@ package com.mogo.eagle.core.function.smp import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater +import android.widget.ImageView +import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout import com.mogo.eagle.core.function.map.R -import kotlinx.android.synthetic.main.view_maker_with_count.view.* class V2XMarkerView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, - defStyleAttr: Int = 0 + defStyleAttr: Int = 0, + private val poiType: String? = "" ) : ConstraintLayout ( context, attrs, @@ -19,5 +21,33 @@ class V2XMarkerView @JvmOverloads constructor( init { LayoutInflater.from(context).inflate(R.layout.layout_v2x_maker, this, true) + initView() + } + + private fun initView() { + val iconView = findViewById(R.id.ivIcon) + val contentView = findViewById(R.id.tvContent) + when (poiType) { + "10006" -> { + iconView.setBackgroundResource(R.drawable.icon_small_v2x_road_construction) + contentView.text = "道路施工" + } + "10007" -> { + iconView.setBackgroundResource(R.drawable.icon_v2x_road_congestion) + contentView.text = "道路拥堵" + } + "10032" -> { + iconView.setBackgroundResource(R.drawable.icon_v2x_road_accidents) + contentView.text = "道路事故" + } + "10025" -> { + iconView.setBackgroundResource(R.drawable.icon_v2x_obstacle) + contentView.text = "障碍车辆" + } +// "10031" -> { +// iconView.setBackgroundResource(R.drawable.icon_small_v2x_road_construction) +// contentView.text = "弱势预警" +// } + } } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_v2x_maker.xml b/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_v2x_maker.xml index 8a5ee087ea..d105f5057d 100644 --- a/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_v2x_maker.xml +++ b/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_v2x_maker.xml @@ -19,7 +19,7 @@ /> Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91c%TCS1ONa40RR91cmMzZ00`n$?f?Kl07*naRCod1oe8w1Rdwgjci($8 z0L4%!piqcH6_j9zq5%}7M2(b6h*1XP5L?aQT8W*Nv>i?CUcFYEsEM&{W4et>)TnJV z$x0OC6oJACC*s5)g9u15Q&1E&zIX5K|L?!|`R;dLy_%qkA?LmCJLl}_?6ddT=bUf2 z_crA}KpL)CvEb&-H!W=j!=neoa`dni@`IXwv#2y>A9ZmN$8a!QRECW}WnCE#)(x9x zT{A4}hGnRFxkLFirSz^I4x6ic2M(@%;;I`qJ=)EqzCQZWEze%Md^kOG`e0C=Bd44o zCmk*asW1FD^4-9l0@MtLA`wgwiY|Z!po9Se3{IrZ1nrsPCZR7Il-{bT;ozbpF2C_A zcpgoO{ypN;Ei0BiW;i{4Rv8RWm)TD*P48elq)3zQ%JF9u?I61bN6GUBhrgqrBDW)r zF}vs-)nXU~KVT0Egd~l*o7AGs?c$49dsK;S(1u{layd5&lR^k2nY4_1tC8=uh`wClj8lDRn>FRuM*W zq>?k08UUQA!|?J5P63n-^wbQYVJSnLmXp!%Foy++&^mJAQ3dYU zS#^?0T+cEvGen)DllcP{1cJ(YCQW+WXWvUIn7RyPlPz10xsWSfguo%dg=IML_N70$ zZdD*3-t)um;5EOzY~{>M|E)6X$u)W~RtAl|;mwiEH`LAt0CnTFRgQX{I&nW;vb9ZD zWf}x|O*Ep^I?!b}8ARc9yGwL+#;~yv4eO{G#$P)YEtNsjluL(A@6V3D@~2-A_F+rb z`Qd2&u3uhyqSn;+$)YDW5}SEp!0F86b_7Q2_=V_p|i{R~_Ji0T{XD zqG6Cw9`Cr|Ovg2KqS{fM@Q7%nM5^uB*B)#swU@&awVUQLNq^(AD{uIA75`A?aC7Qtvv%du*J>mDPFZI$o*MSUUG9In&Q`%8th*Q#z3gyhxh8iV zWVIm*AubHO)`qc-a-^s6p#T`sm0rMU-DEdGV+}lQi-&e$?FoU%*b#t;=Ivl{v<^lj zbuTF9UDKOr-u$F1e)?fuZXs%qr}2L6q2@N6b>x!Go69F;l2b-aFuZe3#i0y$A~}YA zkflL&2P)QFEQeX_A+j)dTStxvFsWVUdO+-iS#{G`R>+0ZNiZB3p&KBiNI?^Lys4x+ zXGYQ*CD+t&+6>Zr?q`twS)r*bU3N7LFDEq&3JEzS33gj4LLFoW8} zs8}PMXP@L9C`Uj?E7z?lrqsbepcu8WvbRWL2pJJ$=2E~!(1cThKZXKwV)~|pM%zdk zbY!UGHdMAMsgI}Z%I=11rIQZ^r|62|vTK$<=|vsr9w}C}cDwN5|5!1(_PeX!t{D46 zEa5=m#6P3iiI@Sv#z)Q$e@Ea1X;4-AzJTdjrtg?1LpB)Wh(5_7w(UOEV@(!?Z&Zj( zc=Llp9_pyfUT%=`kv0IPwm}oDCIcb1T8>B;OoPsQZ_!zonnO>L65 z; zG^rhoIGd_<5_LH0z;Qcn6*|GyrW@-zI5-TheAdl;W(%I#4wfQP-|BF3A$dZNkpOVj zzzir%Q1aRxD)$Wuz2;l}smXJX{^2#NlY6&iwf)^DaNSFmE-(Gzm(-!d95M6~r_zFZ zq+U|d$*_b+Z9*_XafmYG$?IBY0IXOF)kO^qnk>gMQoHms2Ndd;s^~oE^)@P;&pGPKYj(>Wu-y{D8(y;P zJoV_a>OeX-dxOSSoO+bqOP`X4vLh(!8q)$qqy;lo;W&(nGDbCD6jV_aSWPNNT?O&B zDCBsz4h&g}e&a*F+lMiujYo+VgaDNz`U2Llru#^m+P3l>qM>4lrZu(KA#yzc?SLE% z7HTu{FV`(U^4wXJ52%XT4=Qa^xjs`5=#Fe*SVnl1I&vE&q{=x^p}{v;J!_$ z!%26-Cu@(E(HUTgbZ3CKuu4lVa7JT#^CL`V&N zo7lIL;2G++kGaRLgAJ0AB?~@eVP@LLbOuN3eyoU7qH0}26=W;v1kSRu-pYa?iLAEk zsXw%BAE~G+J<#5pEOyxDHJQerD)FCsiov6V+=M!%Y*&q5GcnPe_CR;n4=93%XCHs4 zI`Snoe;}P|9V+c(M5lH}>V)#>ZQbp>n3`G`^!8A8ugjkuHaq2z740ChOG`cJ)h70I zqY&4Kq}(GqK~avwBq}-&t|$XTj1qa2qfO2(+4GgEB~oEju6jc6NFFf@Vks#<_5|3> zdxODXalb$K!q1Oib|~U@HSMy4xkI(7Y~Uuw5;rE@P~KBzHI^VYt_<1u5TyWdR|wP zl>>4e5HeJ+Da&0@MRoHYmrUs}J3Flx14Y~j;4n>As)fZ0gycLcK~*terCWHsqhrp% z^hKoEJBXu_fRPkrjFKa{B?U9WMkxfCPIm==cIWCp8*%SkX(Vwc=r^6W^hLT~dx7lP zX`fE2ijmW3)sKb=Y&?ph8m8yAQ}1 z=>|7CJL+T%u;^fk0+RQe=By(xzxH2M+^J+)J3~1<@3OGSQhYI%`e2Un1o$Ai{P;z?p)xRoOYKq3-GD`pW1&3I{w=1S8qA6|Xjaj`rm zYXJw8YzSY9^P!kms8RSJ1G(+K33b9;zc_lKGv>AYgn$AmWw!>PMjjMldMa&E3k*2 zcIy$nsw=v2x`Ww3;i%KB^zpKU{%(^#;hJzBLfj>ql@-)aGt_l_DE-_gn%AE+RyR>n zHOZ$gT0yW*z}2nATZYpg!zW1HQG#=aY5L{IyjB8F-98~IDy4$9qqK=0qOforN-mST zHp;V_a%v4cj6of(sEpGEHV!8_wbLWYx$D=|22_7g(Rw05icoN7DB9@-6BdYmIj4$M0)%KvVW>(MG|?=EF&uG_rtwC1fdXFX%qx(m zT8W53?1I?Ujv|km4TWf~o6#poR8~O=Ii9VFP8E=2%)EJJ>gXqzsbh{S6N?{PdIua( zCJs2TH1ijf;r;iQ{<^hgu=c((ef_m%!)4zo{abH!yTlm1whY~UV}@Z6>)$8fE?Ya5 z5+F(%Hx7K5!5}!p;VA3DtXzhmmDuAqYntA?V|Mh8mvsthbDy`oeAx#i_BT^QYdYp& z&t1WbE@9kM66qKa)s0l$dSI8yqkTSNXJNSORUpW3NS#=5R3b z?NEoI|3zh2h;%RiODrVY9@8abMFJh9MjcF;4IyB2x~E=6KsKo2T3b{DO?mjJ^N zBYM4IkH1OcJpTz-T=UyeoBQnM=0=sW<-DaQs)0+%nJvFdu~8_j3?GD(%|cF{{oC%=)w3<@vK*U`6fF(pqt z?y$1=%3m#0dW7vYTTZhRu^#9!G zv4IC5X@;vU>C1$sLF640S)GpA9PM?+S!LlVr-x%5l|*PaN{Qf+Gabz}iqo+%0Fq9; zGqcpVf`V9M=Y33DvO7wXn-B6H*F_Xm}qOlYM(*LT%LqbusOl=Kral)gu9NfxCI0%h}1$g;!=Wh%pZrT-Qe<~SwWIA;2l$E=Wc7aJ<+Zh$k>O>I(5gb@YG zLQKKkdesUcbWwHF=D5P>@$cR^!bDSd(Rw19ZPTt21`>T$p-$1pAzvTp1Rc|}O>&Ur%2 zlBlgI=|S7EsvGN5(wi0n{b$4jY6pTVs3Zb8iKvDSr?O)vpa0a8%06emT9K&noKe|K zO=-fxv65XQRFNBZ+9t}CuRgDAy5sg}$og23vi#leEqkwcp5?&TRHsJ7)6uas{gbPP zH=lEsT&t*6TXD^-K*t_kO4Ntj;j1%tOuPdnaa`I#hbf%YN735EdY|j$!+&ta*yocO zQe$Z_GyVE8KwCkEBv-*SNUHUyg+Xe$n~UBoiZYDo&NwROkO7}PC?4cz8E^HL-t zn*jrdOr7oUq+^sDrxUU)#YBS3f_)A1y-#^g=`DVYLIy{S95S5HTSgo>MmLg&dTqjM zs~m>okd0BTqgrXjgM)^Ffpd{-V%ncO9q`6KC<6^5e1Ib`dInweiMmnYJ`sj_&Ka)6hody+;Ij7mGbLmH5n3fQvZQDn+^CfJE)1o7aOxyvjB%>o z(xpV^9sRq;$#~f4762W{Y3CS))^3o)?K^Me3TGXBEn>f=8+gJ_!=MXDp28N^Nk zM?~V>a2h`IZGPnwqN8j-!h@{fOQqDUO`2AL|zUfS))->ke{!m|dQdI^c4cbU{YeEuL@gFjvZxe{oVU$nNCCI3b zrsxU?jMqQYi$*LlVgqNnwQcEUTy2Y(fS%{NeYW13qBRKS=?+zI(SG4PM_oo-jXcBT z^u!Uxj%3yCT!LF|SYJ7If^rT3>64nG-;UEh&p#t?+*noFK?>6kv04%*4*IC04yLe4 z!aI1+q81>xYDSF#XnC*dYJ(e{hQD>fV87$kgFKa`5Dkf>PBHtit@`pYBL=wAwM9NKL0kWCNG;fhjk= z`p)dlD>yio!$xFNwTsTBKl7jdOZqCdMc(*%BN%GCj?(DO;cjQ$Wx)WtOs)f`#r(~@ z97mNP)-!H7;RLNoky;0r%^S`Vk%n_(uoh*WbE?4KSTdNACa5h-LrE7bCO4PYY#SzI z)*hum?((!YGegQuIq^`Q?nhJdg6O%O6Wye9b%z~J4%+#@_>7oN(|I^Cu49R0Ih9?t zr|xj7qf_hjP;0U-i?l&jWN1^>b1of;t_PYXC!2kqy~5mn*;2aKwbZw0tMxFbjq0{+ zP)^|ka|C6F4%^i~S$T3ey;;7D)H+zZywfYtxf@X_Y&Al;&M6vg@zw`2;Y=d{GICuF zSjCA9V?jsg#T6?+!FH6QovO%eo!hR* zL~PwKRYzxp6UovYiESg%Hp#mB9!unSlp@5N zO=w9rmt2f~{P&vY1VUY`1))zjotUF>QC0yeTBwYNfV6qAng#+TtSbVOQ*R9-BIr^c zrb7lhNr0#yynLyL+)v*Ufiu|@ z=@>mMAaZBH9L;jJ;W(LfO$yk{a;`#dAYFR{T>ik*ZBzLlxMlUBH)7gIya|6*5APKMctz@-dNyIMP)6zQg?LMW;+$ovU= z1QVIc{bB)CO_}pfIJHb3_w>?x{NdgR8HbZtkJEt@haO%AcCeytUtR4nHRCYRdF@Rn z$NDSY*|?MgEmJc(wh2d|8-{s+Y2rZ5DrVOyMRmoE$rpZh>b6|PFdzaR44k7reY%R_ zU`-oxu)tu0Zd^7TcrQ4OGbr4Wa4~jyt1%#~e85~u0AZ?j%?2)qDRr;8!uOuEyzG6( z*`?7dG&rP2VEbUeP6{VZK5mHz2LaDiT_e{#HHtkQ<8V2jKIim27RhZ7nRBF{$Rn~e z0lE(+*yYn;-MSHvnr0jm3UP^3jYNx>(pFI^;I!*y!#JIkY&oG#ndH_}Flo9%B!3+d zT*}j67$vxB1Iq1OxI_WiN8*8zR7C+pah!;0%ykUeO#pRZcn7fBqB&2|T*iu*HE-T& zFD_H3{4#{Hf{yA8>eXR5IGr|e*b$N!vbNlFPeg6yX`@%(YGoleBb;cTosdPhb@DFV z_*s3K&9j~Q%$;|rb73P)5W|O@HekdkQFjfyNr!N(hnm>2Yj8tDvPRYRBftq1Cx@?D zv0ym3_3)8cLERXTFjhzy!Gk~zMf*ulC3(!?X4A>IEbtgCQpy%jI8;!L3v_3EO#RYn z;oLUTm~PV{kluA$8QiCr;O@OgFT>sEi0!M4gE^+});IlnicTImx{dlA5O%KNqM4QU zJ@KS6bNAh0Th$=8AK`=&lxpM>wCJc0x zNYxMK)X5aRa=1R~vOre5ZK>ppdWcYS>BQWm57`*fN&}us)Eo*xR#rIyj2w6bi|s(b zP}-uv(@_*s)H>S1>F6DPRGD|i%LJ^^scX~q_m@rI{%YBL?UiN2Pp>J%&0E402-AT$ zig7Asdd=NBP3s}QzVKZGW8AsORhMa>K{H1>=xy(s1Nz`Vn{T{P>Wy4T2QV9EjL$L& zCxg%r;7--1wXQrO8opD~n0t9;+rFDZ{f z8P;5GUf}GVOv5c(H0U(5%}#m=el$hSMsB-)|AjSr!xpI3%Yp7*2*6^2n@ka87U-g8 z!ZcZ@5n(_I;Y(Lj1c_XbGVR*+UJ|34t z=!0^N;{q=x%-g|JED)ipB?&(#TT4s?TAQoe_KQN6y!#Z;f?APi7fk`^x%= z9P6J21~8hV3`M3+5$A4f9p1P#rY+O0CIpo($8biUSUq99V_B*G8lQLL{xH zpDG9#NoYTl&~yi@Rab#2dg^#RGbMU`{W_t`qOVJoyPi$UiE<$7`B9!78xb3CT?h_N zC!DSAlnr~^2meo*`N`$c{!X5)7b??F>EKOEc3~$)aJ4X8{gyu}!;PETelX~`G-Gfw z*jYRMM?dqhqgAF|{>XLmVaHV*sDxLViZ^vLR0J3OI#?%x*lMWKNfPTHxw$DQwT;7; zgk+V+L?#Rv^by3OS0~v$<7T~-K5;A$=woVzWBvEOY4MI!@i|Im5I>`p5`Gx3dd0J8 zVE|C)AhMYX%a+aM#y9>}87P`}Ho2c_!(COs)XXlYHSc~`x#yBqS~hZEYVdk$wor5p z^Wk(F@+4SWL4V55RfZ%F5R?N@^A;#HWsKZg#4b7_*xZ73ouq0=0-og-Zva3YBsobk z>{m2JUR3gFQLMI(Udb3amnIv%@o=i&Zmid-Ggo}S^w+Pm%oy38*urs=&GXslsM^tP z+E>z=GPq~M#;d2hCwk1M_p)L+nAUAVHcm@E`0>&#SQsjA=e*alW6I(U8%;qE=?YzM z=IhDTPNemp`RCzkP0cu$eZ!=5#^jjA15y%wKS}^Q#4?4XF_Ie-hK8*`AZpb#Mg?~p zT$TovlN{U?Sixw~g<^x3RM=IKJUcS)N`q$QO@Pj zrtfNVB?6Clq)8l3jR=sjgrsZUP0EOTe+LqI7mJ}ld+e%vIw_ES17-b>e^73E&ADaC zdp}Tm2k9~6cGBYCe^Ys&Hzn7e|AFBR?|f&OVhO>yc5=)()?fW+YL2oxslH*Yj=8K^ zT5y|McJbynB~~3J1{Gm4f`I1$R^iT7Hx9#+M)jbTs4fpq*R?2{DArd70U&om1%d5k z?p*csG0usjo-F6;s!h&C{`zlyl}1D!1EYH@5699LM)FjI!AxnbWH<(f27{nc*38e; ztv1(Rd3m|!++Qivm;cc6cjsxic~iOdO@B~s`15z_Wf7)e4s__**|B_Rnr4rXgVpmi z{b~Eex~xNZ_bto5rCQ7MJry@+Jyjm?K6>kjV19X1PseE^*>HptUQnS*qhgvC(2_+# z=gKP*7onG~IF|#5x;!;s*ON~wlX`Bu;H+0FJhk?+!BQt?uKYonxqqFE5RPkQBN3sg z15)%j%dL!h)ri~Z= zTlx84yrXQ?M@OgB9?sqi|>%iAjNJI=Zh`fxA=6J!7O!qJxKB z_CV7B>#_&j%uHE*{s+pfpZa83@`m3l`@Zzt(&&?cyONlhroZ={a?5+(UDjT9ncJC+ zjg(dzJ9tRDK5(}5AaXrDW6=1IrAs(f)t~5*vQ7d9Hf#u0B%mt0?+J2-U`x}_=f3Kg zZ)m-GrtcHNX9R*&q27TxEC9%8C}It1m?9^PN0aJ!1rbFe51aEYm3GSu-~7Kyvp=uY zFeQ&1Yx&e2$q~)Nd)Jiy4cFj;;8jXU^!Bgc6{hm+k}<_UfUao$8f;yQ>U&h%>nUt zhMkKuiQsN7BUQ&Y2R*J#9&%`zeCFw4kkr8gaP7TixaQ8d{LvSr3}@u<{)}?{zJ(4x zKFU+2Mvn}eefBB6efCwZ-;7?QT*u~bf3w{D7k^eZu3qf{eb2WpEgYUU)z0L8`+8THr!|koNUUh z&}6VzWYPk!J~B$u!ws6E%LK0(h$JXf z|6iB>h7A%Bec;Rs1?$(Y9UEBfI*RW4XE5*wT!EU?@VK+9bD_g%OwqPaYt%XPu4V;g zFPl4x$(NJ)ICJs=6vrJ}gPW_vQz$Gf1USo1rEWmLLDss(QV&ti@uWKuFq5hX3C?wW zUu|e|w_Kxi?&!r@nqWL|khfwc#!Kkt=gQZvak!4Ds*PS~4q%v^~_nu{eIz_irvy8zYc$m`6wO5x-`i_nD-@mNfr_Ixh z)?FN^US`D7<%n9G44kRiYq2QoX!WbotE7FRYNGKg#42;yXB*-O6{*gd=0LQdw$S0U zFqTBM)imcc!`D3JDO#s~)V2VVjvT<*vbbQ3Q-mXACUPNhB7!#u3j+YB@?sQDk;>~sV;dmgg4s0_GR^P05!0ytQpxs;g_iEkOC0wH~ zP1~Tyi5sid7E;fYc7)~jtFPqk($z( z71VWBqRaz%P7jsSpsb)+D2Ij$V-gO=xjJSp`$k#)(GOX~ZJG{m``l;BK1VMvhrIH& zW#RMB+^L5HA$0egx!&D!$wlQ}ZMg2&x8$I;Z&0Wc_xmpzmF*)&Hd~JJdyHMI_q( zNH$>LyVG!mnK}80Y$ZmOf4!TkSE2aG3Py{t4pwHfx%X{gt1H+|uA=1(bX85WlDB6u?^->@q$2r4hMzrOIb?tMcdPzrXzW z1*ev^A9&ALle@FBDp~W5=#76OoyH0e?NJ96MfLu-fZgL_>CP^RdgXk{-922`EH9DA#(; z0SL@UMKue|P8b0gm80=`0nDA2Fc=Qh!8gohn$m~H{Jaz=vkMi!rIRc2<4Mx6T>n?^ zDTCW@scgG7|Ji?gOWAbGt(NI1q7Ux7K<=`fseIv5y)%|6?jC_;5X5?lN$5T7bzOAc zLS0A#5n_xW&T>>+n8>?-aAQZ$cq|XI56kM^KL4vJ~NwBQ9VDf=wfM?ytduP6OzP0IVOkKi=D-!i?UuiK4# zA}xN_DN-Fpb)a`9bSCw5LuBuhPcHkt^}h!|=b>J!tyc)~Ed*k(yfyC%%Q7yK5ziu`-YXjX5>qh-Zs>gNF=2o8&&!P7gPzuRG4mD%8yP-0J+7)$0KgG41nZH4HvTi#X_WoAKd>N6GGPSMRLFVpk4=8J(4D_U~U zP#dADGv|}40^m@+!YR`Wz>0X^({+#KWWnls)Z_yZ|U2M>~=ny`09IM}e zqU?ePa<}C5wA#Ab363soJLSq>>9wSNQP;onWu(@@t~R~DtB9yey{>SaMyJS0ZJ|>( zz3MfublGXMa^kk+qdfUBsO_OhR%+MZ+OKLSJ72b}K~Qbev8^37%dxG~L|4nUE5oM4 zTVWnZy~!~jjyrhqp%;iqH(R9{$~kgXKv=6RJ;?@W$cHk>SajiGt%hE7&V)fhn*kJ- z;6}%zJ!yv(FGi?;o}y(BoQQp}i~pnVwvTM%s|oCjoqWhDO!c1bm3!A#>!PpAfOsee zzjDf*13p=M?YxBxFX)v4TG=_803u206}Z{!a=Vw z_NnFz_;8fQ9Bgni^&vA+$qtOj)gN}vI8K91+8E`jNwjfYXi(=w6QY9$V|aa5otNw$ z<;j;x*)^L&{i{)i?RYfki0t+gli@7>og1L40d0;meZ`T^gVyvox$E>QL%Hr=o!@PW z@>ULRKJkO^O3+uVK}(Hywv#|hKi?qekTMgYz7v%w`20wFB$&$WS|$g&SMFpuD0-Y_ zjBg9nzRwa5cpIo$lx@|MMDn=Vlp*t8IPa26wt7mlm4lI_w+{Z)>#!9Rphg|SJStOh z)%oh9NP=ae}GMv-rTc29I3WT^wa&f_31XT8MbK40SO#7_5rUA zRSQ(+NElhOLt-lX#Dsh{N1Ah|(|r5~s|M#i<(m@qOgjykk{IK)imuXB2L}zQo72#4;`jo|cWxhWI4vECfI^Q9=FpD_TaJ{G?Prp z%~F(UClt&Ul(}vu+Jk^odYM|JnvWP0K1&{w^ht@g&8DmMZ9Di=KmNkt<-hPf3D8IW zl;}OeL${75xqGe>ZLz9e&1bWThgVy7GR<6fwarkcxVS$r!(?Y^CDaJN`}rOL*SlCNub<-_7cem035M{RAZ(~h;PgsExGD)~<5V{+AIueogUqD$ud%_L-Q z)4?F6@b5|y{j?oduJl9)nHq_;R|VE*V4NJe;2{960}{}HB2%vSv+lVU=uV|gKmJks z5CVr0k3=z%iA)?#8)F8xWU!g6gvwPJR8nY=p5%A5(JN~YJPVP?iRFt2mk$#zTH3P7e1t^`ZwuB7{{d)Kxb4$8FC7> zb9Gv$js*>uA=3HNH(ehurSHUMYt5HG?+=e*#Q21v984H%Z~?PujEo93*+9@JG9hqX zNY$a^3;vA%tE+o>*2+ob3%+WXCl*1K(umWtLx11m@e+I3ebN3~!!tW1d&BTN)@ zM4h5WUu-sW$(LJ++bRrxeq-5q^-r|vj!)=K>63X=x(mi93g%7eP(G!1oT&TzI-F1H z(|vg)?UcS7nh%AUPPi!_@aZ!|$Pk`)nP+ajrEK_rpV;OSGSt^O4fH!moBrX`W%Cuh ziJ}<=D>9ovM!(mq7ufXcDEd94 zGJX5)W%@21x7}Vg-*CP1+uCQve7H0oq%%!pRJA2}o+44uDfOv_Onn`$NkP=2H=j?U z#BQ5+xBHr^`Lz~4yToJ6Nxelmx&MCJ$mkn?%t5$7wV`H|2Y;87pyv`cjKj-*MOa=lcmcp4;8Jw(!7ip|j98~; zR%Ay>Yq*ZJBxjVOtD&{d(TpAI_qWrr=o~+&g`QkiNuG$^9(q|1qBfj7sjpka!TwB= z^ovh7s4eMJbqpP_)0jdDWy8Cr4K2 zGW{_H<9H$nUaxu1vn`m~_Ny-7B8ASeDoF*aZwIPXe!d;&^O7L12(ibft@?RpV< zi{q*;e3(0R5scU0G>Rm%=4f6iC{K>l!?3i#X6>!_8(1!Jc1pimiVhIC3es zgAaXz&h1*aRy#@PBot5*U6!KG8G!k-49ux%&Q$dNYpw1muQGN-*W&vxd)i;f$^T_c zEwrges%3M?dCui64B0wapVP&77`m@{Td0f_2@xzh$K*>SM1){K8y7>0fQaT%JOBPb zS4|(gh(BDAmUu>5Fz?`8IaT`b6;3!G zneC7he5-`Gs!$ZOfvqTK1O9Si)v7nm25zrDN9)@oR|k&U_buw^rDIf9kKRdKb};aQ z=|9j!Qv7*p#vn2bJ6GPQ^bS{Vd3Z;w&5C!&Y+6KD*EsKzC6CDFgUxce@i@(rH8}hh zCU7ahhRo5Xb|TN|R5*!|s;YCCR`e?P!`s?W>E3Q^p4dnU5&FfBo4tT_k!~?XBOiH| z>b9_h56K=+9e9wZGNRf}T^~;TR&T|MZT?R1cpIY{B6m3r&p!FkL4Wh58vjeo%>35T zF4j7MJjEqW)2`PuRpUcxifHlp?vZf_p{}!xQzOlN#*pa-hPe1SBtF8CcdsW$P*+0}GN`ryNdYPTK6!jwuln35VJ`WZM(iE)#GwunI`+I14`n33QGp_6kqdccAT7^0!P3RX z#|ceiz_5IHrjpzg(V@#?)l*f`bZW-;CF51ig%|$)){MIb*=GB@CPp^~6v?`-_($1( zuUJ$i!3M7CD<_(9G;5~2lsFq+0AL)ht60}oU9Wh(O9wcn(Y($GZYOz769Z_>Y$-Dv z5HSfMI>W=^3eFC=>lL23fcflGOw%fgJ(_@bOhOR1{Yt`s`YeuYTvbiWs=w^PMs5|~ z=}84W@O*gYi6`}&{^!)a1IIQzRek3)NtaY{#L`}>0m!vlS5A=&(ykL*XLWcfR=KUb z%9rx$CalUzIy<<+tUzranE;f=+6+*I!;edI9!T2ScG9Mp4rg0bYk}2Q*^5;;2)GrqU%YrcjuKs`SuQT|rbhWhd}Trpw}1Gy#wHvTgL}rVf7vOR~mCbF*fH z7d+72a+NhZ&$(I zXCS1VLna7P0xK^}@KJD0Y0yMqzh{KKWICr{Y>*^>S)nRH}2)=X-7j8-a5ai$7VCOb?@t>sq5 zyV}-(Le>;)wWb_^j_MqQ15!Pv(hjMMYR$B;LD)&jXS`_8Ys|SF(m9LB?H(-=nz*rd zHK(5X><4laqZPHC0{ZUJH1jLJ^dfDBKB`@5+z_#`quDUF%7Ov*hNZQy;C1(lS#68p z6Qy*v-b~#_-41$X)I!q5SDp&5xY~BjTO}a~BFX%kzUb|#d)m3E z*6AJ9J(qM{*z{MP_*%8_PPz6#y2`Ca=QOK=U5;Tg0_*h5^|LAK=B!m)w04&AmJeZ_ zZiP)_s)vRIkIR+LjR&r!fu!P-Cn%CPD=ELCLN2x02+O-$J^7>Zm9PA*WN%H-3fX;y zJs!bTRXQ~J#qXRyv1nqM*3u8EqtQW~SzGH}BcS!DPH3k_b5ti`!w^y1uu&_BJj+{| zvg@7`KHZCcdNph~LMqiYw5pem3Ux6!Y6Dd6j5>VU#o0+Ce3W9EZ5>6&TE3J6jFfQr zA_>saR@eyDLh9fUapg_6?==%szuSEI%iDeXv6Zu%3sslhEOzI`&8&RZN;&zhGKRjC zTxS`|w+}5MCYW}r1W)o*t-MB7n;V->2CpJ4)%aV{C4IW2jr2+n8Xi&?Mm@n4os1tj zSH1YA;BVVqccikFUCthM2Um@!&p2g;Ua9yKndo_~@y6EPN~ydX!5EgvwUe?tWH`4Q zOVuHEL=ud_kU!$EfQmONWm9&VT@U9LZ-9xF6E$>>fU(jc>29;mVZ(RspI0^ZWh#&(sw8Y8_|DM^knp z#;uW6ojPmnwOhMRXdPU;D`XdsBC5Ab0TuA1tsEROwDFr3y}q=j`MWZ2-UU2U3CI8d z0Q^ZrK~%FpSs%;~|GD<~;n!q48Vt`|@tFSR>9h1}<)@46blvAZB%Ez8jW}^eIwsa$ zP~9$4p2Y*jm@`!|NtX{frn^nM{fqQ|*F|Noy*|@ia6$WRHbL>oJ8#{KN1l#bX*7J^ zvzHH=-s!{sj2zy3nr?|6t~+JzC0}$m%Bk4gv6HpB2WD;AWS2TS|I-qHFNy`%N(Ncuv_!NH~>*>e9^m|eI;V3!ye(GB9Z`WF?x6(C=6rcG$JeM?S)LX+Nsd{|7Q<4LmGq Rsd4}S002ovPDHLkV1mc2f+hd} literal 0 HcmV?d00001 diff --git a/core/mogo-core-res/src/main/function-hmi-res/drawable-xhdpi/icon_v2x_road_accidents.png b/core/mogo-core-res/src/main/function-hmi-res/drawable-xhdpi/icon_v2x_road_accidents.png new file mode 100644 index 0000000000000000000000000000000000000000..10e3accd568fd82ec2ebbc13216447194a9558d2 GIT binary patch literal 15743 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 literal 0 HcmV?d00001 diff --git a/core/mogo-core-res/src/main/function-hmi-res/drawable-xhdpi/icon_v2x_road_congestion.png b/core/mogo-core-res/src/main/function-hmi-res/drawable-xhdpi/icon_v2x_road_congestion.png new file mode 100644 index 0000000000000000000000000000000000000000..390ed0bdef11c4093bdb1c7f57f83421eb659c9f GIT binary patch literal 16210 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 Date: Wed, 11 Jan 2023 15:44:34 +0800 Subject: [PATCH 14/48] =?UTF-8?q?[2.13.2][fix]=E8=A7=A3=E5=86=B3=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E5=B4=A9=E6=BA=83=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../function/main/MainMoGoApplication.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java index 5468dfa427..421856a714 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java @@ -123,7 +123,25 @@ public abstract class MainMoGoApplication extends AbsMogoApplication { }).start(); } - // TODO 李小鹏 这里需要将逻辑抽离出去,单独使用更新服务控制 + private void checkMonitorDb() { + new Thread(() -> { + long limitId = 50001; + File file = this.getDatabasePath(MonitorDb.INTERNAL_DB_NAME); + try { + if (file != null && file.exists()) { + List cpuList = MonitorDb.getDb(this).monitorDao().getAllCPUById(limitId); + List memList = MonitorDb.getDb(this).monitorDao().getAllMemById(limitId); + // 大于5w条清除 + if (cpuList.size() > 0 || memList.size() > 0) { + this.deleteDatabase(MonitorDb.INTERNAL_DB_NAME); + } + } + } catch (Exception e) { + CallerLogger.INSTANCE.e(TAG, e.getMessage()); + } + }).start(); + } + private void upgradeProgressListener() { final NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setSmallIcon(R.mipmap.icon1001);//todo emArrow 更换图标,去除地图下载图标的依赖关系 From a841735ac44e7905858cd1a273f18d545c049a17 Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Wed, 11 Jan 2023 16:43:04 +0800 Subject: [PATCH 15/48] =?UTF-8?q?[2.13.2][Opt]=E6=9F=A5=E8=AF=A2=E6=80=A7?= =?UTF-8?q?=E8=83=BD=E7=9B=91=E6=8E=A7=E7=9A=84=E6=97=B6=E6=9C=BA=E5=90=8E?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../function/main/MainMoGoApplication.java | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java index 421856a714..9be0248578 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java @@ -70,7 +70,6 @@ public abstract class MainMoGoApplication extends AbsMogoApplication { initKoom(); } clearMessageBoxTable(); - checkMonitorDb(); CallerMsgBoxManager.INSTANCE.queryAllMessages(this); } upgradeProgressListener(); @@ -123,25 +122,6 @@ public abstract class MainMoGoApplication extends AbsMogoApplication { }).start(); } - private void checkMonitorDb() { - new Thread(() -> { - long limitId = 50001; - File file = this.getDatabasePath(MonitorDb.INTERNAL_DB_NAME); - try { - if (file != null && file.exists()) { - List cpuList = MonitorDb.getDb(this).monitorDao().getAllCPUById(limitId); - List memList = MonitorDb.getDb(this).monitorDao().getAllMemById(limitId); - // 大于5w条清除 - if (cpuList.size() > 0 || memList.size() > 0) { - this.deleteDatabase(MonitorDb.INTERNAL_DB_NAME); - } - } - } catch (Exception e) { - CallerLogger.INSTANCE.e(TAG, e.getMessage()); - } - }).start(); - } - private void upgradeProgressListener() { final NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setSmallIcon(R.mipmap.icon1001);//todo emArrow 更换图标,去除地图下载图标的依赖关系 From 5a73a9baf29a0df4fddc46aa022b588136cfb6dd Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Thu, 12 Jan 2023 16:15:49 +0800 Subject: [PATCH 16/48] =?UTF-8?q?[2.13.2][feat]V2X=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E6=B1=87=E6=80=BB=E7=9A=84=E6=B6=88=E6=81=AF=E5=8A=A0=E5=85=A5?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E7=9B=92=E5=AD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eagle/core/function/v2x/V2XProvider.kt | 9 ++- .../function/v2x/events/V2XEventManager.kt | 10 ++- .../core/function/v2x/road/V2XEventResult.kt | 70 +++++++++++++++++++ .../function/v2x/road/V2XEventServiceApi.kt | 11 +++ .../eagle/core/data/msgbox/DataSourceType.kt | 6 +- .../function/api/v2x/IV2XEventProvider.kt | 7 ++ .../function/call/map/CallerSmpManager.kt | 8 +++ 7 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/road/V2XEventResult.kt create mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/road/V2XEventServiceApi.kt create mode 100644 core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/IV2XEventProvider.kt diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/V2XProvider.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/V2XProvider.kt index 7979889dea..0ad6e9caf9 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/V2XProvider.kt +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/V2XProvider.kt @@ -4,12 +4,13 @@ import android.content.Context import com.alibaba.android.arouter.facade.annotation.Route import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.data.constants.MogoServicePaths.PATH_V2X_MODULE -import com.mogo.eagle.core.function.api.base.IMoGoFunctionServerProvider +import com.mogo.eagle.core.function.api.v2x.IV2XEventProvider +import com.mogo.eagle.core.function.call.trafficlight.CallerTrafficLightManager import com.mogo.eagle.core.function.v2x.events.V2XEventManager import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils @Route(path = PATH_V2X_MODULE) -class V2XProvider : IMoGoFunctionServerProvider { +class V2XProvider : IV2XEventProvider { override val functionName: String get() = "V2XProvider" @@ -22,6 +23,10 @@ class V2XProvider : IMoGoFunctionServerProvider { } } + override fun queryWholeRoadEvents() { + V2XEventManager.queryWholeRoadEvents() + } + override fun onDestroy() { if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode) && AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) { //不处理 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 d0945dedbf..d3b91a1902 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,6 +5,7 @@ import android.os.* import android.util.* import androidx.localbroadcastmanager.content.* import com.mogo.cloud.passport.* +import com.mogo.commons.constants.HostConst import com.mogo.commons.module.ServiceConst.CARD_TYPE_ROAD_CONDITION import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.data.enums.EventTypeHelper @@ -18,6 +19,7 @@ import com.mogo.eagle.core.data.map.entity.MarkerExploreWay import com.mogo.eagle.core.data.map.entity.MarkerShowEntity import com.mogo.eagle.core.data.map.entity.V2XMessageEntity import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity +import com.mogo.eagle.core.data.msgbox.DataSourceType import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.V2XMsg @@ -25,6 +27,7 @@ import com.mogo.eagle.core.data.traffic.* 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.CallerAutoPilotStatusListenerManager +import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager 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 @@ -49,6 +52,9 @@ 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.function.v2x.road.V2XEventServiceApi +import com.mogo.eagle.core.network.MoGoRetrofitFactory +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 import com.mogo.eagle.core.utilcode.util.* @@ -505,8 +511,6 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb } private fun realQueryV2xEvents(lineId: String, sn: String) { - /* - TODO fufeng 先注掉,编译通过 v2xEventDisposable = MoGoRetrofitFactory.getInstance(HostConst.getHost()) .create(V2XEventServiceApi::class.java) .queryAllV2XEventsByLineId(lineId, sn) @@ -528,7 +532,7 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb msgBoxBean.sourceType = DataSourceType.SUMMARY CallerMsgBoxManager.saveMsgBox(msgBoxBean) } - }*/ + } } private fun getLineId(): Long { diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/road/V2XEventResult.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/road/V2XEventResult.kt new file mode 100644 index 0000000000..836fcfc2bd --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/road/V2XEventResult.kt @@ -0,0 +1,70 @@ +package com.mogo.eagle.core.function.v2x.road + +import androidx.annotation.Keep + +import com.google.gson.annotations.SerializedName +import com.mogo.eagle.core.data.BaseData + + +@Keep +data class V2XEventResult ( + @SerializedName("result") + var result: Result? +): BaseData() + +@Keep +data class Result( + @SerializedName("eventList") + var v2XEventList: List? +) + +@Keep +data class V2XEvent( + @SerializedName("receiveTime") + var receiveTime: Long, + + @SerializedName("detectTime") + var detectTime: Long, + + @SerializedName("id") + var id: String?, + + @SerializedName("center") + var center: Center?, + + @SerializedName("centerRoad") + var centerRoad: CenterRoad?, + + @SerializedName("radius") + var radius: Double, + + @SerializedName("poiType") + var poiType: String? +) + +@Keep +data class Center( + @SerializedName("lat") + var lat: Double, + + @SerializedName("lon") + var lon: Double +) + +@Keep +data class CenterRoad( + @SerializedName("bearing") + var bearing: Double, + + @SerializedName("laneNo") + var laneNo: Long, + + @SerializedName("roadId") + var roadId: String?, + + @SerializedName("roadName") + var roadName: String?, + + @SerializedName("tileId") + var tileId: Long +) \ 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/road/V2XEventServiceApi.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/road/V2XEventServiceApi.kt new file mode 100644 index 0000000000..5b73866375 --- /dev/null +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/road/V2XEventServiceApi.kt @@ -0,0 +1,11 @@ +package com.mogo.eagle.core.function.v2x.road + +import io.reactivex.Observable +import retrofit2.http.GET +import retrofit2.http.Query + +interface V2XEventServiceApi { + + @GET("/eagleEye-mis/config/queryV2NInformation") + fun queryAllV2XEventsByLineId(@Query("lineId") lineId: String, @Query("sn") sn: String): Observable +} \ No newline at end of file diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/DataSourceType.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/DataSourceType.kt index 60561f77de..af15d0b8a7 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/DataSourceType.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/DataSourceType.kt @@ -1,5 +1,9 @@ package com.mogo.eagle.core.data.msgbox enum class DataSourceType { - DEFAULT, OBU, TELEMATIC, AICLOUD + DEFAULT, + OBU, + TELEMATIC, + AICLOUD, + SUMMARY// V2X事件汇总 } \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/IV2XEventProvider.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/IV2XEventProvider.kt new file mode 100644 index 0000000000..629ed5938d --- /dev/null +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/IV2XEventProvider.kt @@ -0,0 +1,7 @@ +package com.mogo.eagle.core.function.api.v2x + +import com.mogo.eagle.core.function.api.base.IMoGoFunctionServerProvider + +interface IV2XEventProvider: IMoGoFunctionServerProvider { + fun queryWholeRoadEvents() +} \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerSmpManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerSmpManager.kt index e0281c2f76..16fbe0a4e9 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerSmpManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerSmpManager.kt @@ -3,8 +3,10 @@ package com.mogo.eagle.core.function.call.map import android.os.Looper import com.alibaba.android.arouter.launcher.ARouter import com.mogo.eagle.core.data.constants.MoGoFragmentPaths +import com.mogo.eagle.core.data.constants.MogoServicePaths import com.mogo.eagle.core.data.map.MogoLatLng import com.mogo.eagle.core.function.api.map.smp.IMogoSmallMapProvider +import com.mogo.eagle.core.function.api.v2x.IV2XEventProvider import com.mogo.eagle.core.function.call.base.CallerBase import com.mogo.eagle.core.utilcode.util.UiThreadHandler @@ -22,6 +24,10 @@ object CallerSmpManager : CallerBase() { get() = ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW) .navigation() as IMogoSmallMapProvider + private val v2xProvider: IV2XEventProvider + get() = ARouter.getInstance().build(MogoServicePaths.PATH_V2X_MODULE) + .navigation() as IV2XEventProvider + /** * 绘制路径线 */ @@ -58,9 +64,11 @@ object CallerSmpManager : CallerBase() { fun startQueryV2XEvents() { if (Thread.currentThread() !== Looper.getMainLooper().thread) { UiThreadHandler.post { + v2xProvider.queryWholeRoadEvents() mogoOverViewMapProvider.startQueryV2XEvents() } } else { + v2xProvider.queryWholeRoadEvents() mogoOverViewMapProvider.startQueryV2XEvents() } } From bac6a2f8c9ed153592041c16013c057921401835 Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Thu, 12 Jan 2023 17:06:21 +0800 Subject: [PATCH 17/48] =?UTF-8?q?[2.13.2][opt]=E5=85=A8=E8=A7=88=E5=9C=B0?= =?UTF-8?q?=E5=9B=BE=E4=B8=AD=E7=BB=8F=E7=BA=AC=E5=BA=A6=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E5=9D=90=E6=A0=87=E7=B3=BB=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E5=85=BC=E5=AE=B9=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eagle/core/function/overview/remote/V2XEventResult.kt | 5 ++++- .../com/mogo/eagle/core/function/smp/AMapCustomView.java | 8 +++++++- .../function/v2x/internal/data/V2XMarkerCardResult.kt | 4 +++- .../mogo/eagle/core/function/v2x/road/V2XEventResult.kt | 5 ++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/remote/V2XEventResult.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/remote/V2XEventResult.kt index 38dcae72a6..e9138cb04e 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/remote/V2XEventResult.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/remote/V2XEventResult.kt @@ -39,7 +39,10 @@ data class V2XEvent( var radius: Double, @SerializedName("poiType") - var poiType: String? + var poiType: String?, + + @SerializedName("coordinateType") + var coordinateType:Int? = null ) @Keep diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/AMapCustomView.java b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/AMapCustomView.java index 0eceebdb66..c8f97d3f25 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/AMapCustomView.java +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/AMapCustomView.java @@ -260,7 +260,13 @@ public class AMapCustomView if (center != null) { center.getLon(); MarkerOptions markerOption = new MarkerOptions(); - LatLng latLng = MarkerDrawerManager.INSTANCE.coordinateConverterWgsToGcj(mContext, center.getLat(), center.getLon()); + LatLng latLng; + if (event.getCoordinateType() == null || event.getCoordinateType() == 0) { + latLng = new LatLng(center.getLat(), center.getLon()); + } else { + // wgs84坐标系需转成高德坐标系 + latLng = MarkerDrawerManager.INSTANCE.coordinateConverterWgsToGcj(mContext, center.getLat(), center.getLon()); + } markerOption.position(latLng); markerOption.anchor(0.13f, 1f); markerOption.icon(BitmapDescriptorFactory.fromBitmap(getV2XBitmap(event.getPoiType()))); 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 index 61e4928e23..48bd6a55e4 100644 --- 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 @@ -434,8 +434,10 @@ class V2XMarkerExploreWay: Serializable { */ var infoCheckNode = 0 + var coordinateType: Int? = null + 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)" + 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, coordinateType=$coordinateType)" } } diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/road/V2XEventResult.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/road/V2XEventResult.kt index 836fcfc2bd..7a98c26ab4 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/road/V2XEventResult.kt +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/road/V2XEventResult.kt @@ -39,7 +39,10 @@ data class V2XEvent( var radius: Double, @SerializedName("poiType") - var poiType: String? + var poiType: String?, + + @SerializedName("coordinateType") + var coordinateType:Int? = null ) @Keep From 0bcf3a677cb6abe1540fcc976b948a3bd4fdc404 Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Mon, 30 Jan 2023 11:09:43 +0800 Subject: [PATCH 18/48] =?UTF-8?q?[Opt]=E8=A7=A3=E5=86=B3=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E8=BF=87=E7=A8=8B=E4=B8=AD=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/mogo/eagle/core/function/v2x/V2XProvider.kt | 1 - .../com/mogo/eagle/core/function/v2x/events/V2XEventManager.kt | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/V2XProvider.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/V2XProvider.kt index 0ad6e9caf9..214567d3fa 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/V2XProvider.kt +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/V2XProvider.kt @@ -5,7 +5,6 @@ import com.alibaba.android.arouter.facade.annotation.Route import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.data.constants.MogoServicePaths.PATH_V2X_MODULE import com.mogo.eagle.core.function.api.v2x.IV2XEventProvider -import com.mogo.eagle.core.function.call.trafficlight.CallerTrafficLightManager import com.mogo.eagle.core.function.v2x.events.V2XEventManager import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils 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 d3b91a1902..dbb4bdd0a6 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 @@ -67,7 +67,9 @@ import com.shuyu.gsyvideoplayer.model.* import com.shuyu.gsyvideoplayer.player.* import com.shuyu.gsyvideoplayer.utils.* import com.zhjt.service.chain.* +import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable +import io.reactivex.schedulers.Schedulers import kotlinx.coroutines.* import kotlinx.coroutines.android.* import tv.danmaku.ijk.media.player.* From 25585416ad4e77be0f3e7625ac6992f6e342aa98 Mon Sep 17 00:00:00 2001 From: renwj Date: Mon, 30 Jan 2023 11:30:21 +0800 Subject: [PATCH 19/48] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0]=E6=9B=BF?= =?UTF-8?q?=E6=8D=A2=E9=AB=98=E7=B2=BE=E5=9D=90=E6=A0=87=E6=9B=BF=E6=8D=A2?= =?UTF-8?q?=E9=AB=98=E5=BE=B7=E5=9D=90=E6=A0=87=E6=96=B9=E6=B3=95=E8=B0=83?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../function/v2x/events/utils/EntityUtils.kt | 38 +++++++------------ 1 file changed, 13 insertions(+), 25 deletions(-) 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 497a287343..65ebd78c9d 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 @@ -8,6 +8,7 @@ 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.* +import com.mogo.eagle.core.utilcode.util.CoordinateTransform import mogo.telematics.pad.MessagePad import roadwork.Road @@ -85,15 +86,10 @@ fun Road.RW_PB.toRoadMarker(): V2XMarkerCardResult = l3.poiType = this.roadwork?.poiType?.toString() l3.generateTime = this.roadwork?.detectTime ?: 0L l3.location = V2XMarkerLocation().also { l4 -> - /* - TODO zhongchao 先注掉,编译通过 - val p = MogoMap.getInstance().mogoMap.switchLonLat( - this.roadwork?.center?.point?.lon ?: 0.0, - this.roadwork?.center?.point?.lat ?: 0.0 - ) - l4.lon = p.lon - l4.lat = p.lat - l4.angle = this.roadwork?.center?.road?.bearing?.toDouble() ?: 0.0*/ + val p = CoordinateTransform.WGS84ToGCJ02(this.roadwork?.center?.point?.lon ?: 0.0, this.roadwork?.center?.point?.lat ?: 0.0) + l4.lon = p[0] + l4.lat = p[1] + l4.angle = this.roadwork?.center?.road?.bearing?.toDouble() ?: 0.0 } l3.infoId = id }) @@ -117,15 +113,10 @@ fun V2XRoadXData.toRoadMarker(): V2XMarkerCardResult = l3.poiType = this.poiType l3.generateTime = this.detectTime ?: 0L l3.location = V2XMarkerLocation().also { l4 -> - /* - TODO zhongchao 先注掉,编译通过 - val p = MogoMap.getInstance().mogoMap.switchLonLat( - this.center?.lon ?: 0.0, - this.center?.lat ?: 0.0 - ) - l4.lon = p.lon - l4.lat = p.lat - l4.angle = this.centerRoad?.bearing ?: 0.0*/ + val p = CoordinateTransform.WGS84ToGCJ02(this.center?.lon ?: 0.0, this.center?.lat ?: 0.0) + l4.lon = p[0] + l4.lat = p[1] + l4.angle = this.centerRoad?.bearing ?: 0.0 } l3.infoId = this.index }) @@ -148,13 +139,10 @@ fun MessagePad.TrackedObject.toRoadMarker(poiType: String): V2XMarkerCardResult l3.poiType = poiType l3.generateTime = 0L l3.location = V2XMarkerLocation().also { l4 -> - /* - TODO zhongchao 先注掉,编译通过 - val p = - MogoMap.getInstance().mogoMap.switchLonLat(this.longitude, this.latitude) - l4.lon = p.lon - l4.lat = p.lat - l4.angle = this.heading*/ + val p = CoordinateTransform.WGS84ToGCJ02(this.longitude, this.latitude) + l4.lon = p[0] + l4.lat = p[1] + l4.angle = this.heading } l3.infoId = id }) From aa3455a5abdea2557138ffda41a06004801294d2 Mon Sep 17 00:00:00 2001 From: lixiaopeng Date: Mon, 30 Jan 2023 11:31:13 +0800 Subject: [PATCH 20/48] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E9=80=9F=E5=BA=A6=E6=9D=A5=E6=BA=90=E7=9A=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eagle/core/function/api/hmi/view/IViewLimitingVelocity.kt | 1 + .../mogo/eagle/core/function/api/hmi/warning/IMoGoHmiProvider.kt | 1 + 2 files changed, 2 insertions(+) diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewLimitingVelocity.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewLimitingVelocity.kt index 3d566205ef..c1b5499a1d 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewLimitingVelocity.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewLimitingVelocity.kt @@ -13,6 +13,7 @@ abstract class IViewLimitingVelocity(context: Context?, attrs: AttributeSet?, de /** * 更新限速数据 * @param limitingSpeed 限速值,单位:km/h + * @param limitSource 限速来源 1:MAP, 2:RSU */ open fun updateLimitingSpeed(limitingSpeed: Int, limitSource: Int) {} } \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoHmiProvider.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoHmiProvider.kt index 1a37611bb3..266eaa8fa6 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoHmiProvider.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoHmiProvider.kt @@ -139,6 +139,7 @@ interface IMoGoHmiProvider : IMoGoHmiViewProxy { * 展示限速预警 * * @param limitingSpeed 限速速度 + * @param limitSpeedSource 限速来源 1:MAP, 2:RSU */ fun showLimitingVelocity(limitingSpeed: Int, limitSpeedSource: Int) From 339d38b5f16e028489da783d308fcd659a167aed Mon Sep 17 00:00:00 2001 From: lixiaopeng Date: Mon, 30 Jan 2023 12:06:31 +0800 Subject: [PATCH 21/48] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E9=A2=91=E7=B9=81=E7=9A=84=E9=99=90=E5=88=B6=EF=BC=8C=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=AD=98=E5=82=A8=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/function/obu/mogo/MoGoObuProvider.kt | 2 +- .../obu/mogo/MogoObuDcCombineManager.kt | 32 +++---- .../obu/mogo/MogoPrivateObuManager.kt | 19 ++-- .../obu/mogo/MogoPrivateObuNewManager.kt | 90 +++++-------------- 4 files changed, 41 insertions(+), 102 deletions(-) diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MoGoObuProvider.kt b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MoGoObuProvider.kt index a4de8e25d8..f9c946d9f7 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MoGoObuProvider.kt +++ b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MoGoObuProvider.kt @@ -33,7 +33,7 @@ class MoGoObuProvider : IMoGoObuProvider { override fun init(context: Context) { //obu融合数据 -// MogoObuDcCombineManager.INSTANCE.init(context) + MogoObuDcCombineManager.INSTANCE.init(context) CallerLogger.d("$M_OBU$TAG", "初始化蘑菇自研OBU…… localIp = " + CommonUtils.getLocalIPAddress()) //bus乘客版本obu功能去掉 if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode) && AppIdentityModeUtils.isPassenger( diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoObuDcCombineManager.kt b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoObuDcCombineManager.kt index c5fc15016d..f95f73480d 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoObuDcCombineManager.kt +++ b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoObuDcCombineManager.kt @@ -4,6 +4,7 @@ import android.content.Context import com.mogo.eagle.core.data.config.HmiBuildConfig import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.data.enums.WarningDirectionEnum +import com.mogo.eagle.core.data.msgbox.DataSourceType import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.V2XMsg @@ -13,7 +14,6 @@ import com.mogo.eagle.core.function.call.hmi.CallerHmiManager import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager import com.mogo.eagle.core.function.call.obucombine.CallerObuDcCombineListenerManager -import com.mogo.eagle.core.function.obu.mogo.utils.TrafficDataConvertUtils import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU import com.mogo.support.obu.constants.MogoObuConstants @@ -89,7 +89,7 @@ class MogoObuDcCombineManager private constructor() : IMoGoObuDcCombineListener ) if (rsiWarningData != null && rsiWarningData.warningMsgList != null && rsiWarningData.warningMsgList.size > 0) { var alertContent = "" - var ttsContent = "" //TODO 列表还是只有一项吗? + var ttsContent = "" //列表只有一项 var appId = rsiWarningData.warningMsgList[0].sceneType.toString() val status = rsiWarningData.status val level = rsiWarningData.warningMsgList[0].warningLevel @@ -265,10 +265,9 @@ class MogoObuDcCombineManager private constructor() : IMoGoObuDcCombineListener alertContent, ttsContent ) - ) -// .apply { -// sourceType = DataSourceType.TELEMATIC -// } + ).apply { + sourceType = DataSourceType.TELEMATIC + } ) CallerHmiManager.warningV2X( appId, @@ -363,10 +362,9 @@ class MogoObuDcCombineManager private constructor() : IMoGoObuDcCombineListener alertContent, ttsContent ) - ) -// .apply { //TODO -// sourceType = DataSourceType.TELEMATIC -// } + ).apply { + sourceType = DataSourceType.TELEMATIC + } ) CallerHmiManager.warningV2X( v2xType, @@ -560,10 +558,9 @@ class MogoObuDcCombineManager private constructor() : IMoGoObuDcCombineListener alertContent, ttsContent ) - ) -// .apply { -// sourceType = DataSourceType.TELEMATIC -// } + ).apply { + sourceType = DataSourceType.TELEMATIC + } ) CallerHmiManager.warningV2X( @@ -604,10 +601,9 @@ class MogoObuDcCombineManager private constructor() : IMoGoObuDcCombineListener alertContent, ttsContent ) - ) -// .apply { //TODO -// sourceType = DataSourceType.TELEMATIC -// } + ).apply { + sourceType = DataSourceType.TELEMATIC + } ) CallerHmiManager.warningV2X( diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuManager.kt b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuManager.kt index 973c7da6ee..a942a7556e 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuManager.kt +++ b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuManager.kt @@ -2,13 +2,15 @@ package com.mogo.eagle.core.function.obu.mogo import android.content.Context import android.util.Log -import com.alibaba.android.arouter.launcher.ARouter import com.mogo.cloud.passport.MoGoAiCloudClientConfig import com.mogo.eagle.core.data.app.AppConfigInfo import com.mogo.eagle.core.data.config.FunctionBuildConfig -import com.mogo.eagle.core.data.config.HmiBuildConfig -import com.mogo.eagle.core.data.constants.MogoServicePaths +import com.mogo.eagle.core.data.enums.EventTypeEnum +import com.mogo.eagle.core.data.enums.EventTypeHelper import com.mogo.eagle.core.data.enums.WarningDirectionEnum +import com.mogo.eagle.core.data.msgbox.MsgBoxBean +import com.mogo.eagle.core.data.msgbox.MsgBoxType +import com.mogo.eagle.core.data.msgbox.V2XMsg import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager import com.mogo.eagle.core.function.call.hmi.CallerHmiManager @@ -16,18 +18,12 @@ import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.Default import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.TooClose +import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager import com.mogo.eagle.core.function.call.obu.CallerObuListenerManager import com.mogo.eagle.core.function.obu.mogo.utils.TrafficDataConvertUtils import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr -import com.mogo.eagle.core.data.enums.EventTypeEnum -import com.mogo.eagle.core.data.enums.EventTypeHelper -import com.mogo.eagle.core.data.msgbox.MsgBoxBean -import com.mogo.eagle.core.data.msgbox.MsgBoxType -import com.mogo.eagle.core.data.msgbox.V2XMsg -import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager -//import com.mogo.service.IMogoServiceApis import com.zhidao.support.obu.MogoObuManager import com.zhidao.support.obu.OnMogoObuListener import com.zhidao.support.obu.constants.ObuConstants @@ -48,14 +44,11 @@ class MogoPrivateObuManager private constructor() { } } -// private var mMogoServiceApis: IMogoServiceApis? = null private var mContext: Context? = null private var mObuStatusInfo = CallerObuListenerManager.getObuStatusInfo() fun init(context: Context, ipAddress: String) { CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "obuManager初始化--") -// mMogoServiceApis = ARouter.getInstance().build(MogoServicePaths.PATH_SERVICE_APIS) -// .navigation(context) as IMogoServiceApis mContext = context //连接obu设备 connectObu(context, ipAddress) diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt index 961844e834..93706d2adc 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt +++ b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt @@ -4,7 +4,7 @@ import android.content.Context import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.data.config.HmiBuildConfig import com.mogo.eagle.core.data.enums.* -//import com.mogo.eagle.core.data.msgbox.DataSourceType +import com.mogo.eagle.core.data.msgbox.DataSourceType import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.V2XMsg @@ -193,20 +193,6 @@ class MogoPrivateObuNewManager private constructor() { level = data.warningMsg.warningData[0].warningLevel appId = data.warningMsg.warningData[0].warningType.toString() status = data.warningMsg.warningData[0].status - - //30秒内同一个事件只出现一次 - if (rvMap.containsKey(appId)) { - var oldTime = rvMap[appId] - var timeDiff = (System.currentTimeMillis() - oldTime!!) / 1000 - if (timeDiff < 30) { - return - } - rvMap.remove(appId) - rvMap[appId] = System.currentTimeMillis() - } else { - rvMap[appId] = System.currentTimeMillis() - } - //拼凑数据 if (appId != null) { handleSdkObu(appId, direction, status, level, data) @@ -242,11 +228,6 @@ class MogoPrivateObuNewManager private constructor() { } } - val rvMap = mutableMapOf() - val rsiMap = mutableMapOf() - val rsmMap = mutableMapOf() - val rsmPtcIdMap = mutableMapOf() - /** * RSI预警信息 onMogoObuRsiWarning(交通标志预警(前方限速、前方学校等等),交通事件预警(前方拥堵、前方积水等等)) */ @@ -317,9 +298,9 @@ class MogoPrivateObuNewManager private constructor() { MogoObuConstants.RTS.RTI_TYPE_BRIDGE -> { //桥梁 appId = EventTypeEnumNew.TYPE_ID_BRIDGE.poiType } -// MogoObuConstants.RTS.RTI_TYPE_PEDESTRIAN -> { //行人 TODO 暂时去掉 -// appId = EventTypeEnumNew.TYPE_ID_PEDESTRIAN.poiType -// } + MogoObuConstants.RTS.RTI_TYPE_PEDESTRIAN -> { //行人 + appId = EventTypeEnumNew.TYPE_ID_PEDESTRIAN.poiType + } MogoObuConstants.RTS.RTI_TYPE_SLIPPERY_ROAD -> { //路滑 appId = EventTypeEnumNew.TYPE_ID_SLIPPERY_ROAD.poiType } @@ -420,19 +401,6 @@ class MogoPrivateObuNewManager private constructor() { } } - //30秒内同一个事件只出现一次 - if (rsiMap.containsKey(appId)) { - var oldTime = rsiMap[appId] - var timeDiff = (System.currentTimeMillis() - oldTime!!) / 1000 - if (timeDiff < 30) { - return - } - rsiMap.remove(appId) - rsiMap[appId] = System.currentTimeMillis() - } else { - rsiMap[appId] = System.currentTimeMillis() - } - CallerLogger.d( "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", "new onMogoObuRsiWarning appId = $appId ---status = $status --- ttsContent = $ttsContent --alertContent = $alertContent -- eventSerialNum = ${data.warningMsg[0].eventSerialNum} ---signSerialNum = ${data.warningMsg[0].signSerialNum} ---direction = ${direction.direction} --distance = ${ @@ -456,10 +424,9 @@ class MogoPrivateObuNewManager private constructor() { alertContent, ttsContent ) - ) -// .apply { -// sourceType = DataSourceType.OBU -// } + ).apply { + sourceType = DataSourceType.OBU + } ) CallerHmiManager.warningV2X( appId, @@ -543,7 +510,7 @@ class MogoPrivateObuNewManager private constructor() { var level = -1 val direction = getMessageDirection(data.participant.targetPosition) - //物体数据绘制 TODO 这里与dc通过工控机有区别 + //物体数据绘制 CallerLogger.d( "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", "onMogoObuRsmWarning ---- data.status = ${data.status} ---data.participant.ptcId = ${data.participant.ptcId} ---data.participant.ptcType = ${data.participant.ptcType} ---data.warningMsg = ${data.warningMsg} -----data = ${data.toString()}") when (data.status) { @@ -598,19 +565,6 @@ class MogoPrivateObuNewManager private constructor() { when (data.warningMsg.warningData[0].status) { MogoObuConstants.STATUS.ADD -> { // 添加 //更新模型的颜色 - //30秒内同一个事件只出现一次 - if (rsmMap.containsKey(v2xType)) { - var oldTime = rsmMap[v2xType] - var timeDiff = (System.currentTimeMillis() - oldTime!!) / 1000 - if (timeDiff < 30) { - return - } - rsmMap.remove(v2xType) - rsmMap[v2xType] = System.currentTimeMillis() - } else { - rsmMap[v2xType] = System.currentTimeMillis() - } - TrafficDataConvertUtilsNew.cvxPtcThreatIndInfo2TrafficData(data) ?.let { CallerMapUIServiceManager.getMarkerService() @@ -630,10 +584,9 @@ class MogoPrivateObuNewManager private constructor() { alertContent, ttsContent ) - ) -// .apply { //TODO -// sourceType = DataSourceType.OBU -// } + ).apply { + sourceType = DataSourceType.OBU + } ) CallerHmiManager.warningV2X( @@ -883,10 +836,9 @@ class MogoPrivateObuNewManager private constructor() { alertContent, ttsContent ) - ) -// .apply { -// sourceType = DataSourceType.OBU -// } + ).apply { + sourceType = DataSourceType.OBU + } ) CallerHmiManager.warningV2X( appId, @@ -1021,10 +973,9 @@ class MogoPrivateObuNewManager private constructor() { alertContent, ttsContent ) - ) -// .apply { -// sourceType = DataSourceType.OBU -// } + ).apply { + sourceType = DataSourceType.OBU + } ) CallerHmiManager.warningV2X( @@ -1079,10 +1030,9 @@ class MogoPrivateObuNewManager private constructor() { alertContent, ttsContent ) - ) -// .apply { //TODO -// sourceType = DataSourceType.OBU -// } + ).apply { + sourceType = DataSourceType.OBU + } ) CallerHmiManager.warningV2X( From 73ce6b667c79721f04aed3e0c275bf913b3e6f44 Mon Sep 17 00:00:00 2001 From: lixiaopeng Date: Mon, 30 Jan 2023 14:20:28 +0800 Subject: [PATCH 22/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eagle/core/data/enums/EventTypeEnumNew.kt | 97 ++++++++++++++----- 1 file changed, 74 insertions(+), 23 deletions(-) diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt index 6de86e6a02..977ff69174 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt @@ -106,6 +106,12 @@ enum class EventTypeEnumNew( GHOST_PROBE("10024", "前方盲区行人预警", "前方盲区行人预警", R.drawable.icon_warning_v2x_pedestrian_crossing, "前方盲区行人通行,请注意", "前方盲区即将有行人通过,请减速慢行"), + //接管 + TAKE_OVER_EVENT( + "20000", "注意周围、立即接管", "注意周围、立即接管", R.drawable.icon_warning_take_over, + "注意周围、立即接管", "自动驾驶退出请立即接管" + ), + // 前方静止or慢速车辆报警 ALERT_FRONT_CAR("99999"), @@ -494,8 +500,9 @@ enum class EventTypeEnumNew( tts = "" ), - TYPE_VIP_IDENTIFICATION("10022", "", "", R.drawable.icon_warning_v2x_vip_turn_light, "VIP车辆优先通行", "已为您变灯,请优先通行"), - + TYPE_VIP_IDENTIFICATION_PASS("20022", "", "", R.drawable.icon_warning_v2x_vip_turn_light, "VIP车辆优先通行,已为您变为绿灯", "VIP车辆优先通行,已为您变为绿灯"), + TYPE_VIP_IDENTIFICATION_EXTEND("20023", "", "", R.drawable.icon_warning_v2x_vip_turn_light, "VIP车辆优先通行,已为您延长绿灯", "VIP车辆优先通行,已为您延长绿灯"), + TYPE_VIP_ERROR_IDENTIFICATION("20024", "", "", R.drawable.icon_warning_v2x_vip_turn_light, "请求失败,", "请求失败,稍后重试"), TYPE_OPTIMAL_ROUTE_RECOMMEND("2000", "", "", R.drawable.icon_warning_v2x_optimal_route, "为您推荐最优路线", "已为您选择最优路线"); @@ -669,7 +676,7 @@ enum class EventTypeEnumNew( fun getMarker3DRes(poiType: String?): Int { return when (poiType) { FOURS_BLOCK_UP.poiType -> R.raw.v2x_yongdu - FOURS_ACCIDENT.poiType -> R.raw.v2x_shigu + FOURS_ACCIDENT.poiType,FOURS_ACCIDENT_04.poiType -> R.raw.v2x_shigu FOURS_LIVING.poiType -> R.raw.v2x_shishilukuang FOURS_FOG.poiType -> R.raw.v2x_nongwu TRAFFIC_CHECK.poiType -> R.raw.v2x_jiaotongjiancha @@ -690,15 +697,15 @@ enum class EventTypeEnumNew( return when (poiType) { //交通检查 TRAFFIC_CHECK.poiType -> { - R.drawable.v_to_x_marker_2 + R.drawable.v2x_icon_jiaotongjiancha_vr } //封路 ROAD_CLOSED.poiType -> { - R.drawable.v_to_x_marker_16 + R.drawable.v2x_icon_fenglu_vr } //施工 FOURS_ROAD_WORK.poiType -> { - R.drawable.v_to_x_marker_11 + R.drawable.icon_warning_v2x_road_construction } //AI施工 TYPE_SOCKET_ROAD_SHIGONG.poiType -> R.drawable.icon_warning_v2x_road_construction @@ -707,23 +714,43 @@ enum class EventTypeEnumNew( TYPE_SOCKET_ROAD_CONGESTION.poiType -> R.drawable.v2x_icon_yongdu_vr //拥堵 FOURS_BLOCK_UP.poiType -> { - R.drawable.v_to_x_marker_5 + R.drawable.icon_warning_v2x_congestion } //积水 FOURS_PONDING.poiType -> { - R.drawable.v_to_x_marker_6 + R.drawable.v2x_icon_jishui_vr } //浓雾 FOURS_FOG.poiType -> { - R.drawable.v_to_x_marker_9 + R.drawable.v2x_icon_nongwu_vr } //结冰 FOURS_ICE.poiType -> { - R.drawable.v_to_x_marker_8 + R.drawable.v2x_icon_jiebing_vr } //事故 FOURS_ACCIDENT.poiType -> { - R.drawable.v_to_x_marker_7 + R.drawable.v2x_icon_jiaotongshigu_vr + } + //重大事故 + FOURS_ACCIDENT_01.poiType -> { + R.drawable.v2x_icon_jiaotongshigu_vr + } + //特大事故 + FOURS_ACCIDENT_02.poiType -> { + R.drawable.v2x_icon_jiaotongshigu_vr + } + //较大事故 + FOURS_ACCIDENT_03.poiType -> { + R.drawable.v2x_icon_jiaotongshigu_vr + } + //一般事故 + FOURS_ACCIDENT_04.poiType -> { + R.drawable.v2x_icon_jiaotongshigu_vr + } + //轻微事故 + FOURS_ACCIDENT_05.poiType -> { + R.drawable.v2x_icon_jiaotongshigu_vr } //事故 FOURS_LIVING.poiType -> { @@ -745,16 +772,38 @@ enum class EventTypeEnumNew( ALERT_CAR_TROUBLE_WARNING.poiType -> { R.drawable.icon_car_red } - - //闯红灯预警 - TYPE_USECASE_ID_IVP_RED.poiType -> { - R.drawable.icon_warning_v2x_traffic_lights_red + //VIP车辆优先通行,已为您变为绿灯 + TYPE_VIP_IDENTIFICATION_PASS.poiType -> { + R.drawable.icon_warning_v2x_vip_turn_light + } + //VIP车辆优先通行,已为您延长绿灯 + TYPE_VIP_IDENTIFICATION_EXTEND.poiType -> { + R.drawable.icon_warning_v2x_vip_turn_light + } + //VIP变灯请求失败 + TYPE_VIP_ERROR_IDENTIFICATION.poiType -> { + R.drawable.icon_warning_v2x_vip_turn_light + } + //最优路线 + TYPE_OPTIMAL_ROUTE_RECOMMEND.poiType -> { + R.drawable.icon_warning_v2x_optimal_route } //绿波通行 TYPE_USECASE_ID_IVP_GREEN.poiType -> { R.drawable.icon_warning_v2x_traffic_lights_green } - + //闯红灯预警 + TYPE_USECASE_ID_IVP_RED.poiType -> { + R.drawable.icon_warning_v2x_traffic_lights_red + } + //鬼探头类型 + GHOST_PROBE.poiType -> { + R.drawable.icon_warning_v2x_pedestrian_crossing + } + //接管 + TAKE_OVER_EVENT.poiType -> { + R.drawable.icon_warning_take_over + } //机动车 TYPE_USECASE_ID_VRUCW_MOTOR_VEHICLES.poiType -> { R.drawable.icon_warning_v2x_motorcycle_collision @@ -812,7 +861,7 @@ enum class EventTypeEnumNew( return when (poiType) { TYPE_USECASE_ID_EBW.poiType -> TYPE_USECASE_ID_EBW.poiTypeSrcVr TYPE_USECASE_ID_FCW.poiType -> TYPE_USECASE_ID_FCW.poiTypeSrcVr -// TYPE_USECASE_ID_ICW.poiType -> TYPE_USECASE_ID_ICW.poiTypeSrcVr + TYPE_USECASE_ID_ICW.poiType -> TYPE_USECASE_ID_ICW.poiTypeSrcVr TYPE_USECASE_ID_CLW.poiType -> TYPE_USECASE_ID_CLW.poiTypeSrcVr TYPE_USECASE_ID_DNPW.poiType -> TYPE_USECASE_ID_DNPW.poiTypeSrcVr TYPE_USECASE_ID_AVW.poiType -> TYPE_USECASE_ID_AVW.poiTypeSrcVr @@ -820,7 +869,8 @@ enum class EventTypeEnumNew( TYPE_USECASE_ID_LCW.poiType -> TYPE_USECASE_ID_LCW.poiTypeSrcVr TYPE_USECASE_ID_EVW.poiType -> TYPE_USECASE_ID_EVW.poiTypeSrcVr TYPE_USECASE_ID_LTA.poiType -> TYPE_USECASE_ID_LTA.poiTypeSrcVr - TYPE_VIP_IDENTIFICATION.poiType -> TYPE_VIP_IDENTIFICATION.poiTypeSrcVr + TYPE_VIP_IDENTIFICATION_PASS.poiType -> TYPE_VIP_IDENTIFICATION_PASS.poiTypeSrcVr + TYPE_VIP_IDENTIFICATION_EXTEND.poiType -> TYPE_VIP_IDENTIFICATION_EXTEND.poiTypeSrcVr TYPE_ERROR.poiType -> TYPE_ERROR.poiTypeSrcVr TYPE_OPTIMAL_ROUTE_RECOMMEND.poiType -> TYPE_OPTIMAL_ROUTE_RECOMMEND.poiTypeSrcVr GHOST_PROBE.poiType -> GHOST_PROBE.poiTypeSrcVr @@ -876,7 +926,7 @@ enum class EventTypeEnumNew( return when (poiType) { TYPE_USECASE_ID_EBW.poiType -> TYPE_USECASE_ID_EBW.content TYPE_USECASE_ID_FCW.poiType -> TYPE_USECASE_ID_FCW.content -// TYPE_USECASE_ID_ICW.poiType -> TYPE_USECASE_ID_ICW.content + TYPE_USECASE_ID_ICW.poiType -> TYPE_USECASE_ID_ICW.content TYPE_USECASE_ID_CLW.poiType -> TYPE_USECASE_ID_CLW.content TYPE_USECASE_ID_DNPW.poiType -> TYPE_USECASE_ID_DNPW.content TYPE_USECASE_ID_AVW.poiType -> TYPE_USECASE_ID_AVW.content @@ -884,7 +934,8 @@ enum class EventTypeEnumNew( TYPE_USECASE_ID_LCW.poiType -> TYPE_USECASE_ID_LCW.content TYPE_USECASE_ID_EVW.poiType -> TYPE_USECASE_ID_EVW.content TYPE_USECASE_ID_LTA.poiType -> TYPE_USECASE_ID_LTA.content - TYPE_VIP_IDENTIFICATION.poiType -> TYPE_VIP_IDENTIFICATION.content + TYPE_VIP_IDENTIFICATION_PASS.poiType -> TYPE_VIP_IDENTIFICATION_PASS.content + TYPE_VIP_IDENTIFICATION_EXTEND.poiType -> TYPE_VIP_IDENTIFICATION_EXTEND.content FOURS_ROAD_WORK.poiType -> FOURS_ROAD_WORK.content TYPE_SOCKET_ROAD_SHIGONG.poiType -> TYPE_SOCKET_ROAD_SHIGONG.content TYPE_SOCKET_ROAD_JINGZHI.poiType -> TYPE_SOCKET_ROAD_JINGZHI.content @@ -942,7 +993,7 @@ enum class EventTypeEnumNew( return when (poiType) { TYPE_USECASE_ID_EBW.poiType -> TYPE_USECASE_ID_EBW.tts TYPE_USECASE_ID_FCW.poiType -> TYPE_USECASE_ID_FCW.tts -// TYPE_USECASE_ID_ICW.poiType -> TYPE_USECASE_ID_ICW.tts + TYPE_USECASE_ID_ICW.poiType -> TYPE_USECASE_ID_ICW.tts TYPE_USECASE_ID_CLW.poiType -> TYPE_USECASE_ID_CLW.tts TYPE_USECASE_ID_DNPW.poiType -> TYPE_USECASE_ID_DNPW.tts TYPE_USECASE_ID_AVW.poiType -> TYPE_USECASE_ID_AVW.tts @@ -950,7 +1001,8 @@ enum class EventTypeEnumNew( TYPE_USECASE_ID_LCW.poiType -> TYPE_USECASE_ID_LCW.tts TYPE_USECASE_ID_EVW.poiType -> TYPE_USECASE_ID_EVW.tts TYPE_USECASE_ID_LTA.poiType -> TYPE_USECASE_ID_LTA.tts - TYPE_VIP_IDENTIFICATION.poiType -> TYPE_VIP_IDENTIFICATION.tts + TYPE_VIP_IDENTIFICATION_PASS.poiType -> TYPE_VIP_IDENTIFICATION_PASS.tts + TYPE_VIP_IDENTIFICATION_EXTEND.poiType -> TYPE_VIP_IDENTIFICATION_EXTEND.tts FOURS_ROAD_WORK.poiType -> FOURS_ROAD_WORK.tts TYPE_SOCKET_ROAD_SHIGONG.poiType -> TYPE_SOCKET_ROAD_SHIGONG.tts TYPE_SOCKET_ROAD_JINGZHI.poiType -> TYPE_SOCKET_ROAD_JINGZHI.tts @@ -1014,5 +1066,4 @@ enum class EventTypeEnumNew( } } } - } \ No newline at end of file From 995189fcecab006da1570b1930c6accebb21963f Mon Sep 17 00:00:00 2001 From: yangyakun Date: Mon, 30 Jan 2023 15:10:53 +0800 Subject: [PATCH 23/48] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0]=20[=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0noop=E7=BB=B4=E5=BA=A6=E5=8F=8A=E8=BF=87=E6=BB=A4]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/build.gradle b/app/build.gradle index 734265a7d3..b1a2ae93b4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -210,6 +210,9 @@ android { buildConfigField 'String', 'MAP_SDK_VERSION', "\"${MAP_SDK_VERSION}\"" buildConfigField 'String', 'MAP_SDK_OPT_VERSION', "\"${MAP_SDK_OPERATION_VERSION}\"" } + noop { + dimension "business" + } busbase { dimension "business" } @@ -253,6 +256,12 @@ android { variantFilter { variant -> def names = variant.flavors*.name //要检查特定的构建类型,请使用variant.buildType.name ==“ ” + // region 过滤noop 的flavors 不带och业务的 + if (names.contains("noop")&&!names.contains("fPadLenovo")) { + //Gradle会忽略满足上述条件的所有变体 + setIgnore(true) + } + // endregion // region 过滤sweper 的flavors if (names.contains("sweeper")&&!names.contains("fPadLenovoOchSweeper")) { //Gradle会忽略满足上述条件的所有变体 From f0a02e4d01252143e9be042586b6dc1fa5881cbf Mon Sep 17 00:00:00 2001 From: wangmingjun Date: Mon, 30 Jan 2023 15:40:23 +0800 Subject: [PATCH 24/48] =?UTF-8?q?[opt]=20OCH=E6=A8=A1=E5=9D=97=E5=8E=BB?= =?UTF-8?q?=E9=99=A4=E5=BC=95=E7=94=A8v2x?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OCH/mogo-och-bus-passenger/build.gradle | 2 - OCH/mogo-och-common-module/build.gradle | 2 - OCH/mogo-och-taxi-passenger/build.gradle | 2 - OCH/mogo-och-taxi/build.gradle | 2 - .../com/mogo/och/taxi/TaxiOverlayManager.java | 71 ------------------- 5 files changed, 79 deletions(-) delete mode 100644 OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/TaxiOverlayManager.java diff --git a/OCH/mogo-och-bus-passenger/build.gradle b/OCH/mogo-och-bus-passenger/build.gradle index af805de9a1..0677d0aacd 100644 --- a/OCH/mogo-och-bus-passenger/build.gradle +++ b/OCH/mogo-och-bus-passenger/build.gradle @@ -57,7 +57,6 @@ dependencies { implementation rootProject.ext.dependencies.mogocommons implementation rootProject.ext.dependencies.mogo_core_data implementation rootProject.ext.dependencies.mogo_core_function_call - implementation rootProject.ext.dependencies.mogo_core_function_v2x implementation rootProject.ext.dependencies.mogo_core_function_hmi }else { implementation project(':foudations:mogo-aicloud-services-sdk') @@ -65,7 +64,6 @@ dependencies { implementation project(':core:mogo-core-data') implementation project(":core:mogo-core-utils") implementation project(':core:mogo-core-function-call') - implementation project(':core:function-impl:mogo-core-function-v2x') implementation project(':core:function-impl:mogo-core-function-hmi') } } diff --git a/OCH/mogo-och-common-module/build.gradle b/OCH/mogo-och-common-module/build.gradle index 6bcce00b7e..4045e3d793 100644 --- a/OCH/mogo-och-common-module/build.gradle +++ b/OCH/mogo-och-common-module/build.gradle @@ -62,14 +62,12 @@ dependencies { implementation rootProject.ext.dependencies.mogocommons implementation rootProject.ext.dependencies.mogo_core_data implementation rootProject.ext.dependencies.mogo_core_function_call - implementation rootProject.ext.dependencies.mogo_core_function_v2x implementation rootProject.ext.dependencies.mogo_core_function_hmi }else { implementation project(":core:mogo-core-utils") implementation project(":foudations:mogo-commons") implementation project(':core:mogo-core-data') implementation project(':core:mogo-core-function-call') - implementation project(':core:function-impl:mogo-core-function-v2x') implementation project(':core:function-impl:mogo-core-function-hmi') } diff --git a/OCH/mogo-och-taxi-passenger/build.gradle b/OCH/mogo-och-taxi-passenger/build.gradle index a682c2e839..03c8289c7f 100644 --- a/OCH/mogo-och-taxi-passenger/build.gradle +++ b/OCH/mogo-och-taxi-passenger/build.gradle @@ -60,14 +60,12 @@ dependencies { implementation rootProject.ext.dependencies.mogocommons implementation rootProject.ext.dependencies.mogo_core_data implementation rootProject.ext.dependencies.mogo_core_function_call - implementation rootProject.ext.dependencies.mogo_core_function_v2x implementation rootProject.ext.dependencies.mogo_core_res }else { implementation project(":core:mogo-core-utils") implementation project(":foudations:mogo-commons") implementation project(':core:mogo-core-data') implementation project(':core:mogo-core-function-call') - implementation project(':core:function-impl:mogo-core-function-v2x') implementation project(':core:mogo-core-res') } } diff --git a/OCH/mogo-och-taxi/build.gradle b/OCH/mogo-och-taxi/build.gradle index f802637796..8ca98d2c2c 100644 --- a/OCH/mogo-och-taxi/build.gradle +++ b/OCH/mogo-och-taxi/build.gradle @@ -59,14 +59,12 @@ dependencies { implementation rootProject.ext.dependencies.mogocommons implementation rootProject.ext.dependencies.mogo_core_data implementation rootProject.ext.dependencies.mogo_core_function_call - implementation rootProject.ext.dependencies.mogo_core_function_v2x implementation rootProject.ext.dependencies.mogo_core_function_hmi }else { implementation project(":core:mogo-core-utils") implementation project(":foudations:mogo-commons") implementation project(':core:mogo-core-data') implementation project(':core:mogo-core-function-call') - implementation project(':core:function-impl:mogo-core-function-v2x') implementation project(':core:function-impl:mogo-core-function-hmi') } } diff --git a/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/TaxiOverlayManager.java b/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/TaxiOverlayManager.java deleted file mode 100644 index d525f97b1b..0000000000 --- a/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/TaxiOverlayManager.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.mogo.och.taxi; - -import android.content.Context; - -import com.mogo.eagle.core.data.map.MogoLatLng; -import com.mogo.eagle.core.data.map.MogoLocation; -import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager; -import com.mogo.commons.utils.LocationUtils; -import com.mogo.eagle.core.utilcode.util.ColorUtils; -import com.mogo.map.overlay.IMogoOverlayManager; -import com.mogo.map.overlay.IMogoPolyline; -import com.mogo.map.overlay.MogoPolylineOptions; -import java.util.ArrayList; -import java.util.List; - -public class TaxiOverlayManager { - - - private IMogoPolyline mMoGoPolyline; - // 连接线参数 - private MogoPolylineOptions mPolylineOptions; - // 线路径集合 - private List mPolylinePointList; - // 渐变色 - private List mPolylineColors; - private Context mContext; - IMogoOverlayManager mogoOverlayManager; - public TaxiOverlayManager(Context context) { - mPolylineOptions = new MogoPolylineOptions(); - // 绘制路径集合 - mPolylinePointList = new ArrayList<>(); - // 引导线颜色 - mPolylineColors = new ArrayList<>(); - mContext = context; - mogoOverlayManager = CallerMapUIServiceManager.INSTANCE.getOverlayManager(context); - } - - /** - * 绘制最优路线 - * - * @param polylinePoint 要绘制的经纬度度集合 - */ - public IMogoPolyline draw(MogoLocation carLocal, List polylinePoint) { - if (mMoGoPolyline != null) { - mMoGoPolyline.remove(); - mPolylinePointList.clear(); - mPolylineColors.clear(); - } - if (polylinePoint != null) { - - // 将当前车辆位置放进去 - mPolylinePointList.add(new MogoLatLng(carLocal.getLatitude(), carLocal.getLongitude())); - // 过滤后台推送的推荐路线集合 - for (MogoLatLng polyline : polylinePoint) { - //需要剔除已经行驶过的经纬度,这里需要比对推荐路线集合中的点是否在当前车辆行驶方向前面如果不在则抛弃 - if (LocationUtils.isPointOnCarFront(carLocal, polyline)) { - mPolylinePointList.add(polyline); - } - } - mPolylineColors.addAll(ColorUtils.getGradientAlpha("#002965ED", "#FF2965ED", "#002965ED", mPolylinePointList.size())); - // 替换路径集合 - mPolylineOptions.points(mPolylinePointList); - // 线条粗细,渐变,渐变色值 - mPolylineOptions.width(25).useGradient(true).colorValues(mPolylineColors); - // 绘制线 - mMoGoPolyline = mogoOverlayManager.addPolyline(mPolylineOptions); - } - return mMoGoPolyline; - } - -} From dac67410552e2cef52e0817f1c344dc512ae0faa Mon Sep 17 00:00:00 2001 From: donghongyu Date: Mon, 30 Jan 2023 16:52:39 +0800 Subject: [PATCH 25/48] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0]=20[Change]=20[?= =?UTF-8?q?=201=E3=80=81=E8=BF=81=E7=A7=BBmogo-core-function-obu-mogo?= =?UTF-8?q?=E5=B7=A5=E7=A8=8B=E5=88=B0MoGoEagleEye.core.function-impl.mogo?= =?UTF-8?q?-core-function-datacenter=EF=BC=8C=E5=90=8E=E7=BB=AD=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E6=95=B0=E6=8D=AE=E5=8F=8A=E8=A7=86=E5=9B=BE=E6=8B=86?= =?UTF-8?q?=E7=A6=BB=20]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: donghongyu --- .../README.md | 0 .../build.gradle | 7 +- ...PSALPINE CV2X AMI Specification v1.0.7.pdf | Bin .../doc/AMI通讯协议.docx | Bin .../doc/CV2X_HLI_v1.0.1.pdf | Bin .../doc/HLI通讯协议.docx | Bin .../src/main/AndroidManifest.xml | 37 ++++++++++ .../autopilot/MoGoAutopilotProvider.kt | 2 +- .../datacenter/obu}/MoGoObuProvider.kt | 2 +- .../datacenter/obu}/MogoObuConst.java | 2 +- .../obu}/MogoObuDcCombineManager.kt | 2 +- .../datacenter/obu}/MogoPrivateObuManager.kt | 4 +- .../obu}/MogoPrivateObuNewManager.kt | 4 +- .../receiver/ObuRsuTestTriggerReceiver.kt | 4 +- .../obu}/receiver/ObuTestNewObuReceiver.kt | 5 +- .../obu}/receiver/ObuTestNewObuRsiReceiver.kt | 9 +-- .../obu}/receiver/ObuTestTriggerReceiver.kt | 4 +- .../ObuTestTriggerRecognizedReceiver.kt | 4 +- .../obu}/utils/TrafficDataConvertUtils.kt | 2 +- .../obu}/utils/TrafficDataConvertUtilsNew.kt | 3 +- .../mogo-core-function-hmi/build.gradle | 2 - .../mogo-core-function-obu-mogo/.gitignore | 1 - .../mogo-core-function-obu-mogo/build.gradle | 67 ------------------ .../consumer-rules.pro | 0 .../gradle.properties | 3 - .../proguard-rules.pro | 21 ------ .../src/main/AndroidManifest.xml | 45 ------------ .../IMoGoRoboBusJinlvM1StatesListener.kt | 1 - .../CallerAutoPilotStatusListenerManager.kt | 4 +- .../core/function/call/autopilot/REEADME.md | 62 ++++++++++++++-- modules.txt | 2 +- settings.gradle | 4 +- 32 files changed, 122 insertions(+), 181 deletions(-) rename core/function-impl/{mogo-core-function-obu-mogo => mogo-core-function-datacenter}/README.md (100%) rename core/function-impl/{mogo-core-function-obu-mogo => mogo-core-function-datacenter}/doc/ALPSALPINE CV2X AMI Specification v1.0.7.pdf (100%) rename core/function-impl/{mogo-core-function-obu-mogo => mogo-core-function-datacenter}/doc/AMI通讯协议.docx (100%) rename core/function-impl/{mogo-core-function-obu-mogo => mogo-core-function-datacenter}/doc/CV2X_HLI_v1.0.1.pdf (100%) rename core/function-impl/{mogo-core-function-obu-mogo => mogo-core-function-datacenter}/doc/HLI通讯协议.docx (100%) rename core/function-impl/{mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo => mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu}/MoGoObuProvider.kt (98%) rename core/function-impl/{mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo => mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu}/MogoObuConst.java (95%) rename core/function-impl/{mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo => mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu}/MogoObuDcCombineManager.kt (99%) rename core/function-impl/{mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo => mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu}/MogoPrivateObuManager.kt (99%) rename core/function-impl/{mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo => mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu}/MogoPrivateObuNewManager.kt (99%) rename core/function-impl/{mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo => mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu}/receiver/ObuRsuTestTriggerReceiver.kt (97%) rename core/function-impl/{mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo => mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu}/receiver/ObuTestNewObuReceiver.kt (91%) rename core/function-impl/{mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo => mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu}/receiver/ObuTestNewObuRsiReceiver.kt (82%) rename core/function-impl/{mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo => mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu}/receiver/ObuTestTriggerReceiver.kt (96%) rename core/function-impl/{mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo => mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu}/receiver/ObuTestTriggerRecognizedReceiver.kt (93%) rename core/function-impl/{mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo => mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu}/utils/TrafficDataConvertUtils.kt (98%) rename core/function-impl/{mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo => mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu}/utils/TrafficDataConvertUtilsNew.kt (98%) delete mode 100644 core/function-impl/mogo-core-function-obu-mogo/.gitignore delete mode 100644 core/function-impl/mogo-core-function-obu-mogo/build.gradle delete mode 100644 core/function-impl/mogo-core-function-obu-mogo/consumer-rules.pro delete mode 100644 core/function-impl/mogo-core-function-obu-mogo/gradle.properties delete mode 100644 core/function-impl/mogo-core-function-obu-mogo/proguard-rules.pro delete mode 100644 core/function-impl/mogo-core-function-obu-mogo/src/main/AndroidManifest.xml diff --git a/core/function-impl/mogo-core-function-obu-mogo/README.md b/core/function-impl/mogo-core-function-datacenter/README.md similarity index 100% rename from core/function-impl/mogo-core-function-obu-mogo/README.md rename to core/function-impl/mogo-core-function-datacenter/README.md diff --git a/core/function-impl/mogo-core-function-datacenter/build.gradle b/core/function-impl/mogo-core-function-datacenter/build.gradle index b6e5f51262..5b637a7ae6 100644 --- a/core/function-impl/mogo-core-function-datacenter/build.gradle +++ b/core/function-impl/mogo-core-function-datacenter/build.gradle @@ -57,13 +57,16 @@ dependencies { implementation rootProject.ext.dependencies.mogoami implementation rootProject.ext.dependencies.mogoaicloudtelematic + implementation rootProject.ext.dependencies.mogoobuold + implementation rootProject.ext.dependencies.mogoobu + if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { implementation rootProject.ext.dependencies.mogo_core_data implementation rootProject.ext.dependencies.mogo_core_utils implementation rootProject.ext.dependencies.mogo_core_function_call implementation project(':libraries:mogo-adas') - + implementation rootProject.ext.dependencies.mogocommons } else { implementation project(':core:mogo-core-data') implementation project(':core:mogo-core-utils') @@ -71,8 +74,6 @@ dependencies { implementation project(':libraries:mogo-adas') implementation project(':foudations:mogo-commons') - - } } diff --git a/core/function-impl/mogo-core-function-obu-mogo/doc/ALPSALPINE CV2X AMI Specification v1.0.7.pdf b/core/function-impl/mogo-core-function-datacenter/doc/ALPSALPINE CV2X AMI Specification v1.0.7.pdf similarity index 100% rename from core/function-impl/mogo-core-function-obu-mogo/doc/ALPSALPINE CV2X AMI Specification v1.0.7.pdf rename to core/function-impl/mogo-core-function-datacenter/doc/ALPSALPINE CV2X AMI Specification v1.0.7.pdf diff --git a/core/function-impl/mogo-core-function-obu-mogo/doc/AMI通讯协议.docx b/core/function-impl/mogo-core-function-datacenter/doc/AMI通讯协议.docx similarity index 100% rename from core/function-impl/mogo-core-function-obu-mogo/doc/AMI通讯协议.docx rename to core/function-impl/mogo-core-function-datacenter/doc/AMI通讯协议.docx diff --git a/core/function-impl/mogo-core-function-obu-mogo/doc/CV2X_HLI_v1.0.1.pdf b/core/function-impl/mogo-core-function-datacenter/doc/CV2X_HLI_v1.0.1.pdf similarity index 100% rename from core/function-impl/mogo-core-function-obu-mogo/doc/CV2X_HLI_v1.0.1.pdf rename to core/function-impl/mogo-core-function-datacenter/doc/CV2X_HLI_v1.0.1.pdf diff --git a/core/function-impl/mogo-core-function-obu-mogo/doc/HLI通讯协议.docx b/core/function-impl/mogo-core-function-datacenter/doc/HLI通讯协议.docx similarity index 100% rename from core/function-impl/mogo-core-function-obu-mogo/doc/HLI通讯协议.docx rename to core/function-impl/mogo-core-function-datacenter/doc/HLI通讯协议.docx diff --git a/core/function-impl/mogo-core-function-datacenter/src/main/AndroidManifest.xml b/core/function-impl/mogo-core-function-datacenter/src/main/AndroidManifest.xml index ee1c554d89..e641d09ce5 100644 --- a/core/function-impl/mogo-core-function-datacenter/src/main/AndroidManifest.xml +++ b/core/function-impl/mogo-core-function-datacenter/src/main/AndroidManifest.xml @@ -1,6 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/MoGoAutopilotProvider.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/MoGoAutopilotProvider.kt index 7cf7e5da02..cc50534c63 100644 --- a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/MoGoAutopilotProvider.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/MoGoAutopilotProvider.kt @@ -62,9 +62,9 @@ import java.util.concurrent.TimeUnit /** + * 域控制器 * @author xiaoyuzhou * @date 2021/9/22 8:43 下午 - * 域控制器 */ @Route(path = MogoServicePaths.PATH_AUTO_PILOT) class MoGoAutopilotProvider : diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MoGoObuProvider.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MoGoObuProvider.kt similarity index 98% rename from core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MoGoObuProvider.kt rename to core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MoGoObuProvider.kt index f9c946d9f7..dc2f967b43 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MoGoObuProvider.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MoGoObuProvider.kt @@ -1,4 +1,4 @@ -package com.mogo.eagle.core.function.obu.mogo +package com.mogo.eagle.core.function.datacenter.obu import android.content.Context import com.alibaba.android.arouter.facade.annotation.Route diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoObuConst.java b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoObuConst.java similarity index 95% rename from core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoObuConst.java rename to core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoObuConst.java index c4aa8f0906..8134f27b41 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoObuConst.java +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoObuConst.java @@ -1,4 +1,4 @@ -package com.mogo.eagle.core.function.obu.mogo; +package com.mogo.eagle.core.function.datacenter.obu; /** * author : lxiiaopeng diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoObuDcCombineManager.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoObuDcCombineManager.kt similarity index 99% rename from core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoObuDcCombineManager.kt rename to core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoObuDcCombineManager.kt index f95f73480d..8950dd989b 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoObuDcCombineManager.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoObuDcCombineManager.kt @@ -1,4 +1,4 @@ -package com.mogo.eagle.core.function.obu.mogo +package com.mogo.eagle.core.function.datacenter.obu import android.content.Context import com.mogo.eagle.core.data.config.HmiBuildConfig diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuManager.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuManager.kt similarity index 99% rename from core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuManager.kt rename to core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuManager.kt index a942a7556e..091de99b08 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuManager.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuManager.kt @@ -1,4 +1,4 @@ -package com.mogo.eagle.core.function.obu.mogo +package com.mogo.eagle.core.function.datacenter.obu import android.content.Context import android.util.Log @@ -20,7 +20,7 @@ import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.Defa import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.TooClose import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager import com.mogo.eagle.core.function.call.obu.CallerObuListenerManager -import com.mogo.eagle.core.function.obu.mogo.utils.TrafficDataConvertUtils +import com.mogo.eagle.core.function.datacenter.obu.utils.TrafficDataConvertUtils import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuNewManager.kt similarity index 99% rename from core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt rename to core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuNewManager.kt index 93706d2adc..da706a4900 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuNewManager.kt @@ -1,4 +1,4 @@ -package com.mogo.eagle.core.function.obu.mogo +package com.mogo.eagle.core.function.datacenter.obu import android.content.Context import com.mogo.eagle.core.data.config.FunctionBuildConfig @@ -19,7 +19,7 @@ import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager import com.mogo.eagle.core.function.call.obu.CallerObuListenerManager import com.mogo.eagle.core.function.call.obu.CallerObuTrafficLightListenerManager import com.mogo.eagle.core.function.call.v2x.CallObuLimitingSpeedListenerManager -import com.mogo.eagle.core.function.obu.mogo.utils.TrafficDataConvertUtilsNew +import com.mogo.eagle.core.function.datacenter.obu.utils.TrafficDataConvertUtilsNew import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuRsuTestTriggerReceiver.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuRsuTestTriggerReceiver.kt similarity index 97% rename from core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuRsuTestTriggerReceiver.kt rename to core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuRsuTestTriggerReceiver.kt index 644de55099..d79a247af1 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuRsuTestTriggerReceiver.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuRsuTestTriggerReceiver.kt @@ -1,10 +1,10 @@ -package com.mogo.eagle.core.function.obu.mogo.receiver +package com.mogo.eagle.core.function.datacenter.obu.receiver import android.content.BroadcastReceiver import android.content.Context import android.content.Intent //import com.mogo.eagle.core.function.obu.mogo.MogoObuConst -//import com.mogo.eagle.core.function.obu.mogo.MogoPrivateObuManager +//import com.mogo.eagle.core.function.datacenter.obu.MogoPrivateObuManager //import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger //import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU //import com.zhidao.support.obu.constants.ObuConstants diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuTestNewObuReceiver.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuTestNewObuReceiver.kt similarity index 91% rename from core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuTestNewObuReceiver.kt rename to core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuTestNewObuReceiver.kt index 17f677cd98..ed1abd5575 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuTestNewObuReceiver.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuTestNewObuReceiver.kt @@ -1,10 +1,9 @@ -package com.mogo.eagle.core.function.obu.mogo.receiver +package com.mogo.eagle.core.function.datacenter.obu.receiver import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import android.util.Log -import com.mogo.eagle.core.function.obu.mogo.MogoPrivateObuNewManager +import com.mogo.eagle.core.function.datacenter.obu.MogoPrivateObuNewManager import com.mogo.support.obu.model.MogoObuRvWarningData import com.mogo.support.obu.model.advance.V2xWarning import com.mogo.support.obu.model.advance.VehBasics diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuTestNewObuRsiReceiver.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuTestNewObuRsiReceiver.kt similarity index 82% rename from core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuTestNewObuRsiReceiver.kt rename to core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuTestNewObuRsiReceiver.kt index c216a9e7be..f0b78a14f8 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuTestNewObuRsiReceiver.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuTestNewObuRsiReceiver.kt @@ -1,16 +1,11 @@ -package com.mogo.eagle.core.function.obu.mogo.receiver +package com.mogo.eagle.core.function.datacenter.obu.receiver import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import android.util.Log -import com.mogo.eagle.core.function.obu.mogo.MogoPrivateObuNewManager +import com.mogo.eagle.core.function.datacenter.obu.MogoPrivateObuNewManager import com.mogo.support.obu.model.MogoObuRsiWarningData -import com.mogo.support.obu.model.MogoObuRvWarningData import com.mogo.support.obu.model.advance.RsiWarning -import com.mogo.support.obu.model.advance.V2xWarning -import com.mogo.support.obu.model.advance.VehBasics -import com.mogo.support.obu.model.advance.WarningData /** * @author lixiaopeng diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuTestTriggerReceiver.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuTestTriggerReceiver.kt similarity index 96% rename from core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuTestTriggerReceiver.kt rename to core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuTestTriggerReceiver.kt index de530930bd..052107741e 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuTestTriggerReceiver.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuTestTriggerReceiver.kt @@ -1,10 +1,10 @@ -package com.mogo.eagle.core.function.obu.mogo.receiver +package com.mogo.eagle.core.function.datacenter.obu.receiver import android.content.BroadcastReceiver import android.content.Context import android.content.Intent //import com.mogo.eagle.core.function.obu.mogo.MogoObuConst -//import com.mogo.eagle.core.function.obu.mogo.MogoPrivateObuManager +//import com.mogo.eagle.core.function.datacenter.obu.MogoPrivateObuManager //import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger //import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU //import com.zhidao.support.obu.constants.ObuConstants diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuTestTriggerRecognizedReceiver.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuTestTriggerRecognizedReceiver.kt similarity index 93% rename from core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuTestTriggerRecognizedReceiver.kt rename to core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuTestTriggerRecognizedReceiver.kt index fa51916e3b..cd7f5ce3df 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/receiver/ObuTestTriggerRecognizedReceiver.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/receiver/ObuTestTriggerRecognizedReceiver.kt @@ -1,10 +1,10 @@ -package com.mogo.eagle.core.function.obu.mogo.receiver +package com.mogo.eagle.core.function.datacenter.obu.receiver import android.content.BroadcastReceiver import android.content.Context import android.content.Intent //import com.mogo.eagle.core.function.obu.mogo.MogoObuConst -//import com.mogo.eagle.core.function.obu.mogo.MogoPrivateObuManager +//import com.mogo.eagle.core.function.datacenter.obu.MogoPrivateObuManager //import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger //import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU //import com.zhidao.support.obu.model.CvxHvInfoIndInfo diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/utils/TrafficDataConvertUtils.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/utils/TrafficDataConvertUtils.kt similarity index 98% rename from core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/utils/TrafficDataConvertUtils.kt rename to core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/utils/TrafficDataConvertUtils.kt index 8e94bc8bc6..7dfc6f61ec 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/utils/TrafficDataConvertUtils.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/utils/TrafficDataConvertUtils.kt @@ -1,4 +1,4 @@ -package com.mogo.eagle.core.function.obu.mogo.utils +package com.mogo.eagle.core.function.datacenter.obu.utils import com.mogo.eagle.core.data.traffic.TrafficData import com.mogo.eagle.core.data.enums.TrafficTypeEnum diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/utils/TrafficDataConvertUtilsNew.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/utils/TrafficDataConvertUtilsNew.kt similarity index 98% rename from core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/utils/TrafficDataConvertUtilsNew.kt rename to core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/utils/TrafficDataConvertUtilsNew.kt index 7a253a920d..551c4d9c8b 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/utils/TrafficDataConvertUtilsNew.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/utils/TrafficDataConvertUtilsNew.kt @@ -1,6 +1,5 @@ -package com.mogo.eagle.core.function.obu.mogo.utils +package com.mogo.eagle.core.function.datacenter.obu.utils -import android.util.Log import com.mogo.eagle.core.data.enums.TrafficTypeEnum import com.mogo.eagle.core.data.traffic.TrafficData import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger diff --git a/core/function-impl/mogo-core-function-hmi/build.gradle b/core/function-impl/mogo-core-function-hmi/build.gradle index df17cbf358..73ff2911a2 100644 --- a/core/function-impl/mogo-core-function-hmi/build.gradle +++ b/core/function-impl/mogo-core-function-hmi/build.gradle @@ -88,7 +88,6 @@ dependencies { api rootProject.ext.dependencies.mogo_core_data api rootProject.ext.dependencies.mogo_core_utils api rootProject.ext.dependencies.mogo_core_network - api rootProject.ext.dependencies.mogo_core_function_obu_mogo api rootProject.ext.dependencies.mogo_core_function_map api rootProject.ext.dependencies.mogo_core_function_v2x api rootProject.ext.dependencies.mogo_core_function_devatools @@ -104,7 +103,6 @@ dependencies { api project(':core:mogo-core-res') api project(':core:mogo-core-data') api project(':core:mogo-core-utils') - api project(':core:function-impl:mogo-core-function-obu-mogo') api project(':core:function-impl:mogo-core-function-map') api project(':core:function-impl:mogo-core-function-v2x') api project(':core:function-impl:mogo-core-function-devatools') diff --git a/core/function-impl/mogo-core-function-obu-mogo/.gitignore b/core/function-impl/mogo-core-function-obu-mogo/.gitignore deleted file mode 100644 index 42afabfd2a..0000000000 --- a/core/function-impl/mogo-core-function-obu-mogo/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-obu-mogo/build.gradle b/core/function-impl/mogo-core-function-obu-mogo/build.gradle deleted file mode 100644 index 9bf311e83c..0000000000 --- a/core/function-impl/mogo-core-function-obu-mogo/build.gradle +++ /dev/null @@ -1,67 +0,0 @@ -plugins { - id 'com.android.library' - id 'kotlin-android' - id 'kotlin-android-extensions' - id 'kotlin-kapt' - id 'com.alibaba.arouter' -} - -android { - compileSdkVersion rootProject.ext.android.compileSdkVersion - defaultConfig { - minSdkVersion rootProject.ext.android.minSdkVersion - targetSdkVersion rootProject.ext.android.targetSdkVersion - versionCode Integer.valueOf(VERSION_CODE) - versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION") - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles 'consumer-rules.pro' - - //ARouter apt 参数 - kapt { - useBuildCache = false - arguments { - arg("AROUTER_MODULE_NAME", project.getName()) - } - } - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } -} - -dependencies { - - implementation rootProject.ext.dependencies.androidxappcompat - implementation rootProject.ext.dependencies.androidxconstraintlayout - implementation rootProject.ext.dependencies.arouter - implementation rootProject.ext.dependencies.rxandroid - - kapt rootProject.ext.dependencies.aroutercompiler - - if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { - implementation rootProject.ext.dependencies.mogo_core_data - implementation rootProject.ext.dependencies.mogo_core_utils - } else { - implementation project(':core:mogo-core-data') - implementation project(':core:mogo-core-utils') - implementation project(':core:mogo-core-function-call') - } - - implementation rootProject.ext.dependencies.mogoobuold - implementation rootProject.ext.dependencies.mogoobu - -} - -apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-obu-mogo/consumer-rules.pro b/core/function-impl/mogo-core-function-obu-mogo/consumer-rules.pro deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/core/function-impl/mogo-core-function-obu-mogo/gradle.properties b/core/function-impl/mogo-core-function-obu-mogo/gradle.properties deleted file mode 100644 index 0d4b689fa3..0000000000 --- a/core/function-impl/mogo-core-function-obu-mogo/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -GROUP=com.mogo.eagle.core.function.impl -POM_ARTIFACT_ID=obu-mogo -VERSION_CODE=1 diff --git a/core/function-impl/mogo-core-function-obu-mogo/proguard-rules.pro b/core/function-impl/mogo-core-function-obu-mogo/proguard-rules.pro deleted file mode 100644 index 481bb43481..0000000000 --- a/core/function-impl/mogo-core-function-obu-mogo/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/AndroidManifest.xml b/core/function-impl/mogo-core-function-obu-mogo/src/main/AndroidManifest.xml deleted file mode 100644 index 1f72d0c85c..0000000000 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/AndroidManifest.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoRoboBusJinlvM1StatesListener.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoRoboBusJinlvM1StatesListener.kt index fe41e2e245..6f2b6348d7 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoRoboBusJinlvM1StatesListener.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoRoboBusJinlvM1StatesListener.kt @@ -1,6 +1,5 @@ package com.mogo.eagle.core.function.api.autopilot -import chassis.ChassisStatesOuterClass import chassis.VehicleStateOuterClass /** diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerAutoPilotStatusListenerManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerAutoPilotStatusListenerManager.kt index a19f54dc4f..e158d6bced 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerAutoPilotStatusListenerManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerAutoPilotStatusListenerManager.kt @@ -10,9 +10,9 @@ import mogo_msg.MogoReportMsg import system_master.SystemStatusInfo /** - * @author xiaoyuzhou - * @date 2021/9/30 5:48 下午 * 域控制器相关的回调监听 + * @date 2021/9/30 5:48 下午 + * @author xiaoyuzhou */ object CallerAutoPilotStatusListenerManager : CallerBase() { diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/REEADME.md b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/REEADME.md index 6d3fa01f95..313da68621 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/REEADME.md +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/REEADME.md @@ -1,6 +1,58 @@ -#### CallerAutoPilotStatusListenerManager 管理自动驾驶中的状态及参数信息 +#### 管理与工控机相关的数据回掉 + +``` kotlin +/** + * 添加 监听 + * @param tag 标记,用来注销监听使用 + * @param listener 监听回调 + */ +fun addListener( + tag: String, + listener: T +) + +/** + * 在添加了监听后执行 + */ +open fun doSomeAfterAddListener(tag: String, listener: T) + +/** + * 删除监听 + * @param tag 标记,用来注销监听使用 + */ +fun removeListener(tag: String) + +/** + * 删除监听 + * @param listener 要删除的监听对象 + */ +fun removeListener(listener: T) +``` + +CallerAutopilotActionsListenerManager +CallerAutopilotCarConfigListenerManager +CallerAutopilotIdentifyListenerManager +CallerAutoPilotManager +CallerAutopilotPointCloudListenerManager +CallerAutopilotRecordListenerManager +CallerAutopilotStatisticsListenerManager +CallerAutoPilotStatusListenerManager +CallerAutopilotVehicleStateListenerManager +CallerBatteryManagementSystemListenerManager +CallerChassisAccStateListenerManager +CallerChassisBrakeStateListenerManager +CallerChassisGearStateListenerManager +CallerChassisLamplightListenerManager +CallerChassisLocationGCJ20ListenerManager +CallerChassisLocationWGS84ListenerManager +CallerChassisSteeringStateListenerManager +CallerChassisThrottleStateListenerManager +CallerPlanningActionsListenerManager +CallerPlanningRottingListenerManager +CallerPlanningTrajectoryListenerManager +CallerRoboBusJinlvM1StatesListenerManager +CallerStartAutopilotFailedListenerManager +CallerSweeperFutianCleanSystemListenerManager + + -AutopilotStatusInfo: -连接信息 -实时经纬度、速度、车辆硬件状态 -最后一次启动自动驾驶时候的启动参数 AutopilotControlParameters diff --git a/modules.txt b/modules.txt index 4286b0eb33..775878c1c2 100644 --- a/modules.txt +++ b/modules.txt @@ -18,7 +18,7 @@ :test:crashreport-apm :test:crashreport-noop :test:crashreport-upgrade -:core:function-impl:mogo-core-function-obu-mogo +:core:function-impl:mogo-core-function-datacenter :core:function-impl:mogo-core-function-hmi :core:function-impl:mogo-core-function-map :core:function-impl:mogo-core-function-v2x diff --git a/settings.gradle b/settings.gradle index c262ab3649..4954d993e1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -28,13 +28,11 @@ include ':core:function-impl:mogo-core-function-hmi' include ':core:function-impl:mogo-core-function-map' // v2x预警业务,本地+云端预警 include ':core:function-impl:mogo-core-function-v2x' -// 自研OBU业务 -include ':core:function-impl:mogo-core-function-obu-mogo' // 车聊聊业务 include ':core:function-impl:mogo-core-function-chat' // 业务biz include ':core:function-impl:mogo-core-function-biz' -// 消息盒子 +// 消息盒子、自研OBU业务 include ':core:function-impl:mogo-core-function-datacenter' // 模块 From fa04ed406eadcdb38157f040b5486c04e87059e7 Mon Sep 17 00:00:00 2001 From: lixiaopeng Date: Mon, 30 Jan 2023 17:49:17 +0800 Subject: [PATCH 26/48] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E8=80=81obu=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=90=88=E5=B9=B6EventTypeEnumNew?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.gradle | 4 +- .../redlightwarning/RedLightWarningManager.kt | 26 +- .../function/biz/v2x/vip/VipCarManager.kt | 34 +- .../build.gradle | 1 - .../mogo-core-function-hmi/build.gradle | 2 - .../receiver/V2XWarningBroadcastReceiver.kt | 4 +- .../core/function/hmi/ui/MoGoHmiFragment.kt | 23 +- .../adapter/DriverMsgBoxBubbleAdapter.kt | 3 +- .../msgbox/adapter/DriverMsgBoxListAdapter.kt | 3 +- .../adapter/PassengerMsgBoxBubbleAdapter.kt | 6 +- .../adapter/PassengerMsgBoxListAdapter.kt | 4 +- .../hmi/ui/setting/DebugSettingView.kt | 4 +- .../function/hmi/ui/takeover/TakeOverView.kt | 10 +- .../function/main/MainMoGoApplication.java | 3 +- .../impl/marker/drawer/MarkerDrawer.java | 4 +- .../mogo-core-function-obu-mogo/build.gradle | 1 - .../core/function/obu/mogo/MoGoObuProvider.kt | 13 +- .../obu/mogo/MogoPrivateObuManager.kt | 1001 ----------------- .../obu/mogo/MogoPrivateObuNewManager.kt | 12 +- .../obu/mogo/utils/TrafficDataConvertUtils.kt | 133 --- .../v2x/events/alarm/V2XAlarmServer.java | 8 +- .../manager/impl/MoGoV2XMarkerManager.java | 12 +- .../v2x/events/marker/V2XMarkerAdapter.java | 18 +- .../v2x/events/view/V2XMarkerRoadEventView.kt | 10 +- .../core/data/config/CloudPoiManager.java | 31 +- .../eagle/core/data/enums/EventTypeEnumNew.kt | 16 + .../eagle/core/data/enums/EventTypeHelper.kt | 68 +- .../data/map/entity/V2XRoadEventEntity.java | 13 +- 28 files changed, 156 insertions(+), 1311 deletions(-) delete mode 100644 core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuManager.kt delete mode 100644 core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/utils/TrafficDataConvertUtils.kt diff --git a/config.gradle b/config.gradle index 9c6fdcf353..f93598a206 100644 --- a/config.gradle +++ b/config.gradle @@ -91,9 +91,7 @@ ext { // obu sdk obusdk : "com.zhidao.enterprise.smartv2x:smartv2x:1.0.0.3", - mogoobuold : 'com.zhidao.support.obu:mogoobu:1.0.0.33', - mogoobu : 'com.mogo.support.obu:mogo-obu:1.0.6', - mogoami : 'com.zhidao.support.obu.ami:mogoami:1.0.0.24', + mogoobu : 'com.mogo.support.obu:mogo-obu:1.1.0_beta0', // google googlezxing : "com.google.zxing:core:3.3.3", diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/redlightwarning/RedLightWarningManager.kt b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/redlightwarning/RedLightWarningManager.kt index 6b07d8fc61..283bd2d5fd 100644 --- a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/redlightwarning/RedLightWarningManager.kt +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/redlightwarning/RedLightWarningManager.kt @@ -4,7 +4,7 @@ import android.util.Log import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_IVP import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_IVP_GREEN import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.V2I -import com.mogo.eagle.core.data.enums.EventTypeEnum +import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.data.map.MogoLatLng import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType @@ -209,17 +209,17 @@ class RedLightWarningManager : IMoGoTrafficLightListener, IMoGoVipSetListener, MsgBoxBean( MsgBoxType.V2X, V2XMsg( - EventTypeEnum.TYPE_USECASE_ID_IVP.poiType, - EventTypeEnum.TYPE_USECASE_ID_IVP.content, - EventTypeEnum.TYPE_USECASE_ID_IVP.tts + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.content, + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.tts ) ) ) CallerHmiManager.warningV2X( - EventTypeEnum.TYPE_USECASE_ID_IVP.poiType, - EventTypeEnum.TYPE_USECASE_ID_IVP.content, - EventTypeEnum.TYPE_USECASE_ID_IVP.tts, - EventTypeEnum.TYPE_USECASE_ID_IVP.poiType, + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.content, + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.tts, + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, null, true, 5000L @@ -235,11 +235,11 @@ class RedLightWarningManager : IMoGoTrafficLightListener, IMoGoVipSetListener, CallerLogger.d("$M_V2X$TAG", "=====绿灯通行预警=====") ThreadUtils.runOnUiThread { val content = String.format( - EventTypeEnum.getWarningContent(EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType), + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType), speed ) val tts = String.format( - EventTypeEnum.getWarningTts(EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType), + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType), speed ) if (content.isNullOrEmpty() || tts.isNullOrEmpty()) { @@ -249,17 +249,17 @@ class RedLightWarningManager : IMoGoTrafficLightListener, IMoGoVipSetListener, MsgBoxBean( MsgBoxType.V2X, V2XMsg( - EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType, + EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType, content, tts ) ) ) CallerHmiManager.warningV2X( - EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType, + EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType, content, tts, - EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType, + EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType, null, true, 5000L diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/vip/VipCarManager.kt b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/vip/VipCarManager.kt index eef302a909..b3701db467 100644 --- a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/vip/VipCarManager.kt +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/vip/VipCarManager.kt @@ -10,7 +10,7 @@ import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager import com.mogo.cloud.passport.MoGoAiCloudClientConfig import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_VIP import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.V2N -import com.mogo.eagle.core.data.enums.EventTypeEnum +import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.V2XMsg @@ -209,17 +209,17 @@ class VipCarManager : IMogoOnMessageListener, IMoGoTrafficLightListe val light = this.result?.currentRoadTrafficLight() if (light != null && light.isGreen()) { showWarning( - EventTypeEnum.TYPE_VIP_IDENTIFICATION_EXTEND.poiType, - EventTypeEnum.TYPE_VIP_IDENTIFICATION_EXTEND.content, - EventTypeEnum.TYPE_VIP_IDENTIFICATION_EXTEND.tts, - EventTypeEnum.TYPE_VIP_IDENTIFICATION_EXTEND.poiType + EventTypeEnumNew.TYPE_VIP_IDENTIFICATION_EXTEND.poiType, + EventTypeEnumNew.TYPE_VIP_IDENTIFICATION_EXTEND.content, + EventTypeEnumNew.TYPE_VIP_IDENTIFICATION_EXTEND.tts, + EventTypeEnumNew.TYPE_VIP_IDENTIFICATION_EXTEND.poiType ) } else { showWarning( - EventTypeEnum.TYPE_VIP_IDENTIFICATION_PASS.poiType, - EventTypeEnum.TYPE_VIP_IDENTIFICATION_PASS.content, - EventTypeEnum.TYPE_VIP_IDENTIFICATION_PASS.tts, - EventTypeEnum.TYPE_VIP_IDENTIFICATION_PASS.poiType + EventTypeEnumNew.TYPE_VIP_IDENTIFICATION_PASS.poiType, + EventTypeEnumNew.TYPE_VIP_IDENTIFICATION_PASS.content, + EventTypeEnumNew.TYPE_VIP_IDENTIFICATION_PASS.tts, + EventTypeEnumNew.TYPE_VIP_IDENTIFICATION_PASS.poiType ) } return@turnLightToGreen @@ -228,10 +228,10 @@ class VipCarManager : IMogoOnMessageListener, IMoGoTrafficLightListe // 请求变灯失败,根据灯态来提示。 此处灯态未获取到 if (this.result == null || this.result?.currentRoadTrafficLight() == null) { showWarning( - EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.poiType, - EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.content + ", 稍后重试", - EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.tts, - EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.poiType + EventTypeEnumNew.TYPE_VIP_ERROR_IDENTIFICATION.poiType, + EventTypeEnumNew.TYPE_VIP_ERROR_IDENTIFICATION.content + ", 稍后重试", + EventTypeEnumNew.TYPE_VIP_ERROR_IDENTIFICATION.tts, + EventTypeEnumNew.TYPE_VIP_ERROR_IDENTIFICATION.poiType ) return@turnLightToGreen } @@ -249,10 +249,10 @@ class VipCarManager : IMogoOnMessageListener, IMoGoTrafficLightListe "${temp}秒后重试" } showWarning( - EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.poiType, - EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.content + time, - EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.tts, - EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.poiType + EventTypeEnumNew.TYPE_VIP_ERROR_IDENTIFICATION.poiType, + EventTypeEnumNew.TYPE_VIP_ERROR_IDENTIFICATION.content + time, + EventTypeEnumNew.TYPE_VIP_ERROR_IDENTIFICATION.tts, + EventTypeEnumNew.TYPE_VIP_ERROR_IDENTIFICATION.poiType ) } else { CallerLogger.d( diff --git a/core/function-impl/mogo-core-function-datacenter/build.gradle b/core/function-impl/mogo-core-function-datacenter/build.gradle index b6e5f51262..a4c999e435 100644 --- a/core/function-impl/mogo-core-function-datacenter/build.gradle +++ b/core/function-impl/mogo-core-function-datacenter/build.gradle @@ -54,7 +54,6 @@ dependencies { kapt rootProject.ext.dependencies.androidxroomcompiler implementation rootProject.ext.dependencies.androidxroomktx - implementation rootProject.ext.dependencies.mogoami implementation rootProject.ext.dependencies.mogoaicloudtelematic if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { diff --git a/core/function-impl/mogo-core-function-hmi/build.gradle b/core/function-impl/mogo-core-function-hmi/build.gradle index df17cbf358..26c469da4b 100644 --- a/core/function-impl/mogo-core-function-hmi/build.gradle +++ b/core/function-impl/mogo-core-function-hmi/build.gradle @@ -72,8 +72,6 @@ dependencies { implementation rootProject.ext.dependencies.arouter kapt rootProject.ext.dependencies.aroutercompiler - implementation rootProject.ext.dependencies.mogoami - implementation rootProject.ext.dependencies.android_start_up implementation rootProject.ext.dependencies.cicle_indicator implementation rootProject.ext.dependencies.koomnative diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XWarningBroadcastReceiver.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XWarningBroadcastReceiver.kt index 3a60406e12..30f289c218 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XWarningBroadcastReceiver.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XWarningBroadcastReceiver.kt @@ -4,11 +4,11 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log +import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.function.call.hmi.CallerHmiManager import com.mogo.eagle.core.function.hmi.WaringConst import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI -import com.mogo.eagle.core.data.enums.EventTypeEnum import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.V2XMsg @@ -75,7 +75,7 @@ class V2XWarningBroadcastReceiver : BroadcastReceiver() { ttsContent: String?, tag: String? ) { - if (EventTypeEnum.TYPE_USECASE_ID_IVP.poiType == v2xType.toString()) { + if (EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType == v2xType.toString()) { CallerHmiManager.showLimitingVelocity(1, 1) } if (alertContent.isNullOrEmpty() || ttsContent.isNullOrEmpty()) { diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt index a0ac521b3a..9f482ca275 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt @@ -3,7 +3,7 @@ package com.mogo.eagle.core.function.hmi.ui import android.content.Context import android.os.Bundle import android.text.TextUtils -import android.util.* +import android.util.Log import android.view.View import android.view.ViewGroup import android.view.animation.AlphaAnimation @@ -24,16 +24,12 @@ import com.mogo.eagle.core.data.constants.MoGoFragmentPaths import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_RTS import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.V2I import com.mogo.eagle.core.data.dispatch.DispatchAdasAutoPilotLocReceiverBean -import com.mogo.eagle.core.data.enums.EventTypeEnum +import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.data.enums.WarningDirectionEnum import com.mogo.eagle.core.data.map.Infrastructure -import com.mogo.eagle.core.data.msgbox.MsgBoxBean -import com.mogo.eagle.core.data.msgbox.MsgBoxType -import com.mogo.eagle.core.data.msgbox.RecordBagMsg import com.mogo.eagle.core.data.notice.NoticeNormalData import com.mogo.eagle.core.data.notice.NoticeTrafficStylePushData import com.mogo.eagle.core.data.report.ReportEntity -import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener import com.mogo.eagle.core.function.api.hmi.IMoGoHmiViewProxy import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.AutoPilotStatusView_TAG import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.CameraView_TAG @@ -46,16 +42,12 @@ import com.mogo.eagle.core.function.api.hmi.view.IViewTrafficLight import com.mogo.eagle.core.function.api.hmi.warning.IMoGoHmiProvider import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager -import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager -import com.mogo.eagle.core.function.call.biz.CallerFuncBizManager import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager import com.mogo.eagle.core.function.call.hmi.CallerHmiManager import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager -import com.mogo.eagle.core.function.call.map.CallerMapDataCollectorManager import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.Turning -import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.function.hmi.notification.WarningFloat import com.mogo.eagle.core.function.hmi.ui.bindingcar.ModifyBindingCarDialog @@ -67,10 +59,10 @@ import com.mogo.eagle.core.function.hmi.ui.notice.NoticeCheckDialog import com.mogo.eagle.core.function.hmi.ui.notice.traffic.NoticeTrafficDialog import com.mogo.eagle.core.function.hmi.ui.setting.CameraLiveView.Companion.cameraLiveView import com.mogo.eagle.core.function.hmi.ui.setting.IPCReportWindow -import com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugView.Companion.toggleDebugView import com.mogo.eagle.core.function.hmi.ui.setting.ToolsView.Companion.toolsView import com.mogo.eagle.core.function.hmi.ui.tools.AdUpgradeDialog -import com.mogo.eagle.core.function.hmi.ui.widget.* +import com.mogo.eagle.core.function.hmi.ui.widget.DemoModeView +import com.mogo.eagle.core.function.hmi.ui.widget.StatusBarView import com.mogo.eagle.core.function.main.DisplayEffectsHelper import com.mogo.eagle.core.utilcode.kotlin.safeCancel import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils @@ -78,17 +70,12 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr -import com.mogo.eagle.core.utilcode.mogo.toast.TipToast import com.mogo.eagle.core.utilcode.reminder.api.IReminder import com.mogo.eagle.core.utilcode.util.ThreadUtils -import com.mogo.eagle.core.utilcode.util.TimeUtils -import com.mogo.eagle.core.utilcode.util.TimeUtils.millis2String import com.mogo.eagle.core.utilcode.util.ToastUtils -import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig import com.zhjt.service_biz.BizConfig import kotlinx.android.synthetic.main.fragment_hmi.* import kotlinx.coroutines.* -import record_cache.RecordPanelOuterClass import java.util.concurrent.atomic.AtomicReference /** @@ -326,7 +313,7 @@ class MoGoHmiFragment : MvpFragment(), playTts && !AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode) activity?.let { val warningContent = alertContent - ?: EventTypeEnum.getWarningContent(v2xType) + ?: EventTypeEnumNew.getWarningContent(v2xType) //占道施工预警 if (v2xType == "10006" || v2xType == "100061") { diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/DriverMsgBoxBubbleAdapter.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/DriverMsgBoxBubbleAdapter.kt index ab7bab281e..e6917eee75 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/DriverMsgBoxBubbleAdapter.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/DriverMsgBoxBubbleAdapter.kt @@ -8,7 +8,6 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import com.mogo.eagle.core.data.enums.EventTypeEnum import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.data.msgbox.* import com.mogo.eagle.core.data.report.ReportEntity @@ -129,7 +128,7 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A EventTypeEnumNew.getUpdateIconRes(v2XMsg.type))) }else{ holder.ivV2XImage.setImageDrawable(activity.resources.getDrawable( - EventTypeEnum.getUpdateIconRes(v2XMsg.type))) + EventTypeEnumNew.getUpdateIconRes(v2XMsg.type))) } } } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/DriverMsgBoxListAdapter.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/DriverMsgBoxListAdapter.kt index 65a914808d..5e02c0c918 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/DriverMsgBoxListAdapter.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/DriverMsgBoxListAdapter.kt @@ -9,7 +9,6 @@ import android.widget.ImageView import android.widget.TextView import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView -import com.mogo.eagle.core.data.enums.EventTypeEnum import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.data.msgbox.* import com.mogo.eagle.core.data.report.ReportEntity @@ -219,7 +218,7 @@ class DriverMsgBoxListAdapter(private val activity: Activity) : RecyclerView.Ada EventTypeEnumNew.getUpdateIconRes(v2XMsg.type))) }else{ holder.ivV2XImage.setImageDrawable(activity.resources.getDrawable( - EventTypeEnum.getUpdateIconRes(v2XMsg.type))) + EventTypeEnumNew.getUpdateIconRes(v2XMsg.type))) } } } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/PassengerMsgBoxBubbleAdapter.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/PassengerMsgBoxBubbleAdapter.kt index 6b0c6750a6..858f15e6cd 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/PassengerMsgBoxBubbleAdapter.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/PassengerMsgBoxBubbleAdapter.kt @@ -8,17 +8,15 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import com.mogo.eagle.core.data.enums.EventTypeEnum import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.NoticeFrCloudMsg import com.mogo.eagle.core.data.msgbox.V2XMsg -import com.mogo.eagle.core.utilcode.mogo.glide.GlideApp -import com.mogo.eagle.core.data.notice.NoticeNormalData import com.mogo.eagle.core.function.call.hmi.CallerHmiManager import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager import com.mogo.eagle.core.function.hmi.R +import com.mogo.eagle.core.utilcode.mogo.glide.GlideApp import com.mogo.eagle.core.utilcode.mogo.glide.transform.GlideRoundedCornersTransform import com.mogo.eagle.core.utilcode.util.TimeUtils import com.mogo.eagle.core.utilcode.util.TimeUtils.getHourMinFormat @@ -101,7 +99,7 @@ class PassengerMsgBoxBubbleAdapter(private val activity: Activity): RecyclerView EventTypeEnumNew.getUpdateIconRes(v2XMsg.type))) }else{ holder.ivPassengerV2XImage.setImageDrawable(activity.resources.getDrawable( - EventTypeEnum.getUpdateIconRes(v2XMsg.type))) + EventTypeEnumNew.getUpdateIconRes(v2XMsg.type))) } } } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/PassengerMsgBoxListAdapter.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/PassengerMsgBoxListAdapter.kt index 50c635e49c..1dbb6a3be9 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/PassengerMsgBoxListAdapter.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/msgbox/adapter/PassengerMsgBoxListAdapter.kt @@ -7,13 +7,11 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import com.mogo.eagle.core.data.enums.EventTypeEnum import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.NoticeFrCloudMsg import com.mogo.eagle.core.data.msgbox.V2XMsg -import com.mogo.eagle.core.data.notice.NoticeNormalData import com.mogo.eagle.core.function.call.hmi.CallerHmiManager import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.utilcode.mogo.glide.GlideApp @@ -93,7 +91,7 @@ class PassengerMsgBoxListAdapter(private val activity: Activity): RecyclerView.A EventTypeEnumNew.getUpdateIconRes(v2XMsg.type))) }else{ holder.ivPassengerV2XImage.setImageDrawable(activity.resources.getDrawable( - EventTypeEnum.getUpdateIconRes(v2XMsg.type))) + EventTypeEnumNew.getUpdateIconRes(v2XMsg.type))) } } } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt index cb59e84424..6911df61f8 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt @@ -74,7 +74,7 @@ import com.mogo.eagle.core.utilcode.mogo.toast.TipToast import com.mogo.eagle.core.utilcode.util.* import com.mogo.map.uicontroller.VisualAngleMode import com.mogo.map.uicontroller.VisualAngleMode.* -import com.zhidao.easysocket.utils.L +//import com.zhidao.easysocket.utils.L import com.zhjt.mogo_core_function_devatools.env.* import kotlinx.android.synthetic.main.view_debug_setting.view.* import mogo.telematics.pad.MessagePad @@ -1269,7 +1269,7 @@ internal class DebugSettingView @JvmOverloads constructor( * 设置是否输出OBU日志 true-打印日志,false-不打印日志 */ tbObuLog.setOnCheckedChangeListener { _, isChecked -> - L.setEnableLog(isChecked) +// L.setEnableLog(isChecked) } /** diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/takeover/TakeOverView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/takeover/TakeOverView.kt index 23dde7c51a..4b447c2eaa 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/takeover/TakeOverView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/takeover/TakeOverView.kt @@ -6,7 +6,7 @@ import android.view.LayoutInflater import android.view.View import androidx.constraintlayout.widget.ConstraintLayout import com.mogo.eagle.core.data.config.FunctionBuildConfig -import com.mogo.eagle.core.data.enums.EventTypeEnum +import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager @@ -56,10 +56,10 @@ class TakeOverView @JvmOverloads constructor( MogoReport.Code.Error.EMAP.EXIT_AUTOPILOT_FOR_CHASSIS, MogoReport.Code.Error.EMAP.EXIT_AUTOPILOT_FOR_DISTANCE -> { CallerHmiManager.warningV2X( - EventTypeEnum.TAKE_OVER_EVENT.poiType, - EventTypeEnum.TAKE_OVER_EVENT.content, - EventTypeEnum.TAKE_OVER_EVENT.tts, - EventTypeEnum.TAKE_OVER_EVENT.poiType, + EventTypeEnumNew.TAKE_OVER_EVENT.poiType, + EventTypeEnumNew.TAKE_OVER_EVENT.content, + EventTypeEnumNew.TAKE_OVER_EVENT.tts, + EventTypeEnumNew.TAKE_OVER_EVENT.poiType, object : IMoGoWarningStatusListener { override fun onShow() { takeOver = true diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java index 9be0248578..d67b55b7c7 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java @@ -34,7 +34,6 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr; import com.mogo.eagle.core.utilcode.util.ProcessUtils; import com.mogo.eagle.core.utilcode.util.SPUtils; -import com.zhidao.support.obu.ami.AmiClientManager; import java.io.File; import java.lang.reflect.Field; @@ -203,7 +202,7 @@ public abstract class MainMoGoApplication extends AbsMogoApplication { */ private void connectAmiIp() { String ipAddress = SharedPrefsMgr.getInstance(AbsMogoApplication.getApp().getBaseContext()).getString(MoGoConfig.OBU_IP, "192.168.1.199"); - AmiClientManager.getInstance().setObuIp(ipAddress); +// AmiClientManager.getInstance().setObuIp(ipAddress); } private void initModules() { diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/impl/marker/drawer/MarkerDrawer.java b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/impl/marker/drawer/MarkerDrawer.java index 63bba6385f..7195182391 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/impl/marker/drawer/MarkerDrawer.java +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/impl/marker/drawer/MarkerDrawer.java @@ -5,6 +5,7 @@ import android.text.TextUtils; import com.mogo.cloud.commons.utils.CoordinateUtils; import com.mogo.commons.AbsMogoApplication; import com.mogo.commons.module.status.MogoStatusManager; +import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import com.mogo.eagle.core.data.map.MogoLatLng; import com.mogo.eagle.core.data.map.entity.MarkerExploreWay; import com.mogo.eagle.core.data.map.entity.MarkerNoveltyInfo; @@ -19,7 +20,6 @@ import com.mogo.map.MogoMarkerManager; import com.mogo.map.marker.IMogoMarker; import com.mogo.map.marker.IMogoMarkerClickListener; import com.mogo.map.marker.MogoMarkerOptions; -import com.mogo.eagle.core.data.enums.EventTypeEnum; /** * @author congtaowang @@ -81,7 +81,7 @@ public class MarkerDrawer { Object bindObj = markerShowEntity.getBindObj(); if (bindObj instanceof MarkerExploreWay && ((MarkerExploreWay) bindObj).getPoiType() != null) { String poiType = ((MarkerExploreWay) bindObj).getPoiType(); - options.icon3DRes(EventTypeEnum.getMarker3DRes(poiType)); + options.icon3DRes(EventTypeEnumNew.getMarker3DRes(poiType)); } } diff --git a/core/function-impl/mogo-core-function-obu-mogo/build.gradle b/core/function-impl/mogo-core-function-obu-mogo/build.gradle index 9bf311e83c..5f05fb457c 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/build.gradle +++ b/core/function-impl/mogo-core-function-obu-mogo/build.gradle @@ -59,7 +59,6 @@ dependencies { implementation project(':core:mogo-core-function-call') } - implementation rootProject.ext.dependencies.mogoobuold implementation rootProject.ext.dependencies.mogoobu } diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MoGoObuProvider.kt b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MoGoObuProvider.kt index f9c946d9f7..2f8b946bee 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MoGoObuProvider.kt +++ b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MoGoObuProvider.kt @@ -11,6 +11,7 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr import com.mogo.eagle.core.utilcode.util.CommonUtils +import com.mogo.support.obu.MogoObuManager /** * @author xiaoyuzhou @@ -54,9 +55,6 @@ class MoGoObuProvider : IMoGoObuProvider { ipAddress, CommonUtils.getIpAddressString() ) - - //old obu - MogoPrivateObuManager.INSTANCE.init(context, ipAddress) } else if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) { //taxi 司机端和乘客端 val ipAddress = SharedPrefsMgr.getInstance(context).getString(MoGoConfig.OBU_IP, taxiObuIp) @@ -66,9 +64,6 @@ class MoGoObuProvider : IMoGoObuProvider { ipAddress, CommonUtils.getIpAddressString() ) - - //old obu - MogoPrivateObuManager.INSTANCE.init(context, ipAddress) } } } @@ -95,18 +90,16 @@ class MoGoObuProvider : IMoGoObuProvider { CommonUtils.getIpAddressString() ) - //连接old obu - MogoPrivateObuManager.INSTANCE.connectObu(it, ipAddress) } } } override fun disConnect() { - MogoPrivateObuManager.INSTANCE.disConnectObu() + MogoPrivateObuNewManager.INSTANCE.disconnect() } override fun isConnected(): Boolean { - return MogoPrivateObuManager.INSTANCE.isConnected() + return MogoObuManager.getInstance().connectStatus == 1 } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuManager.kt b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuManager.kt deleted file mode 100644 index a942a7556e..0000000000 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuManager.kt +++ /dev/null @@ -1,1001 +0,0 @@ -package com.mogo.eagle.core.function.obu.mogo - -import android.content.Context -import android.util.Log -import com.mogo.cloud.passport.MoGoAiCloudClientConfig -import com.mogo.eagle.core.data.app.AppConfigInfo -import com.mogo.eagle.core.data.config.FunctionBuildConfig -import com.mogo.eagle.core.data.enums.EventTypeEnum -import com.mogo.eagle.core.data.enums.EventTypeHelper -import com.mogo.eagle.core.data.enums.WarningDirectionEnum -import com.mogo.eagle.core.data.msgbox.MsgBoxBean -import com.mogo.eagle.core.data.msgbox.MsgBoxType -import com.mogo.eagle.core.data.msgbox.V2XMsg -import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener -import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager -import com.mogo.eagle.core.function.call.hmi.CallerHmiManager -import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager -import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager -import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.Default -import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.TooClose -import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager -import com.mogo.eagle.core.function.call.obu.CallerObuListenerManager -import com.mogo.eagle.core.function.obu.mogo.utils.TrafficDataConvertUtils -import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger -import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU -import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr -import com.zhidao.support.obu.MogoObuManager -import com.zhidao.support.obu.OnMogoObuListener -import com.zhidao.support.obu.constants.ObuConstants -import com.zhidao.support.obu.model.* -import com.zhidao.support.obu.model.advance.Light -import org.json.JSONObject - -/** - * - * @author lixiaopeng - * @since 2021/8/8 - * @description OBU 管理 - */ -class MogoPrivateObuManager private constructor() { - companion object { - val INSTANCE: MogoPrivateObuManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { - MogoPrivateObuManager() - } - } - - private var mContext: Context? = null - private var mObuStatusInfo = CallerObuListenerManager.getObuStatusInfo() - - fun init(context: Context, ipAddress: String) { - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "obuManager初始化--") - mContext = context - //连接obu设备 - connectObu(context, ipAddress) - //控制日志输出 - MogoObuManager.getInstance() - .init(MoGoAiCloudClientConfig.getInstance().getSn(), AppConfigInfo.toString()) - MogoObuManager.getInstance().registerListener(mogoObuListener) - } - - fun connectObu(context: Context, ipAddress: String) { - //自研obu初始化 - mObuStatusInfo.connectIP = ipAddress - mObuStatusInfo.obuSdkVersion = MogoObuManager.getInstance().versionName - if (!MogoObuManager.getInstance().isConnected) { - MogoObuManager.getInstance().connect(context, mObuStatusInfo.connectIP) - } else { - try { - MogoObuManager.getInstance().disConnect() - Thread.sleep(500) - } catch (e: Exception) { - e.printStackTrace() - } - MogoObuManager.getInstance().connect(context, mObuStatusInfo.connectIP) - } - } - - fun disConnectObu() { - try { - MogoObuManager.getInstance().disConnect() - } catch (e: Exception) { - e.printStackTrace() - } - - } - - fun isConnected(): Boolean { - return MogoObuManager.getInstance().isConnected - } - - private val mogoObuListener: OnMogoObuListener = object : OnMogoObuListener() { - // OBU连接成功 - override fun onConnected() { - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "onConnected ------> ") - mObuStatusInfo.obuStatus = true - CallerObuListenerManager.invokeListener(mObuStatusInfo) - mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU", true) } - - //断开mogo obu - com.mogo.support.obu.MogoObuManager.getInstance().disconnect() - } - - // OBU连接失败 - override fun onConnectFail(isNeedReconnect: Boolean) { - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "onConnectFail ------> ") - mObuStatusInfo.obuStatus = false - mObuStatusInfo.obuHvStatus = false - mObuStatusInfo.obuRvStatus = false - CallerObuListenerManager.invokeListener(mObuStatusInfo) - mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU", false) } - mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU_HV", false) } - mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU_RV", false) } - } - - // OBU断开连接 - override fun onDisconnect() { - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "onDisconnect ------> ") - mObuStatusInfo.obuStatus = false - mObuStatusInfo.obuHvStatus = false - mObuStatusInfo.obuRvStatus = false - CallerObuListenerManager.invokeListener(mObuStatusInfo) - mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU", false) } - mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU_HV", false) } - mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU_RV", false) } - } - - // 接收到的原始数据 - override fun onReceiveOriginData(data: String) { - super.onReceiveOriginData(data) - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "onReceiveOriginData ------> data = $data" - ) - - } - - // 发送的数据 - override fun onSendData(bytes: ByteArray) { - super.onSendData(bytes) - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "onSendData ------> ") - } - - // CV2X系统信息 - override fun onCvxAppInitIndInfo(info: CvxAppInitIndInfo) { - super.onCvxAppInitIndInfo(info) - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "onCvxAppInitIndInfo ------> $info" - ) - if (info != null) { - if (!info.stack_info.isNullOrEmpty()) { - mObuStatusInfo.stackInfo = info.stack_info - } - - if (!info.app_info.isNullOrEmpty()) { - mObuStatusInfo.appInfo = info.app_info - } - - if (!info.hli_info.isNullOrEmpty()) { - mObuStatusInfo.hliInfo = info.hli_info - } - CallerObuListenerManager.invokeListener(mObuStatusInfo) - } - } - - // (2) 车辆信息:CVX_HV_INFO_IND - override fun onCvxHvInfoIndInfo(info: CvxHvInfoIndInfo?) { - mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU_HV", true) } - mObuStatusInfo.obuHvStatus = true - CallerObuListenerManager.invokeListener(mObuStatusInfo) - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "onCvxHvInfoIndInfo ------> $info") - if (info != null && info.basic_info != null && info.basic_info.position != null) { - val movingObjectInfo = info.basic_info - val position = movingObjectInfo.position - val data = JSONObject() - try { - data.putOpt("lon", position.longitude) - data.putOpt("lat", position.latitude) - data.putOpt("speed", movingObjectInfo.speed) - data.putOpt("heading", movingObjectInfo.heading) - if (info.acceleration_set != null) { - data.putOpt("acceleration", info.acceleration_set.lateral) - data.putOpt("yawRate", info.acceleration_set.yaw_rate) - } - try { - data.putOpt("systemTime", System.currentTimeMillis()) - } catch (e: Exception) { - e.printStackTrace() - } - try { - data.putOpt("satelliteTime", System.currentTimeMillis()) - } catch (e: Exception) { - e.printStackTrace() - } - - // 使用与渠道配置一样的gps提供者提供的数据,app/productFlavors/fPadLenovo.gradle GPS_PROVIDER 0-Android系统,1-工控机,2-OBU - if (2 == FunctionBuildConfig.gpsProvider) { - // 同步给MAP地图 - CallerMapUIServiceManager.getMapUIController()?.syncLocation2Map(data) - // 同步更新经纬度和系统时间至 AutoPilotStatusListener - CallerAutoPilotStatusListenerManager.updateAutoPilotLatLon( - System.currentTimeMillis() / 1000.0, - position.longitude, - position.latitude - ) - } - - } catch (e: Exception) { - e.printStackTrace() - } - } - } - - // (3) 远车信息:CVX_RV_INFO_IND - override fun onCvxRvInfoIndInfo(info: CvxRvInfoIndInfo) { - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "onCvxRvInfoIndInfo ------> $info") - mObuStatusInfo.obuRvStatus = true - CallerObuListenerManager.invokeListener(mObuStatusInfo) - mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU_RV", true) } - // 更新数据 - TrafficDataConvertUtils.cvxRvInfoIndInfo2TrafficData(info)?.let { - CallerMapUIServiceManager.getMarkerService()?.updateITrafficLocationInfo(it) - } - } - - // (3) 道路事件预警信息:CVX_RTI_THREAT_IND - override fun onCvxRtiThreatIndInfo(info: CvxRtiThreatIndInfo?) { -// if (HmiBuildConfig.isShowObuV2iView) { - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "onCvxRtiThreatIndInfo ------> $info" - ) - - if (info != null && info.threat_info != null && info.ext_info != null) { - var alertContent = "" - var ttsContent = "" - var appId = info.threat_info.app_id.toString() - val status = info.status - val level = info.threat_info.threat_level - val direction = - getMessageDirection(if (info.ext_info != null) info.ext_info.pos_classification else -1) - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "onCvxRtiThreatIndInfo direction = $direction -- pos_classification = ${info.ext_info.pos_classification}" - ) - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "onCvxRtiThreatIndInfo appId = $appId --status = $status --level = $level -- handleDirection = $direction --rtiType = ${info.ext_info.rti_type} --direction = $direction -- pos_classification = ${info.ext_info.pos_classification} " - ) - when (appId) { - // 道路危险情况预警 - EventTypeEnum.TYPE_USECASE_ID_HLW.poiType, - EventTypeEnum.TYPE_USECASE_ID_IVS.poiType - -> { - when (info.ext_info.rti_type) { - //急转弯 - 0x2 -> { - // 特殊处理左、右方向的 - when (direction) { - WarningDirectionEnum.ALERT_WARNING_LEFT, - WarningDirectionEnum.ALERT_WARNING_TOP_LEFT, - WarningDirectionEnum.ALERT_WARNING_BOTTOM_LEFT -> { - appId = - EventTypeEnum.TYPE_USECASE_ID_ROAD_TURN_LEFT_SHARP.poiType - } - WarningDirectionEnum.ALERT_WARNING_RIGHT, - WarningDirectionEnum.ALERT_WARNING_TOP_RIGHT, - WarningDirectionEnum.ALERT_WARNING_BOTTOM_RIGHT -> { - appId = - EventTypeEnum.TYPE_USECASE_ID_ROAD_TURN_RIGHT_SHARP.poiType - } - } - } - //施工 - 0x7 -> { - appId = EventTypeEnum.FOURS_ROAD_WORK.poiType - } - //限速 - 0xA -> { - appId = EventTypeEnum.TYPE_USECASE_ID_SLW.poiType - } - //事故 - 0xC -> { - appId = - EventTypeEnum.TYPE_USECASE_ID_ROAD_COLLISION_WARNING.poiType - } - //拥堵 - 0xD -> { - appId = EventTypeEnum.TYPE_USECASE_ID_TJW.poiType - } - //行人 - 0xF -> { - appId = - EventTypeEnum.TYPE_USECASE_ID_ROAD_PEDESTRIAN_CROSSING.poiType - } - //禁止停车 - 0x13 -> { - appId = EventTypeEnum.TYPE_USECASE_ID_ROAD_NO_PARKING.poiType - } - //学校 - 0x14 -> { - appId = - EventTypeEnum.TYPE_USECASE_ID_ROAD_PEDESTRIAN_SCHOOL.poiType - } - //桥梁 - 0x17 -> { - appId = EventTypeEnum.TYPE_USECASE_ID_ROAD_HUMP_BRIDGE.poiType - } - //轻轨电车 - 0x18 -> { - appId = EventTypeEnum.TYPE_USECASE_ID_ROAD_TRAMCAR.poiType - } - //人行横道 - 0x19 -> { - appId = - EventTypeEnum.TYPE_USECASE_ID_ROAD_PEDESTRIAN_CROSSING.poiType - } - //减速慢行 - 0x1A -> { - appId = EventTypeEnum.TYPE_USECASE_ID_ROAD_GIVE_WAY.poiType - } - //事故易发路段 - 0x1B -> { - appId = EventTypeEnum.TYPE_USECASE_ID_ROAD_COLLISION_WARNING.poiType - } - //环岛行驶 - 0x1C -> { - appId = EventTypeEnum.TYPE_USECASE_ID_ROAD_ROUNDABOUTPNG.poiType - } - //环岛行驶 - 0x1D -> { - appId = EventTypeEnum.TYPE_USECASE_ID_ROAD_TEST_SECTION.poiType - } - //驼峰桥 - 0x1E -> { - appId = EventTypeEnum.TYPE_USECASE_ID_ROAD_HUMP_BRIDGE.poiType - } - } - alertContent = EventTypeEnum.getWarningContent(appId) - ttsContent = EventTypeEnum.getWarningTts(appId) - } - // 前方拥堵提醒 - EventTypeEnum.TYPE_USECASE_ID_TJW.poiType -> { - ttsContent = EventTypeEnum.getWarningTts(appId) - if (info.threat_info != null) { - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "ttsContent = $ttsContent --alertContent = $alertContent ---info.threat_info.distance = ${info.threat_info.distance} " - ) - if (info.threat_info.distance.toInt() != 0) { - alertContent = String.format( - EventTypeEnum.getWarningContent(appId), - info.threat_info.distance.toInt() - ) - } else { - alertContent = "前方拥堵,减速慢行" - } - } - - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "ttsContent = $ttsContent --alertContent = $alertContent" - ) - } - } - - when (status) { - // 添加 - ObuConstants.STATUS.ADD -> { - //不显示弹框,其它保留 - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "old onCvxRtiThreatIndInfo ------> appId = $appId --- alertContent = $alertContent --- ttsContent = $ttsContent ") - if (alertContent.isNullOrEmpty() || ttsContent.isNullOrEmpty()) { - Log.d("MsgBox-PriObuManager4", "alertContent或ttsContent为空!") - } - CallerMsgBoxManager.saveMsgBox( - MsgBoxBean( - MsgBoxType.OBU, - V2XMsg(appId, - alertContent, - ttsContent) - ) - ) - CallerHmiManager.warningV2X( - appId, - alertContent, - ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 - (appId + direction.direction).toString(),//使用当前事件类型+方向记录tag,当发生变化的时候关闭当前弹出新的 - object : IMoGoWarningStatusListener { - override fun onDismiss() { - // 关闭警告红边 - CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) - } - }, - true, - 5000L - ) - } - - ObuConstants.STATUS.UPDATE -> { - //显示警告红边 TODO 需要确定是什么值 -// CallerHmiManager.showWarning(direction) - - // 更新数据 - TrafficDataConvertUtils.cvxRtiThreatIndInfo2TrafficData(info)?.let { - CallerObuListenerManager.invokeTrackerWarningInfo(it) - CallerMapUIServiceManager.getMarkerService() - ?.updateITrafficThreatLevelInfo(it) - } - } - - // 删除 - ObuConstants.STATUS.DELETE -> { - // 关闭警告红边 - CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) - // 移除顶部弹窗 -// CallerHmiManager.disableWarningV2X((appId + direction.direction).toString()) - // 更新数据 - TrafficDataConvertUtils.cvxRtiThreatIndInfo2TrafficData(info)?.let { - CallerObuListenerManager.removeTrackerWarningInfo(it) - // 事件结束,还原车辆颜色 - it.threatLevel = 0x01 - CallerMapUIServiceManager.getMarkerService() - ?.updateITrafficThreatLevelInfo(it) - } - } - } - } -// } - } - - // (4) V2I预警信息:CVX_IVP_THREAT_IND,红绿灯 - override fun onCvxIvpThreatIndInfo(info: CvxIvpThreatIndInfo?) { - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "CvxIvpThreatIndInfo ------> $info" - ) - if (info != null && info.ext_info != null - && info.threat_info != null - && info.ext_info.lights != null - && info.ext_info.lights.isNotEmpty() - ) { -// if (HmiBuildConfig.isShowObuV2iView) { - handlerTrafficLight( - info.threat_info.app_id, - info.status, - info.ext_info.lights, - info.ext_info.index - ) -// } - } - } - - // (2) 弱势交通参与者预警信息:CVX_PTC_THREAT_IND - override fun onCvxPtcThreatIndInfo(info: CvxPtcThreatIndInfo?) { -// if (HmiBuildConfig.isShowObuV2iView) { - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "onCvxPtcInfoIndInfo ------> $info" - ) - // 交通参与者类型 0x0:未知 UNKNOWN | 0x1:非机动车 NON_MOTOR | 0x2:行人 PEDESTRIAN 0x3:RSU - if (info != null && (info.ptc_type == 1 || info.ptc_type == 2)) { - //v2i数据传输延迟 -// val hvMillTime = info.threat_info.hv_time.millisecond -// val hvSecondMillTime = (info.threat_info.hv_time.second) * 1000 -// val hvTime = hvMillTime + hvSecondMillTime -// val currentTime = TimeUtils.getNowMills() % 60000 -// val delayTime = currentTime - hvTime - -// CallerObuListenerManager.invokeDelayTime(delayTime) -// CallerLogger.d( -// "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", -// "onCvxPtcInfoIndInfo ---delayTime---> $delayTime" -// ) - - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "onCvxPtcInfoIndInfo ---status---> ${info.status}" - ) - var v2xType = "" - if (info.ptc_type == 1) { //摩托车 - v2xType = EventTypeEnum.TYPE_USECASE_ID_VRUCW_MOTORBIKE.poiType - } else if (info.ptc_type == 2) { //行人 - v2xType = EventTypeEnum.TYPE_USECASE_ID_VRUCW_PERSON.poiType - } - val ttsContent = EventTypeEnum.getWarningTts(v2xType) - val alertContent = EventTypeEnum.getWarningContent(v2xType) - val direction = - getMessageDirection(if (info.ext_info != null) info.ext_info.target_classification else -1) - val level = if (info.threat_info != null) info.threat_info.threat_level else -1 - - when (info.status) { - // 添加 - ObuConstants.STATUS.ADD -> { - // if (level == 2 || level == 3) { //不考虑level - //显示警告红边 - CallerHmiManager.showWarning(direction) - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "old onCvxPtcThreatIndInfo ------> v2xType = $v2xType --- alertContent = $alertContent --- ttsContent = $ttsContent ") - if (alertContent.isNullOrEmpty() || ttsContent.isNullOrEmpty()) { - Log.d("MsgBox-PriObuManager5", "alertContent或ttsContent为空!") - } - CallerMsgBoxManager.saveMsgBox( - MsgBoxBean( - MsgBoxType.OBU, - V2XMsg(v2xType, - alertContent, - ttsContent) - ) - ) - CallerHmiManager.warningV2X( - v2xType, - alertContent, - ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 - (v2xType + direction.direction).toString(),//使用当前事件类型+方向记录tag,当发生变化的时候关闭当前弹出新的 - object : IMoGoWarningStatusListener { - override fun onDismiss() { - // 关闭警告红边 - CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) - } - }, - true, - 5000L - ) -// } - - // 更新数据 - TrafficDataConvertUtils.cvxPtcThreatIndInfo2TrafficData(info)?.let { - CallerObuListenerManager.invokeTrackerWarningInfo(it) - CallerMapUIServiceManager.getMarkerService() - ?.updateITrafficThreatLevelInfo(it) - } - } - - ObuConstants.STATUS.UPDATE -> { - } - - // 删除 - ObuConstants.STATUS.DELETE -> { - // 关闭警告红边 - CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) - // 更新数据 - TrafficDataConvertUtils.cvxPtcThreatIndInfo2TrafficData(info)?.let { - CallerObuListenerManager.removeTrackerWarningInfo(it) - // 事件结束,还原交通参与者颜色 - it.threatLevel = 0x01 - CallerMapUIServiceManager.getMarkerService() - ?.updateITrafficThreatLevelInfo(it) - } -// CallerHmiManager.disableWarningV2X(ObuConstants.USE_CASE_ID.VRUCW.toString()) - } - } - - } -// } - } - - // (5) 限速预警信息:CVX_SLW_THREAT_IND - override fun onCvxSlwThreatIndInfo(info: CvxSlwThreatIndInfo?) { - //todo 限速走高精地图 屏蔽OBU限速\ -// CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "onCvxSlwThreatIndInfo ------> $info") -// if (info != null) { -// when (info.status) { -// // 添加 -// ObuConstants.STATUS.ADD, -// ObuConstants.STATUS.UPDATE -// -> { -// if (info.ext_info != null) { -// // 计算为千米每小时 TODO 这里需要做一下向上取整数,40,60,80,120等 -// CallerLogger.d( -// "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", -// "info.ext_info.speed_limit_max ------> ${info.ext_info.speed_limit_max}" -// ) -// CallerHmiManager.showLimitingVelocity((Math.round(((info.ext_info.speed_limit_max * 60 * 60) / 1000) / 10) * 10).toInt()) -// } -// } -// // 删除 -// ObuConstants.STATUS.DELETE -> { -// CallerHmiManager.disableLimitingVelocity() -// } -// } -// } - } - - - // (1) V2V预警信息:CVX_V2V_THREAT_IND - override fun onCvxV2vThreatIndInfo(info: CvxV2vThreatIndInfo?) { -// if (HmiBuildConfig.isShowObuV2vView) { - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "onCvxV2vThreatIndInfo ------> $info" - ) - info?.let { - //预警信息,预警类型 threat_level 2、3 - info.threat_info?.let { - //预警方位 - val direction = - getMessageDirection(if (info.ext_info != null) info.ext_info.target_classification else -1) - //处理预警类型 - val appId = info.threat_info.app_id - val level = info.threat_info.threat_level - val status = info.status - if (info.ext_info != null) { - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "onCvxV2vThreatIndInfo target_classification = ${ - getMessageDirection(info.ext_info.target_classification) - } --- direction = $direction --- appId = $appId ---level = $level -- status = $status" - ) - } - - handleSdkObu(appId, direction, status, level, info) - } - } - } -// } - } - - /** - * 返回OBU监听 - */ - fun getMogoObuListener(): OnMogoObuListener { - return mogoObuListener - } - - /** - * 获取消息的方位 车辆相关 - */ - private fun getMessageDirection(targetClassification: Int): WarningDirectionEnum { - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "预警红边:预警方向->$targetClassification") - return when (targetClassification) { - ObuConstants.TARGET_CLASSIFICATION.TC_ONCOMING_IN_LANE, - ObuConstants.TARGET_CLASSIFICATION.TC_AHEAD_IN_LANE, - 0x04 -> WarningDirectionEnum.ALERT_WARNING_TOP //正前方 - - 0x03 -> WarningDirectionEnum.ALERT_WARNING_RIGHT //正右方 - - ObuConstants.TARGET_CLASSIFICATION.TC_BEHIND_IN_LANE, - 0x05 -> WarningDirectionEnum.ALERT_WARNING_BOTTOM //正后方 - - 0x02 -> WarningDirectionEnum.ALERT_WARNING_LEFT //正左方 - - ObuConstants.TARGET_CLASSIFICATION.TC_AHEAD_LEFT, - ObuConstants.TARGET_CLASSIFICATION.TC_AHEAD_FAR_LEFT, - ObuConstants.TARGET_CLASSIFICATION.TC_ONCOMING_LEFT, - ObuConstants.TARGET_CLASSIFICATION.TC_ONCOMING_FAR_LEFT, - ObuConstants.TARGET_CLASSIFICATION.TC_INTERSECTION_LEFT -> WarningDirectionEnum.ALERT_WARNING_TOP_LEFT //左前方 - - ObuConstants.TARGET_CLASSIFICATION.TC_ONCOMING_FAR_RIGHT, - ObuConstants.TARGET_CLASSIFICATION.TC_AHEAD_FAR_RIGHT, - ObuConstants.TARGET_CLASSIFICATION.TC_AHEAD_RIGHT, - ObuConstants.TARGET_CLASSIFICATION.TC_INTERSECTION_RIGHT, - ObuConstants.TARGET_CLASSIFICATION.TC_ONCOMING_RIGHT -> WarningDirectionEnum.ALERT_WARNING_TOP_RIGHT //右前方 - - ObuConstants.TARGET_CLASSIFICATION.TC_BEHIND_LEFT, - ObuConstants.TARGET_CLASSIFICATION.TC_BEHIND_FAR_LEFT -> WarningDirectionEnum.ALERT_WARNING_BOTTOM_LEFT //左后方 - - ObuConstants.TARGET_CLASSIFICATION.TC_BEHIND_RIGHT, - ObuConstants.TARGET_CLASSIFICATION.TC_BEHIND_FAR_RIGHT -> WarningDirectionEnum.ALERT_WARNING_BOTTOM_RIGHT //右后方 - - ObuConstants.TARGET_CLASSIFICATION.TC_UNCLASSIFIED -> WarningDirectionEnum.ALERT_WARNING_NON //未知 - else -> WarningDirectionEnum.ALERT_WARNING_ALL - } - } - - fun release() { - MogoObuManager.getInstance().unregisterListener() - } - - /** - * 处理红绿灯 - */ - private fun handlerTrafficLight(appId: Int, status: Int, lights: List, index: Int) { - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "handlerTrafficLight appId = $appId --- status = $status ---index = $index ---lights.size = ${lights.size} ---lights = $lights " - ) - when (status) { - // 添加 - ObuConstants.STATUS.ADD, - ObuConstants.STATUS.UPDATE - -> { - changeTrafficLightStatus(appId, lights, index) - } - // 删除 - ObuConstants.STATUS.DELETE -> { - // 移除顶部弹窗 - CallerHmiManager.disableWarningTrafficLight() -// CallerHmiManager.disableWarningV2X(appId.toString()) - } - } - } - - private var isRedLight = false - private var isGreenLight = false - - /** - * 修改红绿灯 - */ - @Synchronized - private fun changeTrafficLightStatus( - appId: Int, - lights: List, - index: Int - ) { - var ttsContent = "" - var alertContent = "" - //这里需要根据真实数据确定 index 取值方式 - if (index != -1 && lights.size >= index) { - val currentLight = lights[index] - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "currentLight = $currentLight ---currentLight.phase = ${currentLight.phase} ---rlvw_violation_type = ${currentLight.rlvw_violation_type} --- index = $index ---appId = $appId ---appId = $appId" - ) - // 闯红灯预警 - when (currentLight.rlvw_violation_type) { - 0x0 -> {//不可用 V2I_RLVW_VIOLATION_TYPE_UNAVAILABLE - } - 0x1 -> {//无违规 V2I_RLVW_VIOLATION_TYPE_NO_VIOLATION -// CallerHmiManager.disableWarningV2X(appId.toString()) - } - 0x2 -> {//闯红灯 V2I_RLVW_VIOLATION_TYPE_RUNNING_RED_LIGHT - ttsContent = EventTypeEnum.getWarningTts(appId.toString()) - alertContent = EventTypeEnum.getWarningContent(appId.toString()) - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "old changeTrafficLightStatus ------> appId.toString() = ${appId.toString()} --- alertContent = $alertContent --- ttsContent = $ttsContent ") - if (alertContent.isNullOrEmpty() || ttsContent.isNullOrEmpty()) { - Log.d("MsgBox-PriObuManager1", "alertContent或ttsContent为空!") - } - CallerMsgBoxManager.saveMsgBox( - MsgBoxBean( - MsgBoxType.OBU, - V2XMsg(appId.toString(), alertContent, ttsContent) - ) - ) - CallerHmiManager.warningV2X( - appId.toString(), alertContent, ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 - appId.toString(), null, true, 5000L - ) - } - 0x3 -> {//闯黄灯 V2I_RLVW_VIOLATION_TYPE_RUNNING_YELLOW_LIGHT - } - } - - when (currentLight.phase) { - // 灯光不可用 - 0x0 -> { - CallerHmiManager.showWarningTrafficLight(0, 3) - } - // 红灯 - 0x1 -> { - if (!isRedLight) { -// CallerHmiManager.disableWarningV2X(appId.toString()) - isRedLight = true - } - isGreenLight = false - CallerHmiManager.showWarningTrafficLight(1, 3) - - val red = currentLight.count_down.toInt() - CallerHmiManager.changeCountdownRed(red) - CallerHmiManager.changeCountdownGreen(0) - CallerHmiManager.changeCountdownYellow(0) - - } - // 绿灯 - 0x2 -> { - if (!isGreenLight) { -// CallerHmiManager.disableWarningV2X(appId.toString()) - isGreenLight = true - } - isRedLight = false - CallerHmiManager.showWarningTrafficLight(3, 3) - val green = currentLight.count_down.toInt() - CallerHmiManager.changeCountdownGreen(green) - //防止数据出现问题的容错 - CallerHmiManager.changeCountdownRed(0) - CallerHmiManager.changeCountdownYellow(0) - // 拼接建议速度 - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "speed_min = ${currentLight.glosa_suggested_speed_min} --speed_max = ${currentLight.glosa_suggested_speed_max.toInt()}" - ) - val adviceSpeed = - "${currentLight.glosa_suggested_speed_min.toInt()} - ${currentLight.glosa_suggested_speed_max.toInt()}" - - val adviceSpeedTts = - "${currentLight.glosa_suggested_speed_min.toInt()}到${currentLight.glosa_suggested_speed_max.toInt()}" - - ttsContent = - String.format( - EventTypeEnum.getWarningTts(EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType), - adviceSpeedTts - ) - - alertContent = - String.format( - EventTypeEnum.getWarningContent(EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType), - adviceSpeed - ) - - val maxSpeed = currentLight.glosa_suggested_speed_max.toInt() - if (maxSpeed > 0) { - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", "old changeTrafficLightStatus ------> TYPE_USECASE_ID_IVP_GREEN --- alertContent = $alertContent --- ttsContent = $ttsContent ") - if (alertContent.isNullOrEmpty() || ttsContent.isNullOrEmpty()) { - Log.d("MsgBox-PriObuManager2", "alertContent或ttsContent为空!") - } - CallerMsgBoxManager.saveMsgBox( - MsgBoxBean( - MsgBoxType.OBU, - V2XMsg(EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType, - alertContent, - ttsContent) - ) - ) - CallerHmiManager.warningV2X( - EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType, - alertContent, - ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 - appId.toString(), - null, - true, - 5000L - ) - } - } - // 黄灯 - 0x3 -> { -// CallerHmiManager.disableWarningV2X(appId.toString()) - CallerHmiManager.showWarningTrafficLight(2, 2) - val yellow = currentLight.count_down.toInt() - CallerHmiManager.changeCountdownYellow(yellow) - CallerHmiManager.changeCountdownGreen(0) - CallerHmiManager.changeCountdownRed(0) - } - } - } - - } - - - //todo 二期优化此处内容,注解参数 - /** - * 构造对应展示数据和场景 根据obu的场景,add change delete确定是否展示 - * - * @param appId 使用WarningTypeEnum获取icon、提示内容、tts内容 - * - */ - private fun handleSdkObu( - appId: Int, - direction: WarningDirectionEnum, - status: Int, - level: Int, - info: CvxV2vThreatIndInfo - ) { - // 这里排除需要特殊定制的语音及文案外,其余的都可以使用 EventTypeEnum 提供的 - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "handleSdkObu appId = $appId --- handleDirection = $direction ---level = $level ---status = $status" - ) - var alertContent: String? = null - var ttsContent: String? = null - var changeVisualAngle = false - when (appId.toString()) { - // 变道预警,注意左后车辆/注意右后车辆 - EventTypeEnum.TYPE_USECASE_ID_LCW.poiType -> { - EventTypeHelper.getLCW(appId, direction) { alert, tts -> - alertContent = alert - ttsContent = tts - } - } - //车辆失控预警 - EventTypeEnum.TYPE_USECASE_ID_CLW.poiType -> { - EventTypeHelper.getCLW(appId, direction) { alert, tts -> - alertContent = alert - ttsContent = tts - } - } - //左转辅助 - EventTypeEnum.TYPE_USECASE_ID_LTA.poiType -> { - EventTypeHelper.getLTA(appId) { alert, tts -> - alertContent = alert - ttsContent = tts - } - } - //异常车辆提醒 - EventTypeEnum.TYPE_USECASE_ID_AVW.poiType -> { - EventTypeHelper.getAVW(appId, direction) { alert, tts -> - alertContent = alert - ttsContent = tts - } - } - //盲区预警 - EventTypeEnum.TYPE_USECASE_ID_BSW.poiType -> { - EventTypeHelper.getBSW(appId, direction) { alert, tts, visualAngle -> - alertContent = alert - ttsContent = tts - changeVisualAngle = visualAngle - } - } - //前车急刹预警 - EventTypeEnum.TYPE_USECASE_ID_EBW.poiType -> { - EventTypeHelper.getEBW(appId) { alert, tts -> - alertContent = alert - ttsContent = tts - } - } - //前向碰撞预警 - EventTypeEnum.TYPE_USECASE_ID_FCW.poiType -> { - EventTypeHelper.getFCW(appId) { alert, tts -> - alertContent = alert - ttsContent = tts - } - } - //逆向超车预警 - EventTypeEnum.TYPE_USECASE_ID_DNPW.poiType -> { - EventTypeHelper.getDNPW(appId) { alert, tts -> - alertContent = alert - ttsContent = tts - } - } - - // 这里处理固定的提示信息,包括了<紧急车辆提醒> - else -> { - ttsContent = EventTypeEnum.getWarningTts(appId.toString()) - alertContent = EventTypeEnum.getWarningContent(appId.toString()) - } - } - - when (status) { - // 添加,更新 add的时候,可能级别是2, - ObuConstants.STATUS.ADD, - ObuConstants.STATUS.UPDATE -> { - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "appId2 = $appId --- level = $level ---ttsContent = $ttsContent --- alertContent = $alertContent --- direction = $direction" - ) - if (level == 2 || level == 3) { - //不显示顶部弹框,其它保留 - CallerLogger.d("$M_OBU${MogoObuConst.TAG_MOGO_OBU}", - "old handleSdkObu appId2 = $appId --- level = $level ---ttsContent = $ttsContent --- alertContent = $alertContent --- direction = $direction" - ) - if (alertContent.isNullOrEmpty() || ttsContent.isNullOrEmpty()) { - Log.d("MsgBox-PriObuManager3", "alertContent或ttsContent为空!") - } - CallerMsgBoxManager.saveMsgBox( - MsgBoxBean( - MsgBoxType.OBU, - V2XMsg(appId.toString(), - alertContent, - ttsContent) - ) - ) - CallerHmiManager.warningV2X( - appId.toString(), - alertContent, - ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 - (appId + direction.direction).toString(),//使用当前事件类型+方向记录tag,当发生变化的时候关闭当前弹出新的 - object : IMoGoWarningStatusListener { - - override fun onShow() { - super.onShow() - if (changeVisualAngle) { - CallerVisualAngleManager.changeVisualAngle(TooClose) - } - } - - override fun onDismiss() { - // 关闭警告红边 - CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) - if (changeVisualAngle) { - CallerVisualAngleManager.changeVisualAngle(Default()) - } - } - }, - true, - 5000L - ) - //显示警告红边 - CallerHmiManager.showWarning(direction) - } - //更新周边车辆进行预警颜色变换,车辆实时移动和变色 - TrafficDataConvertUtils.cvxV2vThreatIndInfo2TrafficData(info)?.let { - CallerObuListenerManager.invokeTrackerWarningInfo(it) - CallerMapUIServiceManager.getMarkerService()?.updateITrafficThreatLevelInfo(it) - } - } - // 删除 - ObuConstants.STATUS.DELETE -> { - // 关闭警告红边 - CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) - // 移除顶部弹窗 -// CallerHmiManager.disableWarningV2X((appId + direction.direction).toString()) - //更新周边车辆进行预警颜色变换,车辆实时移动和变色 - TrafficDataConvertUtils.cvxV2vThreatIndInfo2TrafficData(info)?.let { - CallerObuListenerManager.removeTrackerWarningInfo(it) - it.threatLevel = 0x01 - CallerMapUIServiceManager.getMarkerService()?.updateITrafficThreatLevelInfo(it) - } - } - } - } - - -} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt index 93706d2adc..b6fcf64afc 100644 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt +++ b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/MogoPrivateObuNewManager.kt @@ -88,6 +88,11 @@ class MogoPrivateObuNewManager private constructor() { return mogoObuListener } + fun disconnect() { + MogoObuManager.getInstance().disconnect() + } + + private val mogoObuListener: OnMogoObuListener = object : OnMogoObuListener() { /** * 连接状态的改变 @@ -105,13 +110,6 @@ class MogoPrivateObuNewManager private constructor() { mObuStatusInfo.obuStatus = true CallerObuListenerManager.invokeListener(mObuStatusInfo) mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU", true) } - - //断开老obu - try { - com.zhidao.support.obu.MogoObuManager.getInstance().disConnect() - } catch (e: Exception) { - e.printStackTrace() - } } } diff --git a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/utils/TrafficDataConvertUtils.kt b/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/utils/TrafficDataConvertUtils.kt deleted file mode 100644 index 8e94bc8bc6..0000000000 --- a/core/function-impl/mogo-core-function-obu-mogo/src/main/java/com/mogo/eagle/core/function/obu/mogo/utils/TrafficDataConvertUtils.kt +++ /dev/null @@ -1,133 +0,0 @@ -package com.mogo.eagle.core.function.obu.mogo.utils - -import com.mogo.eagle.core.data.traffic.TrafficData -import com.mogo.eagle.core.data.enums.TrafficTypeEnum -import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger -import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU -import com.zhidao.support.obu.constants.ObuConstants -import com.zhidao.support.obu.model.CvxPtcThreatIndInfo -import com.zhidao.support.obu.model.CvxRtiThreatIndInfo -import com.zhidao.support.obu.model.CvxRvInfoIndInfo -import com.zhidao.support.obu.model.CvxV2vThreatIndInfo - -/** - * @author xiaoyuzhou - * @date 2021/8/18 2:30 下午 - */ -object TrafficDataConvertUtils { - val TAG = "TrafficDataConvertUtils" - - /** - * OBU 远车 转换交通元素数据 - */ - fun cvxRvInfoIndInfo2TrafficData(info: CvxRvInfoIndInfo): TrafficData? { - if (info.basic_info == null || info.basic_info.position == null) { - CallerLogger.e("$M_OBU$TAG", "cvxRvInfoIndInfo2TrafficData 数据转换异常,请检查参数是否齐全") - return null - } - val trafficData = TrafficData() - trafficData.type = TrafficTypeEnum.TYPE_TRAFFIC_ID_TA_CHE - trafficData.uuid = info.vehicle_id - trafficData.lat = info.basic_info.position.latitude - trafficData.lon = info.basic_info.position.longitude - trafficData.heading = info.basic_info.heading - trafficData.speed = info.basic_info.speed - - return trafficData - } - - /** - * OBU RSU道路事件预警信息 转换交通元素数据 - */ - fun cvxRtiThreatIndInfo2TrafficData(info: CvxRtiThreatIndInfo): TrafficData? { - // 这里只处理道路施工 - if(info.ext_info.rti_type != 0x7){ - return null - } - if (info.rti_id == null || info.ext_info == null - || info.zones_info == null || info.zones_info.first() == null - || info.zones_info.first().path_points.first() == null - || info.threat_info == null - ) { - CallerLogger.e("$M_OBU$TAG", "数据转换异常,请检查参数是否齐全") - return null - } - val trafficData = TrafficData() - trafficData.type = TrafficTypeEnum.TYPE_TRAFFIC_ID_DAO_LU_SHI_GONG - trafficData.uuid = info.rti_id - - trafficData.lat = info.zones_info.first().path_points.first().latitude - trafficData.lon = info.zones_info.first().path_points.first().longitude - - trafficData.threatLevel = info.threat_info.threat_level - - return trafficData - } - - /** - * OBU 预警事件 转换交通元素数据 - */ - fun cvxV2vThreatIndInfo2TrafficData(info: CvxV2vThreatIndInfo): TrafficData? { - if (info.basic_info == null || info.basic_info.position == null || info.threat_info == null) { - CallerLogger.e("$M_OBU$TAG", "数据转换异常,请检查参数是否齐全") - return null - } - val trafficData = TrafficData() - trafficData.uuid = info.vehicle_id - trafficData.lat = info.basic_info.position.latitude - trafficData.lon = info.basic_info.position.longitude - trafficData.heading = info.basic_info.heading - trafficData.speed = info.basic_info.speed - // 判断车辆V2X预警级别,调整车辆颜色 - trafficData.threatLevel = info.threat_info.threat_level - - if (info.threat_info.app_id == ObuConstants.USE_CASE_ID.EVW) { - trafficData.type = TrafficTypeEnum.TYPE_TRAFFIC_ID_SPECIAL_VEHICLE - } else { - trafficData.type = TrafficTypeEnum.TYPE_TRAFFIC_ID_TA_CHE - } - - return trafficData - } - - /** - * OBU 弱势交通参与者信息 转换交通元素数据 TODO - */ - fun cvxPtcThreatIndInfo2TrafficData(info: CvxPtcThreatIndInfo): TrafficData? { - if (info.ptc_pos == null || info.threat_info == null) { - CallerLogger.e("$M_OBU$TAG", "数据转换异常,请检查参数是否齐全") - return null - } - val trafficData = TrafficData() - - trafficData.uuid = info.ptc_id - trafficData.lat = info.ptc_pos.latitude - trafficData.lon = info.ptc_pos.longitude -// trafficData.heading = info.ptc_pos.heading -// trafficData.speed = info.ptc_pos.speed - - when (info.ptc_type) { - // 未知 - 0x0 -> { - trafficData.type = TrafficTypeEnum.TYPE_TRAFFIC_ID_WEI_ZHI - } - // 非机动车 - 0x1 -> { - trafficData.type = TrafficTypeEnum.TYPE_TRAFFIC_ID_MOTO - } - // 行人 - 0x2 -> { - trafficData.type = TrafficTypeEnum.TYPE_TRAFFIC_ID_PEOPLE - } - } - - // 判断车辆V2X预警级别,调整车辆颜色 - if (info.threat_info != null) { - trafficData.threatLevel = info.threat_info.threat_level - } - - return trafficData - } - - -} \ 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/events/alarm/V2XAlarmServer.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/alarm/V2XAlarmServer.java index 0c09db8c20..c4f2ca6de0 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/alarm/V2XAlarmServer.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/alarm/V2XAlarmServer.java @@ -1,15 +1,17 @@ package com.mogo.eagle.core.function.v2x.events.alarm; +import android.util.Log; + +import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import com.mogo.eagle.core.data.map.MogoLocation; import com.mogo.eagle.core.data.map.entity.MarkerLocation; import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity; -import com.mogo.eagle.core.data.enums.EventTypeEnum; import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils; import java.util.Iterator; import java.util.concurrent.CopyOnWriteArrayList; + import io.netty.util.internal.ConcurrentSet; -import android.util.Log; /** * @author donghongyu @@ -64,7 +66,7 @@ public class V2XAlarmServer { double distance = v2XRoadEventEntity.getDistance(); Log.d("RWJ", "distance:" + distance); if (distance <= 500) { - if (EventTypeEnum.GHOST_PROBE.getPoiType().equals(v2XRoadEventEntity.getPoiType())) { + if (EventTypeEnumNew.GHOST_PROBE.getPoiType().equals(v2XRoadEventEntity.getPoiType())) { if (distance > 25) { continue; } 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 13432dbf4f..ffa58677e6 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 @@ -10,6 +10,7 @@ import com.alibaba.android.arouter.facade.annotation.Route; import com.mogo.cloud.commons.utils.CoordinateUtils; import com.mogo.commons.AbsMogoApplication; import com.mogo.commons.module.status.MogoStatusManager; +import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import com.mogo.eagle.core.data.map.MogoLatLng; import com.mogo.eagle.core.data.map.MogoLocation; import com.mogo.eagle.core.data.map.entity.MarkerExploreWay; @@ -26,16 +27,15 @@ import com.mogo.eagle.core.function.v2x.events.manager.V2XStatusManager; import com.mogo.eagle.core.function.v2x.events.marker.V2XMarkerAdapter; import com.mogo.eagle.core.function.v2x.events.utils.EntityUtilsKt; import com.mogo.eagle.core.function.v2x.events.utils.MapUtils; +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 com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; 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.eagle.core.data.enums.EventTypeEnum; -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; @@ -110,7 +110,7 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager { List exploreWayList = markerCardResult.getExploreWay(); if (exploreWayList != null) { for (V2XMarkerExploreWay markerExploreWay : exploreWayList) { - if (EventTypeEnum.isRoadEvent(markerExploreWay.getPoiType())) { + if (EventTypeEnumNew.isRoadEvent(markerExploreWay.getPoiType())) { V2XMarkerLocation markerLocation = markerExploreWay.getLocation(); // 记录道路事件 V2XRoadEventEntity v2XRoadEventEntity = new V2XRoadEventEntity(); diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/V2XMarkerAdapter.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/V2XMarkerAdapter.java index f612b4e6b5..eb6107c2db 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/V2XMarkerAdapter.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/V2XMarkerAdapter.java @@ -3,9 +3,9 @@ package com.mogo.eagle.core.function.v2x.events.marker; import android.content.Context; import android.graphics.Bitmap; +import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity; import com.mogo.eagle.core.function.v2x.R; -import com.mogo.eagle.core.data.enums.EventTypeEnum; import com.mogo.eagle.core.function.v2x.events.view.V2XMarkerRoadEventView; import java.util.ArrayList; @@ -31,10 +31,10 @@ public class V2XMarkerAdapter { */ public static Bitmap getV2XRoadEventViewPng(Context context, V2XRoadEventEntity alarmInfo) { Bitmap bitmap; - if (EventTypeEnum.ALERT_TRAFFIC_LIGHT_SUGGEST.getPoiType().equals(alarmInfo.getPoiType()) - || EventTypeEnum.ALERT_TRAFFIC_LIGHT_WARNING.getPoiType().equals(alarmInfo.getPoiType()) - || EventTypeEnum.FOURS_BLOCK_UP.getPoiType().equals(alarmInfo.getPoiType()) - || EventTypeEnum.ALERT_CAR_TROUBLE_WARNING.getPoiType().equals(alarmInfo.getPoiType())) { + if (EventTypeEnumNew.ALERT_TRAFFIC_LIGHT_SUGGEST.getPoiType().equals(alarmInfo.getPoiType()) + || EventTypeEnumNew.ALERT_TRAFFIC_LIGHT_WARNING.getPoiType().equals(alarmInfo.getPoiType()) + || EventTypeEnumNew.FOURS_BLOCK_UP.getPoiType().equals(alarmInfo.getPoiType()) + || EventTypeEnumNew.ALERT_CAR_TROUBLE_WARNING.getPoiType().equals(alarmInfo.getPoiType())) { bitmap = getV2XRoadEventMarkerView( context, alarmInfo, @@ -53,10 +53,10 @@ public class V2XMarkerAdapter { */ public static ArrayList getV2XRoadEventViewGif(Context context, V2XRoadEventEntity alarmInfo) { ArrayList bitmapArrayList; - if (EventTypeEnum.ALERT_TRAFFIC_LIGHT_SUGGEST.getPoiType().equals(alarmInfo.getPoiType()) - || EventTypeEnum.ALERT_TRAFFIC_LIGHT_WARNING.getPoiType().equals(alarmInfo.getPoiType()) - || EventTypeEnum.FOURS_BLOCK_UP.getPoiType().equals(alarmInfo.getPoiType()) - || EventTypeEnum.ALERT_CAR_TROUBLE_WARNING.getPoiType().equals(alarmInfo.getPoiType())) { + if (EventTypeEnumNew.ALERT_TRAFFIC_LIGHT_SUGGEST.getPoiType().equals(alarmInfo.getPoiType()) + || EventTypeEnumNew.ALERT_TRAFFIC_LIGHT_WARNING.getPoiType().equals(alarmInfo.getPoiType()) + || EventTypeEnumNew.FOURS_BLOCK_UP.getPoiType().equals(alarmInfo.getPoiType()) + || EventTypeEnumNew.ALERT_CAR_TROUBLE_WARNING.getPoiType().equals(alarmInfo.getPoiType())) { bitmapArrayList = getV2XRoadEventOrangeMarkerView(context, alarmInfo); } else { bitmapArrayList = getV2XRoadEventRedMarkerView(context, alarmInfo); diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/view/V2XMarkerRoadEventView.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/view/V2XMarkerRoadEventView.kt index 1b3e41053c..c9d1589194 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/view/V2XMarkerRoadEventView.kt +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/view/V2XMarkerRoadEventView.kt @@ -5,10 +5,10 @@ import android.content.Context import android.graphics.Bitmap import android.view.LayoutInflater import androidx.constraintlayout.widget.ConstraintLayout +import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity import com.mogo.eagle.core.function.v2x.R import com.mogo.eagle.core.utilcode.util.ViewUtils -import com.mogo.eagle.core.data.enums.EventTypeEnum import kotlinx.android.synthetic.main.view_marker_event_car.view.* /** @@ -33,8 +33,8 @@ class V2XMarkerRoadEventView(context: Context, alarmInfo: V2XRoadEventEntity) : } fun initView(context: Context, alarmInfo: V2XRoadEventEntity) { - if (alarmInfo.poiType == EventTypeEnum.ALERT_FRONT_CAR.poiType || - alarmInfo.poiType == EventTypeEnum.ALERT_CAR_TROUBLE_WARNING.poiType + if (alarmInfo.poiType == EventTypeEnumNew.ALERT_FRONT_CAR.poiType || + alarmInfo.poiType == EventTypeEnumNew.ALERT_CAR_TROUBLE_WARNING.poiType ) { LayoutInflater.from(context) .inflate(R.layout.view_marker_event_car, this) @@ -46,11 +46,11 @@ class V2XMarkerRoadEventView(context: Context, alarmInfo: V2XRoadEventEntity) : } /** - * @see EventTypeEnum + * @see EventTypeEnumNew */ private fun updateIcon(alarmInfo: V2XRoadEventEntity) { // 道路施工、积水、路面结冰、浓雾、事故、拥堵 - val iconResId = EventTypeEnum.getUpdateIconRes(alarmInfo.poiType) + val iconResId = EventTypeEnumNew.getUpdateIconRes(alarmInfo.poiType) if (iconResId != 0) { ivCar.setImageResource(iconResId) } diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/CloudPoiManager.java b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/CloudPoiManager.java index 7bb1b06c72..1359dd3e6b 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/CloudPoiManager.java +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/CloudPoiManager.java @@ -6,7 +6,6 @@ import android.util.ArrayMap; import com.elegant.network.utils.GsonUtil; import com.mogo.eagle.core.data.R; -import com.mogo.eagle.core.data.enums.EventTypeEnum; import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import com.mogo.eagle.core.data.map.PoiWrapper; import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; @@ -39,37 +38,37 @@ public class CloudPoiManager { public void generateDefault() { if (poiWrapper.isEmpty()) { - poiWrapper.put(EventTypeEnum.TRAFFIC_CHECK.getPoiType(), new PoiWrapper(EventTypeEnum.TRAFFIC_CHECK.getPoiType(), + poiWrapper.put(EventTypeEnumNew.TRAFFIC_CHECK.getPoiType(), new PoiWrapper(EventTypeEnumNew.TRAFFIC_CHECK.getPoiType(), R.drawable.module_common_icon_map_marker_road_check2, R.drawable.module_common_icon_map_marker_road_check2_white, "交通检查")); - poiWrapper.put(EventTypeEnum.ROAD_CLOSED.getPoiType(), new PoiWrapper(EventTypeEnum.ROAD_CLOSED.getPoiType(), + poiWrapper.put(EventTypeEnumNew.ROAD_CLOSED.getPoiType(), new PoiWrapper(EventTypeEnumNew.ROAD_CLOSED.getPoiType(), R.drawable.module_common_icon_map_marker_road_block_off2, R.drawable.module_common_icon_map_marker_road_block_off2_white, "封路")); - poiWrapper.put(EventTypeEnum.FOURS_ROAD_WORK.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_ROAD_WORK.getPoiType(), + poiWrapper.put(EventTypeEnumNew.FOURS_ROAD_WORK.getPoiType(), new PoiWrapper(EventTypeEnumNew.FOURS_ROAD_WORK.getPoiType(), R.drawable.module_common_icon_map_marker_road_work2, R.drawable.module_common_icon_map_marker_road_work2_white, "施工")); poiWrapper.put(EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGONG.getPoiType(), new PoiWrapper(EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGONG.getPoiType(), R.drawable.module_common_icon_map_marker_road_work2, R.drawable.module_common_icon_map_marker_road_work2_white, "施工")); - poiWrapper.put(EventTypeEnum.FOURS_BLOCK_UP.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_BLOCK_UP.getPoiType(), + poiWrapper.put(EventTypeEnumNew.FOURS_BLOCK_UP.getPoiType(), new PoiWrapper(EventTypeEnumNew.FOURS_BLOCK_UP.getPoiType(), R.drawable.module_common_icon_map_marker_road_block_up2, R.drawable.module_common_icon_map_marker_road_block_up2_white, "拥堵")); - poiWrapper.put(EventTypeEnum.FOURS_PONDING.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_PONDING.getPoiType(), + poiWrapper.put(EventTypeEnumNew.FOURS_PONDING.getPoiType(), new PoiWrapper(EventTypeEnumNew.FOURS_PONDING.getPoiType(), R.drawable.module_common_icon_map_marker_pondingl2, R.drawable.module_common_icon_map_marker_pondingl2_white, "积水")); - poiWrapper.put(EventTypeEnum.FOURS_FOG.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_FOG.getPoiType(), + poiWrapper.put(EventTypeEnumNew.FOURS_FOG.getPoiType(), new PoiWrapper(EventTypeEnumNew.FOURS_FOG.getPoiType(), R.drawable.module_common_ic_rc_dark_frog2, R.drawable.module_common_ic_rc_dark_frog2_white, "浓雾")); - poiWrapper.put(EventTypeEnum.FOURS_ICE.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_ICE.getPoiType(), + poiWrapper.put(EventTypeEnumNew.FOURS_ICE.getPoiType(), new PoiWrapper(EventTypeEnumNew.FOURS_ICE.getPoiType(), R.drawable.module_common_ic_rc_freeze2, R.drawable.module_common_ic_rc_freeze2_white, "结冰")); - poiWrapper.put(EventTypeEnum.FOURS_ACCIDENT.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_ACCIDENT.getPoiType(), + poiWrapper.put(EventTypeEnumNew.FOURS_ACCIDENT.getPoiType(), new PoiWrapper(EventTypeEnumNew.FOURS_ACCIDENT.getPoiType(), R.drawable.module_common_ic_rc_accident3, R.drawable.module_common_ic_rc_accident3_white, "事故")); - poiWrapper.put(EventTypeEnum.FOURS_ACCIDENT_01.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_ACCIDENT_01.getPoiType(), + poiWrapper.put(EventTypeEnumNew.FOURS_ACCIDENT_01.getPoiType(), new PoiWrapper(EventTypeEnumNew.FOURS_ACCIDENT_01.getPoiType(), R.drawable.module_common_ic_rc_accident3, R.drawable.module_common_ic_rc_accident3_white, "重大事故")); - poiWrapper.put(EventTypeEnum.FOURS_ACCIDENT_02.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_ACCIDENT_02.getPoiType(), + poiWrapper.put(EventTypeEnumNew.FOURS_ACCIDENT_02.getPoiType(), new PoiWrapper(EventTypeEnumNew.FOURS_ACCIDENT_02.getPoiType(), R.drawable.module_common_ic_rc_accident3, R.drawable.module_common_ic_rc_accident3_white, "特大事故")); - poiWrapper.put(EventTypeEnum.FOURS_ACCIDENT_03.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_ACCIDENT_03.getPoiType(), + poiWrapper.put(EventTypeEnumNew.FOURS_ACCIDENT_03.getPoiType(), new PoiWrapper(EventTypeEnumNew.FOURS_ACCIDENT_03.getPoiType(), R.drawable.module_common_ic_rc_accident3, R.drawable.module_common_ic_rc_accident3_white, "较大事故")); - poiWrapper.put(EventTypeEnum.FOURS_ACCIDENT_04.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_ACCIDENT_04.getPoiType(), + poiWrapper.put(EventTypeEnumNew.FOURS_ACCIDENT_04.getPoiType(), new PoiWrapper(EventTypeEnumNew.FOURS_ACCIDENT_04.getPoiType(), R.drawable.module_common_ic_rc_accident3, R.drawable.module_common_ic_rc_accident3_white, "一般事故")); - poiWrapper.put(EventTypeEnum.FOURS_ACCIDENT_05.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_ACCIDENT_05.getPoiType(), + poiWrapper.put(EventTypeEnumNew.FOURS_ACCIDENT_05.getPoiType(), new PoiWrapper(EventTypeEnumNew.FOURS_ACCIDENT_05.getPoiType(), R.drawable.module_common_ic_rc_accident3, R.drawable.module_common_ic_rc_accident3_white, "轻微事故")); - poiWrapper.put(EventTypeEnum.FOURS_LIVING.getPoiType(), new PoiWrapper(EventTypeEnum.FOURS_LIVING.getPoiType(), + poiWrapper.put(EventTypeEnumNew.FOURS_LIVING.getPoiType(), new PoiWrapper(EventTypeEnumNew.FOURS_LIVING.getPoiType(), R.drawable.module_common_icon_map_marker_living, R.drawable.module_common_icon_map_marker_living_white, "实时路况")); - poiWrapper.put(EventTypeEnum.ILLEGAL_PARK_LIVING.getPoiType(), new PoiWrapper(EventTypeEnum.ILLEGAL_PARK_LIVING.getPoiType(), + poiWrapper.put(EventTypeEnumNew.ILLEGAL_PARK_LIVING.getPoiType(), new PoiWrapper(EventTypeEnumNew.ILLEGAL_PARK_LIVING.getPoiType(), R.drawable.module_common_ic_rc_illegal_park, R.drawable.module_common_ic_rc_illegal_park_white, "违章停车")); // 分享里用到的故障求助 poiWrapper.put("9999", new PoiWrapper("9999", diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt index 977ff69174..3579d55ea4 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeEnumNew.kt @@ -554,6 +554,22 @@ enum class EventTypeEnumNew( } } + @JvmStatic + fun getTtsWithFeedback(poiType: String?): String { + return when (poiType) { + TRAFFIC_CHECK.poiType -> "交通检查" + ROAD_CLOSED.poiType -> "封路" + FOURS_ROAD_WORK.poiType -> "施工" + FOURS_BLOCK_UP.poiType -> "道路拥堵" + FOURS_PONDING.poiType -> "道路积水" + FOURS_FOG.poiType -> "出现浓雾" + FOURS_ICE.poiType -> "路面结冰" + FOURS_ACCIDENT.poiType, FOURS_ACCIDENT_01.poiType, FOURS_ACCIDENT_02.poiType, + FOURS_ACCIDENT_03.poiType, FOURS_ACCIDENT_04.poiType, FOURS_ACCIDENT_05.poiType -> "交通事故" + else -> "道路事件" + } + } + @JvmStatic fun getPoiTypeSrcVr(poiType: String): Int { return when (poiType) { diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeHelper.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeHelper.kt index 8f8cd1ff35..b1da3cc519 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeHelper.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/EventTypeHelper.kt @@ -29,20 +29,20 @@ class EventTypeHelper { when { direction.isLeft() -> { data.invoke( - EventTypeEnum.getWarningContent(appId.toString() + "左"), - EventTypeEnum.getWarningTts(appId.toString() + "左") + EventTypeEnumNew.getWarningContent(appId.toString() + "左"), + EventTypeEnumNew.getWarningTts(appId.toString() + "左") ) } direction.isRight() -> { data.invoke( - EventTypeEnum.getWarningContent(appId.toString() + "右"), - EventTypeEnum.getWarningTts(appId.toString() + "右") + EventTypeEnumNew.getWarningContent(appId.toString() + "右"), + EventTypeEnumNew.getWarningTts(appId.toString() + "右") ) } else -> { data.invoke( - EventTypeEnum.getWarningContent(appId.toString()), - EventTypeEnum.getWarningTts(appId.toString()) + EventTypeEnumNew.getWarningContent(appId.toString()), + EventTypeEnumNew.getWarningTts(appId.toString()) ) } } @@ -56,8 +56,8 @@ class EventTypeHelper { data: ((alert: String, tts: String) -> Unit) ) { data.invoke( - EventTypeEnum.getWarningContent(appId.toString() + direction.desc), - EventTypeEnum.getWarningContent(appId.toString() + direction.desc) + EventTypeEnumNew.getWarningContent(appId.toString() + direction.desc), + EventTypeEnumNew.getWarningContent(appId.toString() + direction.desc) ) } @@ -65,8 +65,8 @@ class EventTypeHelper { @BizConfig(V2V, "", BIZ_LTA) fun getLTA(appId: Int, data: ((alert: String, tts: String) -> Unit)) { data.invoke( - EventTypeEnum.getWarningContent(appId.toString()), - EventTypeEnum.getWarningTts(appId.toString()) + EventTypeEnumNew.getWarningContent(appId.toString()), + EventTypeEnumNew.getWarningTts(appId.toString()) ) } @@ -78,8 +78,8 @@ class EventTypeHelper { data: ((alert: String, tts: String) -> Unit) ) { data.invoke( - EventTypeEnum.getWarningContent(appId.toString() + direction.desc), - EventTypeEnum.getWarningTts(appId.toString() + direction.desc) + EventTypeEnumNew.getWarningContent(appId.toString() + direction.desc), + EventTypeEnumNew.getWarningTts(appId.toString() + direction.desc) ) } @@ -93,22 +93,22 @@ class EventTypeHelper { when { direction.isLeft() -> { data.invoke( - EventTypeEnum.getWarningContent(appId.toString() + "左"), - EventTypeEnum.getWarningTts(appId.toString() + "左"), + EventTypeEnumNew.getWarningContent(appId.toString() + "左"), + EventTypeEnumNew.getWarningTts(appId.toString() + "左"), true ) } direction.isRight() -> { data.invoke( - EventTypeEnum.getWarningContent(appId.toString() + "右"), - EventTypeEnum.getWarningTts(appId.toString() + "右"), + EventTypeEnumNew.getWarningContent(appId.toString() + "右"), + EventTypeEnumNew.getWarningTts(appId.toString() + "右"), true ) } else -> { data.invoke( - EventTypeEnum.getWarningContent(appId.toString()), - EventTypeEnum.getWarningTts(appId.toString()), + EventTypeEnumNew.getWarningContent(appId.toString()), + EventTypeEnumNew.getWarningTts(appId.toString()), false ) } @@ -119,9 +119,9 @@ class EventTypeHelper { @BizConfig(V2N, "", BIZ_VRU) fun getVRU(data: ((appId: Int, tts: String, content: String) -> Unit)) { data.invoke( - EventTypeEnum.TYPE_USECASE_ID_VRUCW_PERSON.poiType.toInt(), - EventTypeEnum.TYPE_USECASE_ID_VRUCW_PERSON.tts, - EventTypeEnum.TYPE_USECASE_ID_VRUCW_PERSON.content + EventTypeEnumNew.TYPE_USECASE_ID_VRUCW_PERSON.poiType.toInt(), + EventTypeEnumNew.TYPE_USECASE_ID_VRUCW_PERSON.tts, + EventTypeEnumNew.TYPE_USECASE_ID_VRUCW_PERSON.content ) } @@ -129,7 +129,7 @@ class EventTypeHelper { @BizConfig(V2N, "", BIZ_VRU_RI) fun getVRURI(data: ((appId: Int, tts: String, content: String) -> Unit)) { data.invoke( - EventTypeEnum.TYPE_USECASE_ID_VRUCW_PERSON.poiType.toInt(), + EventTypeEnumNew.TYPE_USECASE_ID_VRUCW_PERSON.poiType.toInt(), "行人逆行预警", "行人逆行预警" ) @@ -139,18 +139,18 @@ class EventTypeHelper { @BizConfig(V2N, "", BIZ_OPT_LINE) fun getOptLine(data: ((appId: Int, tts: String, content: String) -> Unit)) { data.invoke( - EventTypeEnum.TYPE_USECASE_OPTIMAL_LANE.poiType.toInt(), - EventTypeEnum.TYPE_USECASE_OPTIMAL_LANE.tts, - EventTypeEnum.TYPE_USECASE_OPTIMAL_LANE.content + EventTypeEnumNew.TYPE_USECASE_OPTIMAL_LANE.poiType.toInt(), + EventTypeEnumNew.TYPE_USECASE_OPTIMAL_LANE.tts, + EventTypeEnumNew.TYPE_USECASE_OPTIMAL_LANE.content ) } //前方道路拥堵预警 fun getTJW(data: ((appId: Int, tts: String, content: String) -> Unit)) { data.invoke( - EventTypeEnum.FOURS_BLOCK_UP.poiType.toInt(), - EventTypeEnum.FOURS_BLOCK_UP.tts, - EventTypeEnum.FOURS_BLOCK_UP.content + EventTypeEnumNew.FOURS_BLOCK_UP.poiType.toInt(), + EventTypeEnumNew.FOURS_BLOCK_UP.tts, + EventTypeEnumNew.FOURS_BLOCK_UP.content ) } @@ -158,8 +158,8 @@ class EventTypeHelper { @BizConfig(V2V, "", BIZ_EBW) fun getEBW(appId: Int, data: ((tts: String, content: String) -> Unit)) { data.invoke( - EventTypeEnum.getWarningContent(appId.toString()), - EventTypeEnum.getWarningTts(appId.toString()) + EventTypeEnumNew.getWarningContent(appId.toString()), + EventTypeEnumNew.getWarningTts(appId.toString()) ) } @@ -167,8 +167,8 @@ class EventTypeHelper { @BizConfig(V2V, "", BIZ_FCW) fun getFCW(appId: Int, data: ((tts: String, content: String) -> Unit)) { data.invoke( - EventTypeEnum.getWarningContent(appId.toString()), - EventTypeEnum.getWarningTts(appId.toString()) + EventTypeEnumNew.getWarningContent(appId.toString()), + EventTypeEnumNew.getWarningTts(appId.toString()) ) } @@ -176,8 +176,8 @@ class EventTypeHelper { @BizConfig(V2V, "", BIZ_DNPW) fun getDNPW(appId: Int, data: ((tts: String, content: String) -> Unit)) { data.invoke( - EventTypeEnum.getWarningContent(appId.toString()), - EventTypeEnum.getWarningTts(appId.toString()) + EventTypeEnumNew.getWarningContent(appId.toString()), + EventTypeEnumNew.getWarningTts(appId.toString()) ) } diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/map/entity/V2XRoadEventEntity.java b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/map/entity/V2XRoadEventEntity.java index 0bd2dab8fd..2c2b3a4e5a 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/map/entity/V2XRoadEventEntity.java +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/map/entity/V2XRoadEventEntity.java @@ -1,9 +1,6 @@ package com.mogo.eagle.core.data.map.entity; import android.text.TextUtils; - - -import com.mogo.eagle.core.data.enums.EventTypeEnum; import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import java.io.Serializable; @@ -59,12 +56,12 @@ public class V2XRoadEventEntity implements Serializable { } public String getTts(boolean haveLiveCar) { - if (EventTypeEnum.GHOST_PROBE.getPoiType().equals(poiType)) { - tts = EventTypeEnum.GHOST_PROBE.getTts(); + if (EventTypeEnumNew.GHOST_PROBE.getPoiType().equals(poiType)) { + tts = EventTypeEnumNew.GHOST_PROBE.getTts(); return tts; } tts = "前方#" + (int) getDistance() + "米#"; - tts += EventTypeEnum.getTts(getPoiType()); + tts += EventTypeEnumNew.getTts(getPoiType()); if (haveLiveCar) { tts += ",查看实况请说确定。"; setShowEventButton(true); @@ -80,7 +77,7 @@ public class V2XRoadEventEntity implements Serializable { */ public String getTtsWithFeedback() { tts = "检测到附近"; - tts += EventTypeEnum.getTtsWithFeedback(getPoiType()); + tts += EventTypeEnumNew.getTtsWithFeedback(getPoiType()); tts += ",确认该信息是否正确?您可以说“正确”或“错误”帮助其他车友。"; return tts; } @@ -102,7 +99,7 @@ public class V2XRoadEventEntity implements Serializable { } public String getAlarmContent() { - alarmContent = EventTypeEnum.getAlarmContent(getPoiType()); + alarmContent = EventTypeEnumNew.getAlarmContent(getPoiType()); return alarmContent; } From 0b84b3855e1df67827362f89039af5db2d8555f7 Mon Sep 17 00:00:00 2001 From: lixiaopeng Date: Mon, 30 Jan 2023 18:13:25 +0800 Subject: [PATCH 27/48] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=B0=E7=9A=84obu?= =?UTF-8?q?=20sdk=E6=97=A5=E5=BF=97=E7=9A=84=E5=BC=80=E5=85=B3=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mogo-core-function-hmi/build.gradle | 1 + .../hmi/ui/setting/DebugSettingView.kt | 20 ++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/core/function-impl/mogo-core-function-hmi/build.gradle b/core/function-impl/mogo-core-function-hmi/build.gradle index 86fe27008a..cfbb042e0e 100644 --- a/core/function-impl/mogo-core-function-hmi/build.gradle +++ b/core/function-impl/mogo-core-function-hmi/build.gradle @@ -69,6 +69,7 @@ dependencies { // debugImplementation rootProject.ext.dependencies.debugleakcanary // releaseImplementation rootProject.ext.dependencies.releaseleakcanary + implementation rootProject.ext.dependencies.mogoobu implementation rootProject.ext.dependencies.arouter kapt rootProject.ext.dependencies.aroutercompiler diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt index 6911df61f8..1674acdcb5 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt @@ -16,6 +16,7 @@ import androidx.appcompat.widget.PopupMenu import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.ContextCompat import androidx.core.view.* +import androidx.lifecycle.lifecycleScope import chassis.Chassis import chassis.ChassisStatesOuterClass import com.mogo.cloud.passport.MoGoAiCloudClient @@ -63,6 +64,7 @@ import com.mogo.eagle.core.function.hmi.ui.logcatch.ILogViewListener import com.mogo.eagle.core.function.hmi.ui.logcatch.LogInfoView import com.mogo.eagle.core.function.hmi.ui.widget.DemoModeView import com.mogo.eagle.core.utilcode.kotlin.currentPadding +import com.mogo.eagle.core.utilcode.kotlin.lifecycleOwner import com.mogo.eagle.core.utilcode.kotlin.onClick import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils import com.mogo.eagle.core.utilcode.mogo.logger.LogLevel @@ -74,17 +76,18 @@ import com.mogo.eagle.core.utilcode.mogo.toast.TipToast import com.mogo.eagle.core.utilcode.util.* import com.mogo.map.uicontroller.VisualAngleMode import com.mogo.map.uicontroller.VisualAngleMode.* -//import com.zhidao.easysocket.utils.L +import com.mogo.support.obu.MogoObuManager +import com.mogo.support.obu.constants.MogoObuLogLevel +import com.mogo.support.obu.option.MogoObuLog import com.zhjt.mogo_core_function_devatools.env.* import kotlinx.android.synthetic.main.view_debug_setting.view.* +import kotlinx.coroutines.launch import mogo.telematics.pad.MessagePad import mogo_msg.MogoReportMsg import java.text.SimpleDateFormat import java.util.* import kotlin.math.abs -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.launch -import com.mogo.eagle.core.utilcode.kotlin.lifecycleOwner + /** * @author xiaoyuzhou @@ -1269,7 +1272,14 @@ internal class DebugSettingView @JvmOverloads constructor( * 设置是否输出OBU日志 true-打印日志,false-不打印日志 */ tbObuLog.setOnCheckedChangeListener { _, isChecked -> -// L.setEnableLog(isChecked) + MogoObuManager.getInstance().setEnableLog(isChecked) + + val builder: com.mogo.support.obu.option.MogoObuLog.Builder = + MogoObuLog.newBuilder().setEnableStdio(isChecked) + if (isChecked) { + builder.setStdioLevel(MogoObuLogLevel.DBG) + } + MogoObuManager.getInstance().logConfig(builder.build()) } /** From 2baf4aa785588d617c9e0412623558baf35aa7c2 Mon Sep 17 00:00:00 2001 From: renwj Date: Mon, 30 Jan 2023 19:11:06 +0800 Subject: [PATCH 28/48] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0][fix]=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E5=9B=A0=E4=BD=8D=E7=BD=AE=E5=9B=9E=E8=B0=83=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E9=80=A0=E6=88=90=E7=9A=84v2x=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mogo/launcher/stageone/HttpDnsStartUp.kt | 17 +-- .../collect/MoGoMapDataCollectProvider.kt | 22 ++-- .../function/v2x/events/V2XEventManager.kt | 18 ++- .../v2x/events/marker/MarkerManager.kt | 30 +++-- .../scenario/scene/airoad/AiRoadMarker.kt | 15 +-- .../scene/road/V2XRoadEventScenario.java | 5 +- .../map/CallerMapLocationListenerManager.kt | 114 +----------------- .../call/map/CallerVisualAngleManager.kt | 8 +- .../java/com/mogo/map/AMapViewWrapper.java | 56 +-------- 9 files changed, 66 insertions(+), 219 deletions(-) diff --git a/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt b/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt index a189438325..42da7c05f5 100644 --- a/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt +++ b/app/src/main/java/com/mogo/launcher/stageone/HttpDnsStartUp.kt @@ -29,8 +29,10 @@ import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_ALIAS_C import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_CLOUD import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_LOG_CONNECT_STATUS import com.mogo.eagle.core.data.map.MogoLocation +import com.mogo.eagle.core.function.api.autopilot.* import com.mogo.eagle.core.function.api.map.listener.IMoGoMapLocationListener import com.mogo.eagle.core.function.call.analytics.AnalyticsManager +import com.mogo.eagle.core.function.call.autopilot.* import com.mogo.eagle.core.function.call.cloud.CallerCloudListenerManager import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager @@ -45,6 +47,7 @@ import com.rousetime.android_startup.AndroidStartup import com.zhjt.mogo_core_function_devatools.env.EnvChangeManager import com.zhjt.service.chain.ChainLog import com.zhjt.service.chain.TracingConstants.Endpoint.Companion.PAD +import mogo.telematics.pad.MessagePad.GnssInfo class HttpDnsStartUp : AndroidStartup() { @@ -70,8 +73,7 @@ class HttpDnsStartUp : AndroidStartup() { override fun dependenciesByName(): List { return listOf( - "com.mogo.launcher.stageone.APMStartup", - "com.mogo.launcher.stageone.ThreadOptStartup" + "com.mogo.launcher.stageone.APMStartup" ) } @@ -292,17 +294,16 @@ class HttpDnsStartUp : AndroidStartup() { context?.let { MogoLocationInfoServices.getInstance().init(it) MogoLocationInfoServices.getInstance().start() - CallerMapLocationListenerManager.addListener( + CallerChassisLocationGCJ20ListenerManager.addListener( TAG, - object : IMoGoMapLocationListener { - override fun onLocationChanged( - location: MogoLocation?, from: Int, isGps: Boolean) { - location?.let { loc -> + object : IMoGoChassisLocationGCJ02Listener { + + override fun onChassisLocationGCJ02(gnssInfo: GnssInfo?) { + CallerMapLocationListenerManager.getCurrentLocation()?.let { loc -> MogoLocationInfoServices.getInstance().provideLocation(loc) } } }, - false ) } } diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/collect/MoGoMapDataCollectProvider.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/collect/MoGoMapDataCollectProvider.kt index 5b429da8ba..83e51481df 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/collect/MoGoMapDataCollectProvider.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/collect/MoGoMapDataCollectProvider.kt @@ -10,23 +10,24 @@ import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.data.constants.MogoServicePaths import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_MAP import com.mogo.eagle.core.data.map.MogoLocation -import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener +import com.mogo.eagle.core.function.api.autopilot.* import com.mogo.eagle.core.function.api.map.collect.IMoGoMapDataCollectProvider import com.mogo.eagle.core.function.api.map.listener.IMoGoMapLocationListener -import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager +import com.mogo.eagle.core.function.call.autopilot.* import com.mogo.eagle.core.function.call.map.CallerMapDataCollectorManager import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager import com.zhidaoauto.map.operational.open.GatherApi import com.zhidaoauto.map.operational.open.GatherParams import com.zhidaoauto.map.operational.open.abs.OnTaskListener +import mogo.telematics.pad.MessagePad.GnssInfo import record_cache.RecordPanelOuterClass import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.CopyOnWriteArrayList import java.util.concurrent.atomic.AtomicReference @Route(path = MogoServicePaths.PATH_MAP_DATA_COLLECT_PROVIDER) -class MoGoMapDataCollectProvider : IMoGoMapDataCollectProvider, OnTaskListener, IMoGoMapLocationListener, IMoGoTokenCallback, +class MoGoMapDataCollectProvider : IMoGoMapDataCollectProvider, OnTaskListener, IMoGoChassisLocationGCJ02Listener, IMoGoTokenCallback, IMoGoAutopilotRecordListener { companion object { @@ -52,7 +53,7 @@ class MoGoMapDataCollectProvider : IMoGoMapDataCollectProvider, OnTaskListener, override fun init(context: Context?) { - CallerMapLocationListenerManager.addListener(TAG, this, false) + CallerChassisLocationGCJ20ListenerManager.addListener(TAG, this) CallerAutopilotRecordListenerManager.addListener(TAG, this) executor.set(context?.let { @@ -74,7 +75,7 @@ class MoGoMapDataCollectProvider : IMoGoMapDataCollectProvider, OnTaskListener, override fun onDestroy() { CallerLogger.d("$M_MAP$TAG", "--------- onDestroy --------") - CallerMapLocationListenerManager.removeListener(TAG, false) + CallerChassisLocationGCJ20ListenerManager.removeListener(TAG) CallerAutopilotRecordListenerManager.removeListener(TAG) executor.get()?.setOnTaskListener(null) listeners.clear() @@ -170,18 +171,17 @@ class MoGoMapDataCollectProvider : IMoGoMapDataCollectProvider, OnTaskListener, } } - override fun onLocationChanged(location: MogoLocation?, from: Int, isGps: Boolean) { - location ?: return + override fun onChassisLocationGCJ02(gnssInfo: GnssInfo?) { + val location = CallerMapLocationListenerManager.getCurrentLocation() ?: return executor.get()?.updateLocation( - location.longitude, - location.latitude, + location.longitude, + location.latitude, location.altitude, location.bearing, location.speed, - isGps) + false) } - private fun isInValidStatus(): Boolean { if (map.isEmpty()) { return true 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 dbb4bdd0a6..711fde9e88 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 @@ -24,10 +24,10 @@ import com.mogo.eagle.core.data.msgbox.MsgBoxBean 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.* 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.CallerAutoPilotStatusListenerManager -import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager +import com.mogo.eagle.core.function.call.autopilot.* 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 @@ -72,12 +72,13 @@ import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers import kotlinx.coroutines.* import kotlinx.coroutines.android.* +import mogo.telematics.pad.MessagePad.GnssInfo import tv.danmaku.ijk.media.player.* import java.util.concurrent.* import java.util.concurrent.atomic.* -object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallback { +object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IMoGoTokenCallback, IV2XCallback { private const val TAG = "V2XEventManager" @@ -87,8 +88,6 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb private val hasInit by lazy { AtomicBoolean(false) } - // 记录历史行驶轨迹,用于车行驶方向计算,只保留两个数据 - private val historyPath = arrayOfNulls(2) var v2xEventDisposable: Disposable? = null @@ -120,7 +119,7 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb private fun registerListener() { V2XManager.addCallback(this) - CallerMapLocationListenerManager.addListener(TAG, this, false) + CallerChassisLocationGCJ20ListenerManager.addListener(TAG, this) mogoMarkersHandler.registerMarkerClickListener(CARD_TYPE_ROAD_CONDITION, object : IMogoMarkerClickListener { override fun onMarkerClicked(marker: IMogoMarker?): Boolean { @@ -132,7 +131,7 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb private fun unRegisterListener() { V2XManager.removeCallback(this) - CallerMapLocationListenerManager.removeListener(TAG, false) + CallerChassisLocationGCJ20ListenerManager.removeListener(TAG) mogoMarkersHandler.unregisterMarkerClickListener(CARD_TYPE_ROAD_CONDITION) } @@ -206,8 +205,8 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb V2XScenarioManager.getInstance().handlerMessage(entity) } - override fun onLocationChanged(location: MogoLocation?, from: Int, isGps: Boolean) { - location ?: return + override fun onChassisLocationGCJ02(gnssInfo: GnssInfo?) { + val location = CallerMapLocationListenerManager.getCurrentLocation() ?: return BridgeApi.location.set(location) if (V2XManager.hasInit()) { V2XManager.onLocationChanged( @@ -218,7 +217,6 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb V2XOptimalRouteObserver.getInstance().update(location) refreshCarState(location) } - private fun refreshCarState(location: MogoLocation) { V2XStatusManager.getInstance().location = location val v2xPolyline = BridgeApi.v2xPolyline()?.mogoPolyline diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/MarkerManager.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/MarkerManager.kt index 1039bbcd30..f738b3ab34 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/MarkerManager.kt +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/MarkerManager.kt @@ -4,12 +4,12 @@ import android.os.Handler import android.os.HandlerThread import android.util.Log import com.mogo.cloud.commons.utils.CoordinateUtils -import com.mogo.eagle.core.data.map.MogoLocation -import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager +import com.mogo.eagle.core.function.call.autopilot.* import com.mogo.eagle.core.utilcode.util.* import com.mogo.map.marker.IMogoMarker import com.mogo.map.overlay.IMogoPolyline import kotlinx.coroutines.Runnable +import mogo.telematics.pad.MessagePad.GnssInfo import java.util.LinkedList import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicBoolean @@ -64,9 +64,9 @@ object MarkerManager { private val elapsedDistances by lazy { ConcurrentHashMap() } - private val lastCarLocation by lazy { AtomicReference() } + private val lastCarLocation by lazy { AtomicReference>() } - private val lastGpsLocation by lazy { AtomicReference() } + private val lastGpsLocation by lazy { AtomicReference>() } private val checkTask = object : Runnable { @@ -83,21 +83,22 @@ object MarkerManager { } Log.d(TAG, "--- checkTask --- 3 ---") val toRemove = toRemoveMakers.iterator() - val carLoc = AtomicReference() + val carLoc = AtomicReference() while (toRemove.hasNext()) { val marker = toRemove.next() if (carLoc.get() == null) { carLoc.set(if (marker.coordinateType == 0) { //高德坐标 - CallerMapLocationListenerManager.getCurrentLocation() + CallerChassisLocationGCJ20ListenerManager.getChassisLocationGCJ02() } else { - CallerMapLocationListenerManager.getCurrentGpsLocation() + //高精坐标 + CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() }) } val currentLocation = carLoc.get() val lastLocation = if (marker.coordinateType == 0) lastCarLocation.get() else lastGpsLocation.get() if (currentLocation != null && lastLocation != null) { - val delta = CoordinateUtils.calculateLineDistance(currentLocation.longitude, currentLocation.latitude, lastLocation.longitude, lastLocation.latitude) + val delta = CoordinateUtils.calculateLineDistance(currentLocation.longitude, currentLocation.latitude, lastLocation.first, lastLocation.second) Log.d(TAG, "--- checkTask --- 4 ---:delta:$delta, id:${marker.id}") var elapsed = elapsedDistances[marker] if (elapsed == null) { @@ -148,14 +149,15 @@ object MarkerManager { if (carLoc.get() == null) { carLoc.set(if (marker.coordinateType == 0) { //高德坐标 - CallerMapLocationListenerManager.getCurrentLocation() + CallerChassisLocationGCJ20ListenerManager.getChassisLocationGCJ02() } else { - CallerMapLocationListenerManager.getCurrentGpsLocation() + //高精坐标 + CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() }) } val location = carLoc.get() if (location != null) { - val angle = DrivingDirectionUtils.getDegreeOfCar2Poi2(location.longitude, location.latitude, marker.lon, marker.lat, location.bearing.toDouble()) + val angle = DrivingDirectionUtils.getDegreeOfCar2Poi2(location.longitude, location.latitude, marker.lon, marker.lat, location.heading) if (angle >= 90) { iterator.remove() synchronized(toRemoveMakers) { @@ -167,8 +169,10 @@ object MarkerManager { } catch (t: Throwable) { t.printStackTrace() } finally { - lastCarLocation.set(CallerMapLocationListenerManager.getCurrentLocation()) - lastGpsLocation.set(CallerMapLocationListenerManager.getCurrentGpsLocation()) + val gcInfo = CallerChassisLocationGCJ20ListenerManager.getChassisLocationGCJ02() + lastCarLocation.set((gcInfo?.longitude ?: 0.0) to (gcInfo?.latitude ?: 0.0)) + val wgsInfo = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() + lastGpsLocation.set((wgsInfo?.longitude ?: 0.0) to (wgsInfo?.latitude ?: 0.0)) handler.postDelayed(this, 1000) } } 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 b653876cc6..ef0cb94abc 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 @@ -10,6 +10,7 @@ import com.mogo.cloud.commons.utils.* import com.mogo.commons.AbsMogoApplication import com.mogo.eagle.core.data.map.MogoLatLng import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity +import com.mogo.eagle.core.function.call.autopilot.* import com.mogo.eagle.core.function.call.map.* import com.mogo.eagle.core.function.v2x.events.scenario.scene.road.V2XAiRoadEventMarker import com.mogo.eagle.core.utilcode.mogo.logger.Logger @@ -61,7 +62,7 @@ class AiRoadMarker { private val checkExpiredTask = Runnable { val poi = this.marker.get() - val car = CallerMapLocationListenerManager.getCurrentGpsLocation() + val car = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() if (poi != null && car != null) { val distance = CoordinateUtils.calculateLineDistance(car.longitude, car.latitude, poi.poi_lon, poi.poi_lat) if (distance < 500) { @@ -80,7 +81,7 @@ class AiRoadMarker { } fun marker(marker: Marker, drawMarker: Boolean, drawRoadLine: Boolean = false) { - val location = CallerMapLocationListenerManager.getCurrentGpsLocation() ?: return + val location = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() ?: return this.marker.set(marker) val wrapper = MarkerWrapper(marker.id, marker.poi_lon, marker.poi_lat, 1, null, null) if (drawMarker) { @@ -88,10 +89,10 @@ class AiRoadMarker { } if (drawRoadLine) { //施工中心点前方的自车行驶方向上300米距离 - val l1 = MogoMap.getInstance().mogoMap.getCenterLineRangeInfo(marker.poi_lon, marker.poi_lat, location.bearing, 300f) + val l1 = MogoMap.getInstance().mogoMap.getCenterLineRangeInfo(marker.poi_lon, marker.poi_lat, location.heading.toFloat(), 300f) //施工中心点后方的自车行驶方向上300米距离 Logger.d(TAG, "--- marker --- 3 --- l1: $l1") - val l2 = MogoMap.getInstance().mogoMap.getCenterLineRangeInfo(marker.poi_lon, marker.poi_lat, location.bearing, -300f) + val l2 = MogoMap.getInstance().mogoMap.getCenterLineRangeInfo(marker.poi_lon, marker.poi_lat, location.heading.toFloat(), -300f) if (l1.points.isEmpty() || l2.points.isEmpty()) { Logger.d(TAG, "--- marker --- 3 --- return ----") return @@ -110,7 +111,7 @@ class AiRoadMarker { var find: Pair = Pair(centerX, centerY) var min = Long.MAX_VALUE for (p in it) { - val angle = DrivingDirectionUtils.getDegreeOfCar2Poi2(centerX, centerY, p.first, p.second, location.bearing.toDouble()) + val angle = DrivingDirectionUtils.getDegreeOfCar2Poi2(centerX, centerY, p.first, p.second, location.heading) if (angle < min) { min = angle find = p @@ -122,7 +123,7 @@ class AiRoadMarker { 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.bearing + 180).toDouble()) < 90L) { + if (DrivingDirectionUtils.getDegreeOfCar2Poi2(farthestPoint.lon, farthestPoint.lat, l.first, l.second, (location.heading + 180)) < 90L) { points.add(l.let { MogoLatLng(it.second, it.first) }) } } @@ -180,7 +181,7 @@ class AiRoadMarker { fun receive() { Logger.d(TAG, "receive --- 1 ---") val poi = this.marker.get() - val car = CallerMapLocationListenerManager.getCurrentGpsLocation() + val car = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84() if (poi != null && car != null) { val distance = CoordinateUtils.calculateLineDistance(car.longitude, car.latitude, poi.poi_lon, poi.poi_lat) Logger.d(TAG, "receive --- 2 ---:car:[${car.longitude}, ${car.latitude}] -> poi:[${poi.poi_lon}, ${poi.poi_lat}] --> distance:$distance") diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventScenario.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventScenario.java index 5441044185..98998db728 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventScenario.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventScenario.java @@ -17,6 +17,7 @@ import com.mogo.eagle.core.data.msgbox.MsgBoxBean; import com.mogo.eagle.core.data.msgbox.MsgBoxType; import com.mogo.eagle.core.data.msgbox.V2XMsg; import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener; +import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ20ListenerManager; import com.mogo.eagle.core.function.call.hmi.CallerHmiManager; import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager; import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager; @@ -31,6 +32,7 @@ import java.util.Map; import java.util.Objects; import java.util.concurrent.TimeUnit; +import mogo.telematics.pad.MessagePad; /** @@ -123,9 +125,8 @@ public class V2XRoadEventScenario extends AbsV2XScenario imp EventTypeEnumNew. TYPE_SOCKET_ROAD_JINGZHI.getPoiType().equals(poiType) || EventTypeEnumNew.TYPE_SOCKET_ROAD_CONGESTION.getPoiType().equals(poiType) || EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGU.getPoiType().equals(poiType)) { - MogoLocation carLocation = CallerMapLocationListenerManager.INSTANCE.getCurrentLocation(); MarkerExploreWay noveltyInfo = content.getNoveltyInfo(); - if (carLocation != null && noveltyInfo != null) { + if (noveltyInfo != null) { MarkerLocation eventLocation = noveltyInfo.getLocation(); if (eventLocation != null) { double distance = content.getDistance(); diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerMapLocationListenerManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerMapLocationListenerManager.kt index c779e1e802..08ab9ff67f 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerMapLocationListenerManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerMapLocationListenerManager.kt @@ -13,21 +13,9 @@ import java.util.concurrent.ConcurrentHashMap object CallerMapLocationListenerManager : CallerBase() { // 记录地图最后一次位置 + @Volatile private var mLocation: MogoLocation? = null - /** - * 记录最后一次高精坐标的位置 - */ - private var mGpsLocation: MogoLocation? = null - - // 存储所有注册了监听的对象,invokeXXXX进行遍历回调,将信息同步 - private val mMapStyleChangeListeners: ConcurrentHashMap = - ConcurrentHashMap() - - - // 高精坐标回调 - private val mGpsChangedListeners: ConcurrentHashMap = ConcurrentHashMap() - /** * 获取当前经纬度 */ @@ -35,103 +23,7 @@ object CallerMapLocationListenerManager : CallerBase() { return mLocation } - /** - * 获取当前高精坐标 - */ - fun getCurrentGpsLocation(): MogoLocation? { - return mGpsLocation - } - - /** - * 添加 地图样式改变 监听 - * @param tag 标记,用来注销监听使用 - * @param listener 监听回调 - */ - fun addListener(tag: String, listener: IMoGoMapLocationListener, isGps: Boolean) { - if (!isGps) { - if (mMapStyleChangeListeners.containsKey(tag)) { - return - } - mMapStyleChangeListeners[tag] = listener - listener.onLocationChanged(mLocation, 0, isGps) - } else { - if (mGpsChangedListeners.containsKey(tag)) { - return - } - mGpsChangedListeners[tag] = listener - listener.onLocationChanged(mGpsLocation, 0, isGps) - } - - } - - /** - * 删除 地图样式改变 监听 - * @param tag 标记,用来注销监听使用 - */ - fun removeListener(tag: String, isGps: Boolean) { - if (!isGps) { - if (!mMapStyleChangeListeners.containsKey(tag)) { - return - } - mMapStyleChangeListeners.remove(tag) - } else { - if (!mGpsChangedListeners.containsKey(tag)) { - return - } - mGpsChangedListeners.remove(tag) - } - - } - - /** - * 删除 地图样式改变 监听 - * @param listener 要删除的监听对象 - */ - fun removeListener(listener: IMoGoMapLocationListener, isGps: Boolean) { - if (!isGps) { - if (!mMapStyleChangeListeners.containsValue(listener)) { - return - } - mMapStyleChangeListeners.forEach { - if (it.value == listener) { - mMapStyleChangeListeners.remove(it.key) - } - } - } else { - if (!mGpsChangedListeners.containsValue(listener)) { - return - } - mGpsChangedListeners.forEach { - if (it.value == listener) { - mGpsChangedListeners.remove(it.key) - } - } - } - } - - /** - * 触发 地图样式改变 监听 - */ - fun invokeMapLocationChangeListener() { - invokeMapLocationChangeListener(mLocation, 0, false) - } - - /** - * 触发 地图样式改变 监听 - * @param location 选中状态 - */ - fun invokeMapLocationChangeListener(location: MogoLocation?, from: Int, isGps: Boolean) { - if (!isGps) { - mLocation = location - mMapStyleChangeListeners.forEach { - val listener = it.value - listener.onLocationChanged(location, from, isGps) - } - } else { - mGpsLocation = location - mGpsChangedListeners.forEach { - it.value.onLocationChanged(location, from, isGps) - } - } + fun setCurrentLocation(location: MogoLocation) { + mLocation = location } } \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerVisualAngleManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerVisualAngleManager.kt index 75b7b224e5..5e314cb6aa 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerVisualAngleManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/map/CallerVisualAngleManager.kt @@ -12,6 +12,7 @@ import androidx.lifecycle.LifecycleOwner import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.data.map.* import com.mogo.eagle.core.data.map.MapRoadInfo.StopLine +import com.mogo.eagle.core.function.call.autopilot.* import com.mogo.eagle.core.function.call.map.CallerMapRoadListenerManager.OnRoadListener import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.* import com.mogo.eagle.core.utilcode.kotlin.lifeCycleOwner @@ -23,6 +24,7 @@ import com.zhidaoauto.map.sdk.open.tools.MapTools import kotlinx.coroutines.* import kotlinx.coroutines.android.asCoroutineDispatcher import kotlinx.coroutines.internal.synchronized +import mogo.telematics.pad.MessagePad.GnssInfo import java.util.* import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit.SECONDS @@ -63,7 +65,7 @@ object CallerVisualAngleManager { val displayThreshold: Long //最大展示时长 > 0; 表示最长展示多长时间, -1 表示,一直展示,直到触发默认视角, 0: 默认视角专用值, } - private val triggerLocation = AtomicReference() + private val triggerLocation = AtomicReference() private val distanceOfCarToStopLine = AtomicReference(0.0) @@ -76,7 +78,7 @@ object CallerVisualAngleManager { override fun onRoadIdInfo(roadId: String) { this.roadId.set(roadId) Log.d(TAG, "-- onRoadIdInfo --: prev: ${this.triggerRoadId.get()} -> curr: $roadId") - val loc = CallerMapLocationListenerManager.getCurrentLocation() + val loc = CallerChassisLocationGCJ20ListenerManager.getChassisLocationGCJ02() var triggerClose = false val distance = distanceOfCarToStopLine.get() + 5 if (hasCrossRoad && distance > 0) { @@ -109,7 +111,7 @@ object CallerVisualAngleManager { hasCrossRoad = true triggerRoadId.set(this.roadId.get()) distanceOfCarToStopLine.set(info.distanceOfCarToStopLine) - triggerLocation.set(CallerMapLocationListenerManager.getCurrentLocation()) + triggerLocation.set(CallerChassisLocationGCJ20ListenerManager.getChassisLocationGCJ02()) changeVisualAngle(CrossRoad(true)) } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/AMapViewWrapper.java b/libraries/mogo-map/src/main/java/com/mogo/map/AMapViewWrapper.java index 80f9e2a682..075f159e6f 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/AMapViewWrapper.java +++ b/libraries/mogo-map/src/main/java/com/mogo/map/AMapViewWrapper.java @@ -121,10 +121,6 @@ public class AMapViewWrapper implements IMogoMapView, private boolean mIsFirstLocated = true; private boolean mIsDelayed = false; - // GPS 位置回调 - private final LocationListener mGpsLocationListener = - location -> CallerMapLocationListenerManager.INSTANCE.invokeMapLocationChangeListener(ObjectUtils.fromLocation(location), 0, true); - public AMapViewWrapper(MapAutoView mMapView) { CallerLogger.INSTANCE.i(M_MAP + TAG, "autoop--AMapViewWrapper: init"); this.mMapView = mMapView; @@ -189,7 +185,6 @@ public class AMapViewWrapper implements IMogoMapView, LocationClient client = mMapView.getLocationClient(); if (client != null) { client.registerListener(this); - client.registerGpsListener(mGpsLocationListener); } mMapView.registerListener(this, MapAutoApi.LISTENER_TYPE_ZOOM); mMapView.registerListener(this, MapAutoApi.LISTENER_TYPE_ROTATE); @@ -704,45 +699,12 @@ public class AMapViewWrapper implements IMogoMapView, CallerMapDevaListenerManager.INSTANCE.invokeUploadLogFile(filePath); } - // TODO 这里需要数据中心代理 -// private static class LocationTask implements Runnable { -// -// private MogoLocation location; -// -// public void setMoGoLocation(MogoLocation location) { -// this.location = location; -// } -// -// @Override -// public void run() { -// if (location != null) { -// CallerMapLocationListenerManager.INSTANCE.invokeMapLocationChangeListener(location, 1, false); -// location = null; -// } -// } -// } - -// private volatile LocationTask mLocationTask; - -// private final Handler mainHandler = new Handler(Looper.getMainLooper()); - @Override public void onLocationChanged(@NotNull com.zhidaoauto.map.sdk.open.location.MogoLocation location) { -// MogoLocation currentLocation = ObjectUtils.fromLocation(location); -// if (Looper.myLooper() == Looper.getMainLooper()) { -// CallerMapLocationListenerManager.INSTANCE.invokeMapLocationChangeListener(currentLocation, 1, false); -// } else { -// if (mLocationTask == null) { -// mLocationTask = new LocationTask(); -// } -// mLocationTask.setMoGoLocation(currentLocation); -// mainHandler.removeCallbacks(mLocationTask); -// mainHandler.post(mLocationTask); -// } - + CallerMapLocationListenerManager.INSTANCE.setCurrentLocation(ObjectUtils.fromLocation(location)); // 将有效经纬度暂存本地,提供给下一次的Http-DNS使用,防止首次请求位置获取不到 if (location.getLat() > 0 && location.getLon() > 0) { - if (location.getCityCode() != null && !location.getCityCode().isEmpty()) { + if (location.getCityCode() != null && !location.getCityCode().isEmpty()) { SharedPrefsMgr.getInstance(mMapView.getContext()) .putString(SharedPrefsConstants.LOCATION_CITY_CODE, location.getCityCode()); } @@ -752,20 +714,6 @@ public class AMapViewWrapper implements IMogoMapView, .putString(SharedPrefsConstants.LOCATION_LONGITUDE, String.valueOf(location.getLon())); } -// // 同步给各个模块 -// Location sysLocation = new Location(location.getProvider()); -// sysLocation.setAltitude(location.getAltitude()); -// sysLocation.setLatitude(location.getLat()); -// sysLocation.setLongitude(location.getLon()); -// sysLocation.setProvider(location.getProvider()); -// sysLocation.setAccuracy(location.getAcceleration()); -// sysLocation.setTime(location.duration); -// sysLocation.setBearing((float) location.getHeading()); -// sysLocation.setSpeed(location.getSpeed()); - -// if (MogoCarLocationChangedListenerRegister.getInstance().getListener() != null) { -// MogoCarLocationChangedListenerRegister.getInstance().getListener().onCarLocationChanged2(sysLocation); -// } if (checkAMapView() && mMapLoaded) { // 地图初始化完成后,每隔5s自动判断当前地图的模式 if (mIsFirstLocated) { From d46c11767da1080833e779a5da5c60c95cfd1a68 Mon Sep 17 00:00:00 2001 From: zhongchao Date: Mon, 30 Jan 2023 22:28:02 +0800 Subject: [PATCH 29/48] [2.13.0-arch-opt] merg --- OCH/mogo-och-bus-passenger/build.gradle | 12 +- .../main/res/layout/bus_p_base_fragment.xml | 22 +- OCH/mogo-och-bus/build.gradle | 13 - .../src/main/res/layout/bus_base_fragment.xml | 41 +- OCH/mogo-och-common-module/build.gradle | 22 +- .../java/com/mogo/och/noop/OchNoopFragment.kt | 18 +- .../main/res/layout/och_noop_fragment_hmi.xml | 13 +- OCH/mogo-och-sweeper/build.gradle | 13 - .../view/SweeperLimitingVelocityView.java | 33 - .../view/SweeperLimitingVelocityView.kt | 54 ++ .../sweeper/view/SweeperTrafficDataView.java | 17 +- .../main/res/layout/sweeper_base_fragment.xml | 51 ++ OCH/mogo-och-taxi-passenger/build.gradle | 12 +- .../passenger/model/TaxiPassengerModel.java | 10 +- .../main/res/layout/taxi_p_base_fragment.xml | 22 +- OCH/mogo-och-taxi/build.gradle | 12 +- .../main/res/layout/taxi_base_fragment.xml | 41 +- .../com/mogo/launcher/stageone/APMStartup.kt | 2 +- .../mogo/launcher/stageone/ConfigStartUp.kt | 8 - .../v2x/speedlimit/SpeedLimitDataManager.java | 6 +- .../v2x/speedlimit/SpeedLimitDispatcher.kt | 66 +- .../datacenter/obu/MogoObuDcCombineManager.kt | 9 +- .../obu/MogoPrivateObuNewManager.kt | 809 +++++++++--------- .../V2XLimitingVelocityBroadcastReceiver.kt | 10 +- .../core/function/hmi/ui/MoGoHmiFragment.kt | 114 +-- .../hmi/ui/setting/DebugSettingView.kt | 43 - .../function/hmi/ui/setting/SOPSettingView.kt | 4 +- .../function/hmi/ui/tools/ToolsImageView.kt | 16 +- .../hmi/ui/widget/AutoPilotStatusView.kt | 13 +- .../core/function/hmi/ui/widget/CameraView.kt | 15 +- .../hmi/ui/widget/LimitingVelocityView.kt | 54 +- .../hmi/ui/widget/PerspectiveSwitchView.kt | 17 +- .../function/hmi/ui/widget/SpeedPanelView.kt | 14 +- .../function/hmi/ui/widget/StatusBarView.kt | 2 + .../hmi/ui/widget/VipIdentificationView.kt | 20 +- .../src/main/res/layout/fragment_hmi.xml | 66 -- .../main/res/layout/view_debug_setting.xml | 48 -- .../res/layout/view_limiting_speed_vr.xml | 22 +- .../src/main/res/values/attr.xml | 5 - .../function/v2x/events/V2XEventManager.kt | 2 +- .../eagle/core/data/enums/DataSourceType.kt | 11 + .../eagle/core/data/msgbox/DataSourceType.kt | 9 - .../mogo/eagle/core/data/msgbox/MsgBoxBean.kt | 2 + .../function/api/hmi/IMoGoHmiViewProxy.kt | 8 - .../api/hmi/view/IViewControlListener.kt | 6 +- .../api/hmi/view/IViewLimitingVelocity.kt | 19 - .../api/hmi/warning/IMoGoHmiProvider.kt | 46 - .../api/v2x/ILimitingVelocityListener.kt | 10 + .../api/v2x/LimitingVelocityListener.kt | 8 - .../api/v2x/ObuLimitingSpeedListener.kt | 8 - .../function/call/hmi/CallerHmiManager.kt | 67 -- .../CallLimitingVelocityListenerManager.kt | 29 - .../CallObuLimitingSpeedListenerManager.kt | 26 - .../CallerLimitingVelocityListenerManager.kt | 28 + ...llerViewLimitingVelocityListenerManager.kt | 28 + 55 files changed, 895 insertions(+), 1181 deletions(-) delete mode 100644 OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperLimitingVelocityView.java create mode 100644 OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperLimitingVelocityView.kt create mode 100644 core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/DataSourceType.kt delete mode 100644 core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/DataSourceType.kt delete mode 100644 core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewLimitingVelocity.kt create mode 100644 core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/ILimitingVelocityListener.kt delete mode 100644 core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/LimitingVelocityListener.kt delete mode 100644 core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/ObuLimitingSpeedListener.kt delete mode 100644 core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallLimitingVelocityListenerManager.kt delete mode 100644 core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallObuLimitingSpeedListenerManager.kt create mode 100644 core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallerLimitingVelocityListenerManager.kt create mode 100644 core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallerViewLimitingVelocityListenerManager.kt diff --git a/OCH/mogo-och-bus-passenger/build.gradle b/OCH/mogo-och-bus-passenger/build.gradle index 0677d0aacd..8749b55ad1 100644 --- a/OCH/mogo-och-bus-passenger/build.gradle +++ b/OCH/mogo-och-bus-passenger/build.gradle @@ -53,18 +53,10 @@ dependencies { implementation rootProject.ext.dependencies.amapnavi3dmap implementation project(":OCH:mogo-och-common-module") if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { - implementation rootProject.ext.dependencies.mogoutils - implementation rootProject.ext.dependencies.mogocommons - implementation rootProject.ext.dependencies.mogo_core_data - implementation rootProject.ext.dependencies.mogo_core_function_call - implementation rootProject.ext.dependencies.mogo_core_function_hmi + implementation rootProject.ext.dependencies.mogo_core_function_v2x }else { implementation project(':foudations:mogo-aicloud-services-sdk') - implementation project(":foudations:mogo-commons") - implementation project(':core:mogo-core-data') - implementation project(":core:mogo-core-utils") - implementation project(':core:mogo-core-function-call') - implementation project(':core:function-impl:mogo-core-function-hmi') + implementation project(':core:function-impl:mogo-core-function-v2x') } } diff --git a/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_base_fragment.xml b/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_base_fragment.xml index 59714c2b32..564aa1e394 100644 --- a/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_base_fragment.xml +++ b/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_base_fragment.xml @@ -31,11 +31,29 @@ android:layout_width="@dimen/module_vip_width" android:layout_height="@dimen/module_vip_height" android:visibility="gone" - app:marginStart="@dimen/dp_640" - app:marginTop="@dimen/dp_80" + android:layout_marginStart="@dimen/dp_640" + android:layout_marginTop="@dimen/dp_80" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/> + + + + + + + android:layout_marginStart="@dimen/dp_640" + android:layout_marginTop="@dimen/dp_80"/> + + + + + + + + + + + + (), @@ -32,14 +26,6 @@ class OchNoopFragment : MvpFragment(), override fun initViews() { - //设置StatusBar初始状态 - CallerHmiViewControlListenerManager.updateStatusBarRightView( - StatusBarView.TAG, - FunctionBuildConfig.isDemoMode, - "demoMode", - DemoModeView(requireContext()) - ) - viewShowDebugView.setOnLongClickListener { ToggleDebugView.toggleDebugView.toggle(requireContext()) true @@ -51,7 +37,7 @@ class OchNoopFragment : MvpFragment(), viewDriverMsgBoxList.notifyData() viewDriverMsgBoxBubble.visibility = View.GONE viewDriverMsgBoxBubble.isShowData(false) - CallerHmiManager.updateDriverMsgBoxTipView(false) + MsgBoxTipView.visibility = View.GONE } else { viewDriverMsgBoxList.visibility = View.GONE viewDriverMsgBoxBubble.visibility = View.VISIBLE @@ -64,7 +50,7 @@ class OchNoopFragment : MvpFragment(), viewPassengerMsgBoxList.visibility = View.VISIBLE viewPassengerMsgBoxBubble.visibility = View.GONE viewPassengerMsgBoxBubble.isShowData(false) - CallerHmiManager.updatePassengerMsgBoxTipView(false) + MsgBoxTipView.visibility = View.GONE } else { viewPassengerMsgBoxList.visibility = View.GONE viewPassengerMsgBoxBubble.visibility = View.VISIBLE diff --git a/OCH/mogo-och-noop/src/main/res/layout/och_noop_fragment_hmi.xml b/OCH/mogo-och-noop/src/main/res/layout/och_noop_fragment_hmi.xml index 2638954937..fb1bec67f4 100644 --- a/OCH/mogo-och-noop/src/main/res/layout/och_noop_fragment_hmi.xml +++ b/OCH/mogo-och-noop/src/main/res/layout/och_noop_fragment_hmi.xml @@ -43,13 +43,14 @@ - - \ No newline at end of file diff --git a/OCH/mogo-och-sweeper/build.gradle b/OCH/mogo-och-sweeper/build.gradle index faa8d4934e..0a74593753 100644 --- a/OCH/mogo-och-sweeper/build.gradle +++ b/OCH/mogo-och-sweeper/build.gradle @@ -55,19 +55,6 @@ dependencies { implementation project(":OCH:mogo-och-common-module") implementation rootProject.ext.dependencies.androidxrecyclerview - if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { - implementation rootProject.ext.dependencies.mogoutils - implementation rootProject.ext.dependencies.mogocommons - implementation rootProject.ext.dependencies.mogo_core_data - implementation rootProject.ext.dependencies.mogo_core_function_call - implementation rootProject.ext.dependencies.mogo_core_function_hmi - }else { - implementation project(":core:mogo-core-utils") - implementation project(":foudations:mogo-commons") - implementation project(':core:mogo-core-data') - implementation project(':core:mogo-core-function-call') - implementation project(':core:function-impl:mogo-core-function-hmi') - } } apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() \ No newline at end of file diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperLimitingVelocityView.java b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperLimitingVelocityView.java deleted file mode 100644 index b8831bae9f..0000000000 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperLimitingVelocityView.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.mogo.och.sweeper.view; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.widget.TextView; - -import com.mogo.eagle.core.function.api.hmi.view.IViewLimitingVelocity; -import com.mogo.och.sweeper.R; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -public class SweeperLimitingVelocityView extends IViewLimitingVelocity { - private TextView limitingVelocity; - - public SweeperLimitingVelocityView(@Nullable Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - public SweeperLimitingVelocityView(@Nullable Context context, @Nullable AttributeSet attrs) { - this(context,attrs,0); - initView(context); - } - @Override - public void updateLimitingSpeed(int limitingSpeed, int limitSource) { - super.updateLimitingSpeed(limitingSpeed, limitSource); - limitingVelocity.setText(String.valueOf(limitingSpeed)); - } - private void initView(@NonNull Context context) { - LayoutInflater.from(context).inflate(R.layout.sweeper_limiting_speed, this); - limitingVelocity = findViewById(R.id.tvLimitingVelocity); - } -} diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperLimitingVelocityView.kt b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperLimitingVelocityView.kt new file mode 100644 index 0000000000..c4761b07e2 --- /dev/null +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperLimitingVelocityView.kt @@ -0,0 +1,54 @@ +package com.mogo.och.sweeper.view + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.widget.LinearLayout +import com.mogo.eagle.core.data.enums.DataSourceType +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.LimitingVelocityView_TAG +import com.mogo.eagle.core.function.api.v2x.ILimitingVelocityListener +import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager +import com.mogo.eagle.core.function.call.v2x.CallerViewLimitingVelocityListenerManager +import com.mogo.och.sweeper.R +import kotlinx.android.synthetic.main.sweeper_limiting_speed.view.* + +class SweeperLimitingVelocityView(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : + LinearLayout(context, attrs, defStyleAttr), ILimitingVelocityListener, IViewControlListener { + + companion object { + private const val TAG = "SweeperLimitingVelocityView" + } + + init { + LayoutInflater.from(context).inflate(R.layout.sweeper_limiting_speed, this) + } + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + CallerViewLimitingVelocityListenerManager.addListener(TAG, this) + CallerHmiViewControlListenerManager.addListener(LimitingVelocityView_TAG, this) + } + + override fun onLimitingVelocityChange(limitingVelocity: Int, sourceType: DataSourceType) { + if (limitingVelocity > 0) { + tvLimitingVelocity.visibility = View.VISIBLE + tvLimitingVelocity.text = "$limitingVelocity" + } else { + tvLimitingVelocity.visibility = View.GONE + } + } + + override fun visible(v: Int) { + super.visible(v) + tvLimitingVelocity.visibility = v + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + CallerViewLimitingVelocityListenerManager.removeListener(TAG) + CallerHmiViewControlListenerManager.removeListener(LimitingVelocityView_TAG) + } + +} \ No newline at end of file diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java index 11aaf92603..23cc010b44 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java @@ -10,15 +10,15 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.constraintlayout.widget.ConstraintLayout; +import com.mogo.eagle.core.data.enums.DataSourceType; import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisGearStateListener; import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLamplightListener; import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisSteeringStateListener; -import com.mogo.eagle.core.function.api.v2x.LimitingVelocityListener; -import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotVehicleStateListenerManager; +import com.mogo.eagle.core.function.api.v2x.ILimitingVelocityListener; import com.mogo.eagle.core.function.call.autopilot.CallerChassisGearStateListenerManager; import com.mogo.eagle.core.function.call.autopilot.CallerChassisLamplightListenerManager; import com.mogo.eagle.core.function.call.autopilot.CallerChassisSteeringStateListenerManager; -import com.mogo.eagle.core.function.call.v2x.CallLimitingVelocityListenerManager; +import com.mogo.eagle.core.function.call.v2x.CallerLimitingVelocityListenerManager; import com.mogo.eagle.core.function.hmi.ui.widget.TapPositionView; import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; import com.mogo.eagle.core.utilcode.util.ThreadUtils; @@ -26,9 +26,6 @@ import com.mogo.och.sweeper.R; import org.jetbrains.annotations.NotNull; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.constraintlayout.widget.ConstraintLayout; import chassis.Chassis; import chassis.VehicleStateOuterClass; @@ -75,7 +72,7 @@ public class SweeperTrafficDataView extends ConstraintLayout CallerChassisSteeringStateListenerManager.INSTANCE.addListener(TAG, this); CallerChassisGearStateListenerManager.INSTANCE.addListener(TAG, this); //增加限速监听 - CallLimitingVelocityListenerManager.INSTANCE.addListener(TAG,limitingVelocityListener); + CallerLimitingVelocityListenerManager.INSTANCE.addListener(TAG,limitingVelocityListener); } @Override @@ -85,7 +82,7 @@ public class SweeperTrafficDataView extends ConstraintLayout CallerChassisLamplightListenerManager.INSTANCE.removeListener(TAG); CallerChassisSteeringStateListenerManager.INSTANCE.removeListener(TAG); CallerChassisGearStateListenerManager.INSTANCE.removeListener(TAG); - CallLimitingVelocityListenerManager.INSTANCE.removeListener(limitingVelocityListener); + CallerLimitingVelocityListenerManager.INSTANCE.removeListener(limitingVelocityListener); } /** @@ -146,10 +143,10 @@ public class SweeperTrafficDataView extends ConstraintLayout /** * 限速监听 */ - private final LimitingVelocityListener limitingVelocityListener = new LimitingVelocityListener(){ + private final ILimitingVelocityListener limitingVelocityListener = new ILimitingVelocityListener(){ @Override - public void onLimitingVelocityChange(int limitingVelocity) { + public void onLimitingVelocityChange(int limitingVelocity, DataSourceType sourceType) { //设置限速 sweeperLimitingVelocity.updateLimitingSpeed(limitingVelocity, 0); } diff --git a/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_base_fragment.xml b/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_base_fragment.xml index aa7a2a60ad..c4c85c96b3 100644 --- a/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_base_fragment.xml +++ b/OCH/mogo-och-sweeper/src/main/res/layout/sweeper_base_fragment.xml @@ -21,6 +21,57 @@ android:layout_height="match_parent" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + () { } override fun dependenciesByName(): List { - return listOf("com.mogo.launcher.stageone.ARouterStartUp", "com.mogo.launcher.stageone.ThreadOptStartup") + return listOf("com.mogo.launcher.stageone.ARouterStartUp","com.mogo.launcher.stageone.ConfigStartUp") } } \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt b/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt index 2350e3440c..82ac67ce34 100644 --- a/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt +++ b/app/src/main/java/com/mogo/launcher/stageone/ConfigStartUp.kt @@ -105,13 +105,8 @@ class ConfigStartUp : AndroidStartup() { if (AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) { if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) { - //是否显示 限速UI - HmiBuildConfig.isShowLimitingVelocityView = false //白天模式 FunctionBuildConfig.skinMode = 1 - } else if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) { - //是否显示 限速UI - HmiBuildConfig.isShowLimitingVelocityView = false } } @@ -154,7 +149,4 @@ class ConfigStartUp : AndroidStartup() { } - override fun dependenciesByName(): List { - return listOf("com.mogo.launcher.stageone.ThreadOptStartup") - } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDataManager.java b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDataManager.java index c3e3ffedb3..385cfb841e 100644 --- a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDataManager.java +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDataManager.java @@ -1,6 +1,5 @@ package com.mogo.eagle.function.biz.v2x.speedlimit; -import static com.mogo.eagle.core.data.config.HmiBuildConfig.isShowObuLimitSpeedView; import static com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.BIZ_SLW; import static com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.V2I; @@ -8,9 +7,8 @@ import androidx.annotation.Nullable; import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener; import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ20ListenerManager; -import com.mogo.eagle.core.function.call.hmi.CallerHmiManager; import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager; -import com.mogo.eagle.core.function.call.v2x.CallLimitingVelocityListenerManager; +import com.mogo.eagle.core.function.call.v2x.CallerLimitingVelocityListenerManager; import com.mogo.eagle.core.utilcode.util.UiThreadHandler; import com.zhjt.service_biz.BizConfig; @@ -66,7 +64,7 @@ public class SpeedLimitDataManager implements IMoGoChassisLocationGCJ02Listener UiThreadHandler.post(() -> { if (speedLimit > 0) { // CallerHmiManager.INSTANCE.showLimitingVelocity(speedLimit, 1); - CallLimitingVelocityListenerManager.INSTANCE.invokeOnLimitingVelocityChange(speedLimit); + CallerLimitingVelocityListenerManager.INSTANCE.invokeOnLimitingVelocityChange(speedLimit); } }); diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDispatcher.kt b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDispatcher.kt index c236c2ed0e..47e491ac75 100644 --- a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDispatcher.kt +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDispatcher.kt @@ -1,20 +1,19 @@ package com.mogo.eagle.function.biz.v2x.speedlimit import android.content.Context -import com.mogo.eagle.core.function.api.v2x.LimitingVelocityListener -import com.mogo.eagle.core.function.api.v2x.ObuLimitingSpeedListener -import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager -import com.mogo.eagle.core.function.call.hmi.CallerHmiManager -import com.mogo.eagle.core.function.call.trafficlight.CallerTrafficLightListenerManager -import com.mogo.eagle.core.function.call.v2x.CallLimitingVelocityListenerManager -import com.mogo.eagle.core.function.call.v2x.CallObuLimitingSpeedListenerManager +import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig +import com.mogo.eagle.core.data.enums.DataSourceType +import com.mogo.eagle.core.function.api.v2x.ILimitingVelocityListener +import com.mogo.eagle.core.function.call.v2x.CallerLimitingVelocityListenerManager +import com.mogo.eagle.core.function.call.v2x.CallerViewLimitingVelocityListenerManager +import com.zhjt.service_biz.BizConfig /** * @author lixiaopeng * @description 对多个限速进行调度(map,rsu ...) * @since: 2023/1/12 */ -class SpeedLimitDispatcher : LimitingVelocityListener, ObuLimitingSpeedListener { +class SpeedLimitDispatcher : ILimitingVelocityListener { companion object { const val TAG = "SpeedLimitDispatcher" val INSTANCE: SpeedLimitDispatcher by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { @@ -24,47 +23,42 @@ class SpeedLimitDispatcher : LimitingVelocityListener, ObuLimitingSpeedListener private var mContext: Context? = null - //是否有AI获取红绿灯灯态 + //obu限速状态 private var hasObuStatus: Boolean = false - fun initLimit(context: Context) { mContext = context - //注册监听MAP的限速 - CallLimitingVelocityListenerManager.addListener(TAG, this) - //注册监听OBU的限速 - CallObuLimitingSpeedListenerManager.addListener(TAG, this) + CallerLimitingVelocityListenerManager.addListener(TAG, this) } /** * 地图限速数据 */ - override fun onLimitingVelocityChange(limitingVelocity: Int) { -// CallerHmiManager.disableLimitingVelocity() - if (!hasObuStatus) { - CallerHmiManager.showLimitingVelocity(limitingVelocity, 1) - } - } - - /** - * obu限速 - */ - override fun onObuLimitingSpeedChange(limitingSpeed: Int) { -// CallerHmiManager.disableLimitingVelocity() - if (limitingSpeed > 0) { - hasObuStatus = true - CallerHmiManager.showLimitingVelocity(limitingSpeed, 2) - } else { - hasObuStatus = false - CallerHmiManager.disableLimitingVelocity() + @BizConfig(FuncBizConfig.V2I, "", FuncBizConfig.BIZ_SLW) + override fun onLimitingVelocityChange(limitingVelocity: Int, sourceType: DataSourceType) { + when (sourceType) { // obu 优先级高于 map,体现链路能力 + DataSourceType.OBU -> { + hasObuStatus = limitingVelocity > 0 + CallerViewLimitingVelocityListenerManager.invokeOnLimitingVelocityChange( + limitingVelocity, + sourceType + ) + return + } + DataSourceType.MAP -> { + if (!hasObuStatus) { + CallerViewLimitingVelocityListenerManager.invokeOnLimitingVelocityChange( + limitingVelocity, + sourceType + ) + } + } + else -> {} } } fun destroy() { - //取消注册监听AI云获取红绿灯状态 - CallerTrafficLightListenerManager.removeListener(TAG) - //取消注册监听工控机感知红绿灯 - CallerAutopilotIdentifyListenerManager.removeListener(TAG) + CallerLimitingVelocityListenerManager.removeListener(TAG) } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoObuDcCombineManager.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoObuDcCombineManager.kt index 8950dd989b..27b38679d6 100644 --- a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoObuDcCombineManager.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoObuDcCombineManager.kt @@ -4,7 +4,7 @@ import android.content.Context import com.mogo.eagle.core.data.config.HmiBuildConfig import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.data.enums.WarningDirectionEnum -import com.mogo.eagle.core.data.msgbox.DataSourceType +import com.mogo.eagle.core.data.enums.DataSourceType import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.V2XMsg @@ -14,11 +14,13 @@ import com.mogo.eagle.core.function.call.hmi.CallerHmiManager import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager import com.mogo.eagle.core.function.call.obucombine.CallerObuDcCombineListenerManager +import com.mogo.eagle.core.function.call.v2x.CallerLimitingVelocityListenerManager import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU import com.mogo.support.obu.constants.MogoObuConstants import mogo.v2x.ObuWarningEvent import mogo.v2x.ObuWarningEvent.* +import kotlin.math.roundToInt /** @@ -441,14 +443,15 @@ class MogoObuDcCombineManager private constructor() : IMoGoObuDcCombineListener "MogoObuDcCombineManager onMogoObuMapMath = ${data.status} --speedMaxLimit = ${Math.round((data.speedMaxLimit*0.02*3.6))} --- data.speedMaxLimit = ${data.speedMaxLimit}") when (data.status) { MogoObuConstants.STATUS.ADD -> { // 添加 TODO - CallerHmiManager.showLimitingVelocity(Math.round((data.speedMaxLimit*0.02*3.6)).toInt(), 2) + CallerLimitingVelocityListenerManager.invokeOnLimitingVelocityChange( + (data.speedMaxLimit * 0.02 * 3.6).roundToInt().toInt(),DataSourceType.OBU) } MogoObuConstants.STATUS.UPDATE -> { // 更新 } MogoObuConstants.STATUS.DELETE -> { // 删除 - CallerHmiManager.disableLimitingVelocity() + CallerLimitingVelocityListenerManager.invokeOnLimitingVelocityChange(-1 ,DataSourceType.OBU) } } } diff --git a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuNewManager.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuNewManager.kt index ed185ab548..c06aacde0b 100644 --- a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuNewManager.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuNewManager.kt @@ -4,7 +4,6 @@ import android.content.Context import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.data.config.HmiBuildConfig import com.mogo.eagle.core.data.enums.* -import com.mogo.eagle.core.data.msgbox.DataSourceType import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.V2XMsg @@ -18,8 +17,8 @@ import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.Scene.TooC import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager import com.mogo.eagle.core.function.call.obu.CallerObuListenerManager import com.mogo.eagle.core.function.call.obu.CallerObuTrafficLightListenerManager -import com.mogo.eagle.core.function.call.v2x.CallObuLimitingSpeedListenerManager -import com.mogo.eagle.core.function.datacenter.obu.utils.TrafficDataConvertUtilsNew +import com.mogo.eagle.core.function.call.v2x.CallerLimitingVelocityListenerManager +import com.mogo.eagle.core.function.obu.mogo.utils.TrafficDataConvertUtilsNew import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr @@ -34,6 +33,7 @@ import com.mogo.support.obu.model.advance.SpatLight import com.mogo.support.obu.option.MogoObuCom import com.mogo.support.obu.option.MogoObuOptions import org.json.JSONObject +import kotlin.math.roundToInt /** * @@ -510,7 +510,9 @@ class MogoPrivateObuNewManager private constructor() { //物体数据绘制 CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", "onMogoObuRsmWarning ---- data.status = ${data.status} ---data.participant.ptcId = ${data.participant.ptcId} ---data.participant.ptcType = ${data.participant.ptcType} ---data.warningMsg = ${data.warningMsg} -----data = ${data.toString()}") + "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", + "onMogoObuRsmWarning ---- data.status = ${data.status} ---data.participant.ptcId = ${data.participant.ptcId} ---data.participant.ptcType = ${data.participant.ptcType} ---data.warningMsg = ${data.warningMsg} -----data = ${data.toString()}" + ) when (data.status) { MogoObuConstants.STATUS.ADD -> { // 添加 // 更新数据,模型变色的时候是不是update,如果不是更新,可能导致模型不变色,(add的时候,是否有level高的) TODO @@ -550,7 +552,7 @@ class MogoPrivateObuNewManager private constructor() { //删除弱势交通元素 CallerMapUIServiceManager.getMarkerService() ?.removeCvxRvInfoIndInfo(data.participant.ptcId.toString()) - } + } } //预警status @@ -627,347 +629,421 @@ class MogoPrivateObuNewManager private constructor() { */ override fun onMogoObuMapMath(data: MogoObuMapMathData?) { super.onMogoObuMapMath(data) -// if (isShowObuLimitSpeedView) { - if (data != null) { - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "onMogoObuMapMath = ${data.status} --speedMaxLimit = ${Math.round((data.speedMaxLimit * 3.6))}" - ) - when (data.status) { - MogoObuConstants.STATUS.ADD -> { // 添加 - UiThreadHandler.post { - if (data.speedMaxLimit > 0) { -// CallerHmiManager.showLimitingVelocity( -// Math.round((data.speedMaxLimit * 3.6)).toInt(), 2) - CallObuLimitingSpeedListenerManager.invokeOnObuLimitingSpeedChange(Math.round((data.speedMaxLimit * 3.6)).toInt()) - } - } - } - - MogoObuConstants.STATUS.UPDATE -> { // 更新 - } - - MogoObuConstants.STATUS.DELETE -> { // 删除 - UiThreadHandler.post { -// CallerHmiManager.disableLimitingVelocity() - CallObuLimitingSpeedListenerManager.invokeOnObuLimitingSpeedChange(-1) + if (data != null) { + CallerLogger.d( + "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", + "onMogoObuMapMath = ${data.status} --speedMaxLimit = ${(data.speedMaxLimit * 3.6).roundToInt()}" + ) + when (data.status) { + MogoObuConstants.STATUS.ADD -> { // 添加 + UiThreadHandler.post { + if (data.speedMaxLimit > 0) { + CallerLimitingVelocityListenerManager.invokeOnLimitingVelocityChange( + (data.speedMaxLimit * 3.6).roundToInt(), DataSourceType.OBU + ) } } } + + MogoObuConstants.STATUS.UPDATE -> { // 更新 + } + + MogoObuConstants.STATUS.DELETE -> { // 删除 + UiThreadHandler.post { + CallerLimitingVelocityListenerManager.invokeOnLimitingVelocityChange(-1,DataSourceType.OBU) + } + } } -// } + } } } } - /** - * 获取消息的方位 车辆相关 - */ - private fun getMessageDirection(targetClassification: Int): WarningDirectionEnum { +/** + * 获取消息的方位 车辆相关 + */ +private fun getMessageDirection(targetClassification: Int): WarningDirectionEnum { // CallerLogger.d("$M_OBU${TAG_MOGO_NEW_OBU}", "预警红边:预警方向->$targetClassification") - return when (targetClassification) { - MogoObuConstants.VEH_TARGET_POSITION.AHEAD_IN_LANE, - MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_IN_LANE -> WarningDirectionEnum.ALERT_WARNING_TOP //正前方 + return when (targetClassification) { + MogoObuConstants.VEH_TARGET_POSITION.AHEAD_IN_LANE, + MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_IN_LANE -> WarningDirectionEnum.ALERT_WARNING_TOP //正前方 - MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_IN_LANE -> WarningDirectionEnum.ALERT_WARNING_BOTTOM //正后方 + MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_IN_LANE -> WarningDirectionEnum.ALERT_WARNING_BOTTOM //正后方 - MogoObuConstants.VEH_TARGET_POSITION.INTERSECTION_RIGHT -> WarningDirectionEnum.ALERT_WARNING_RIGHT //正右方 + MogoObuConstants.VEH_TARGET_POSITION.INTERSECTION_RIGHT -> WarningDirectionEnum.ALERT_WARNING_RIGHT //正右方 - MogoObuConstants.VEH_TARGET_POSITION.INTERSECTION_LEFT -> WarningDirectionEnum.ALERT_WARNING_LEFT //正左方 + MogoObuConstants.VEH_TARGET_POSITION.INTERSECTION_LEFT -> WarningDirectionEnum.ALERT_WARNING_LEFT //正左方 - MogoObuConstants.VEH_TARGET_POSITION.AHEAD_LEFT, MogoObuConstants.VEH_TARGET_POSITION.AHEAD_FAR_LEFT, - MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_LEFT, MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_FAR_LEFT - -> WarningDirectionEnum.ALERT_WARNING_TOP_LEFT //左前方 + MogoObuConstants.VEH_TARGET_POSITION.AHEAD_LEFT, MogoObuConstants.VEH_TARGET_POSITION.AHEAD_FAR_LEFT, + MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_LEFT, MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_FAR_LEFT + -> WarningDirectionEnum.ALERT_WARNING_TOP_LEFT //左前方 - MogoObuConstants.VEH_TARGET_POSITION.AHEAD_RIGHT, MogoObuConstants.VEH_TARGET_POSITION.AHEAD_FAR_RIGHT, - MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_RIGHT, MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_FAT_RIGHT - -> WarningDirectionEnum.ALERT_WARNING_TOP_RIGHT //右前方 + MogoObuConstants.VEH_TARGET_POSITION.AHEAD_RIGHT, MogoObuConstants.VEH_TARGET_POSITION.AHEAD_FAR_RIGHT, + MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_RIGHT, MogoObuConstants.VEH_TARGET_POSITION.ONCOMING_FAT_RIGHT + -> WarningDirectionEnum.ALERT_WARNING_TOP_RIGHT //右前方 - MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_LEFT, MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_FAR_LEFT, - -> WarningDirectionEnum.ALERT_WARNING_BOTTOM_LEFT //左后方 + MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_LEFT, MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_FAR_LEFT, + -> WarningDirectionEnum.ALERT_WARNING_BOTTOM_LEFT //左后方 - MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_RIGHT, MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_FAR_RIGHT, - -> WarningDirectionEnum.ALERT_WARNING_BOTTOM_RIGHT //右后方 + MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_RIGHT, MogoObuConstants.VEH_TARGET_POSITION.BEHEAD_FAR_RIGHT, + -> WarningDirectionEnum.ALERT_WARNING_BOTTOM_RIGHT //右后方 - MogoObuConstants.VEH_TARGET_POSITION.UNCLASSIFIED -> WarningDirectionEnum.ALERT_WARNING_NON //未知 - else -> WarningDirectionEnum.ALERT_WARNING_ALL - } + MogoObuConstants.VEH_TARGET_POSITION.UNCLASSIFIED -> WarningDirectionEnum.ALERT_WARNING_NON //未知 + else -> WarningDirectionEnum.ALERT_WARNING_ALL } +} - /** - * 构造对应展示数据和场景 根据obu的场景,add change delete确定是否展示 - * - * @param appId 使用WarningTypeEnum获取icon、提示内容、tts内容 TODO 添加事件频繁播报拦截 - * - * @see com.mogo.module.common.enums.EventTypeEnum - */ - private fun handleSdkObu( - appId: String, - direction: WarningDirectionEnum, - status: Int, - level: Int, - info: MogoObuRvWarningData - ) { - // 这里排除需要特殊定制的语音及文案外,其余的都可以使用 EventTypeEnumNew 提供的 - var alertContent: String = "" - var ttsContent: String = "" - var changeVisualAngle = false - when (appId) { - //交叉路口碰撞预警 - MogoObuConstants.V2X_WARNING_TYPE.FCW.toString() -> { - alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_FCW.poiType) - ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_FCW.poiType) - } +/** + * 构造对应展示数据和场景 根据obu的场景,add change delete确定是否展示 + * + * @param appId 使用WarningTypeEnum获取icon、提示内容、tts内容 TODO 添加事件频繁播报拦截 + * + * @see com.mogo.module.common.enums.EventTypeEnum + */ +private fun handleSdkObu( + appId: String, + direction: WarningDirectionEnum, + status: Int, + level: Int, + info: MogoObuRvWarningData +) { + // 这里排除需要特殊定制的语音及文案外,其余的都可以使用 EventTypeEnumNew 提供的 + var alertContent: String = "" + var ttsContent: String = "" + var changeVisualAngle = false + when (appId) { + //交叉路口碰撞预警 + MogoObuConstants.V2X_WARNING_TYPE.FCW.toString() -> { + alertContent = + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_FCW.poiType) + ttsContent = + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_FCW.poiType) + } - //交叉路口碰撞预警 - MogoObuConstants.V2X_WARNING_TYPE.ICW.toString() -> { - alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_ICW.poiType) - ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_ICW.poiType) - } + //交叉路口碰撞预警 + MogoObuConstants.V2X_WARNING_TYPE.ICW.toString() -> { + alertContent = + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_ICW.poiType) + ttsContent = + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_ICW.poiType) + } - //左转辅助预警 - MogoObuConstants.V2X_WARNING_TYPE.LTA.toString() -> { - alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_LTA.poiType) - ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_LTA.poiType) - } + //左转辅助预警 + MogoObuConstants.V2X_WARNING_TYPE.LTA.toString() -> { + alertContent = + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_LTA.poiType) + ttsContent = + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_LTA.poiType) + } - //盲区预警 - MogoObuConstants.V2X_WARNING_TYPE.BSW.toString() -> { - ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_BSW.poiType) - alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_BSW.poiType) - if ( - direction == WarningDirectionEnum.ALERT_WARNING_LEFT || - direction == WarningDirectionEnum.ALERT_WARNING_TOP_LEFT || - direction == WarningDirectionEnum.ALERT_WARNING_BOTTOM_LEFT - ) { //左后 - changeVisualAngle = true - ttsContent = String.format(ttsContent, "左") - alertContent = String.format(alertContent, "左") - } else if ( - direction == WarningDirectionEnum.ALERT_WARNING_RIGHT || - direction == WarningDirectionEnum.ALERT_WARNING_TOP_RIGHT || - direction == WarningDirectionEnum.ALERT_WARNING_BOTTOM_RIGHT - ) { //右后 - changeVisualAngle = true - ttsContent = String.format(ttsContent, "右") - alertContent = String.format(alertContent, "右") - } + //盲区预警 + MogoObuConstants.V2X_WARNING_TYPE.BSW.toString() -> { + ttsContent = + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_BSW.poiType) + alertContent = + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_BSW.poiType) + if ( + direction == WarningDirectionEnum.ALERT_WARNING_LEFT || + direction == WarningDirectionEnum.ALERT_WARNING_TOP_LEFT || + direction == WarningDirectionEnum.ALERT_WARNING_BOTTOM_LEFT + ) { //左后 + changeVisualAngle = true + ttsContent = String.format(ttsContent, "左") + alertContent = String.format(alertContent, "左") + } else if ( + direction == WarningDirectionEnum.ALERT_WARNING_RIGHT || + direction == WarningDirectionEnum.ALERT_WARNING_TOP_RIGHT || + direction == WarningDirectionEnum.ALERT_WARNING_BOTTOM_RIGHT + ) { //右后 + changeVisualAngle = true + ttsContent = String.format(ttsContent, "右") + alertContent = String.format(alertContent, "右") } + } - // 变道预警,注意左后车辆/注意右后车辆 - MogoObuConstants.V2X_WARNING_TYPE.LCW.toString() -> { - alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_LCW.poiType) - ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_LCW.poiType) - if ( - direction == WarningDirectionEnum.ALERT_WARNING_LEFT || - direction == WarningDirectionEnum.ALERT_WARNING_TOP_LEFT || - direction == WarningDirectionEnum.ALERT_WARNING_BOTTOM_LEFT - ) { - ttsContent = String.format(ttsContent, "左") - alertContent = String.format(alertContent, "左") - } else if ( - direction == WarningDirectionEnum.ALERT_WARNING_RIGHT || - direction == WarningDirectionEnum.ALERT_WARNING_TOP_RIGHT || - direction == WarningDirectionEnum.ALERT_WARNING_BOTTOM_RIGHT - ) { - ttsContent = String.format(ttsContent, "右") - alertContent = String.format(alertContent, "右") - } + // 变道预警,注意左后车辆/注意右后车辆 + MogoObuConstants.V2X_WARNING_TYPE.LCW.toString() -> { + alertContent = + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_LCW.poiType) + ttsContent = + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_LCW.poiType) + if ( + direction == WarningDirectionEnum.ALERT_WARNING_LEFT || + direction == WarningDirectionEnum.ALERT_WARNING_TOP_LEFT || + direction == WarningDirectionEnum.ALERT_WARNING_BOTTOM_LEFT + ) { + ttsContent = String.format(ttsContent, "左") + alertContent = String.format(alertContent, "左") + } else if ( + direction == WarningDirectionEnum.ALERT_WARNING_RIGHT || + direction == WarningDirectionEnum.ALERT_WARNING_TOP_RIGHT || + direction == WarningDirectionEnum.ALERT_WARNING_BOTTOM_RIGHT + ) { + ttsContent = String.format(ttsContent, "右") + alertContent = String.format(alertContent, "右") } + } - //逆向超车预警 - MogoObuConstants.V2X_WARNING_TYPE.DNPW.toString() -> { - alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_DNPW.poiType) - ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_DNPW.poiType) - } + //逆向超车预警 + MogoObuConstants.V2X_WARNING_TYPE.DNPW.toString() -> { + alertContent = + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_DNPW.poiType) + ttsContent = + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_DNPW.poiType) + } - //紧急制动预警 - MogoObuConstants.V2X_WARNING_TYPE.EBW.toString() -> { - alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_EBW.poiType) - ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_EBW.poiType) - } + //紧急制动预警 + MogoObuConstants.V2X_WARNING_TYPE.EBW.toString() -> { + alertContent = + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_EBW.poiType) + ttsContent = + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_EBW.poiType) + } - //异常车辆提醒 - MogoObuConstants.V2X_WARNING_TYPE.AVW.toString() -> { - alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_AVW.poiType) - ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_AVW.poiType) - alertContent = String.format(alertContent, direction.desc) - ttsContent = String.format(ttsContent, direction.desc) - } + //异常车辆提醒 + MogoObuConstants.V2X_WARNING_TYPE.AVW.toString() -> { + alertContent = + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_AVW.poiType) + ttsContent = + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_AVW.poiType) + alertContent = String.format(alertContent, direction.desc) + ttsContent = String.format(ttsContent, direction.desc) + } - //车辆失控预警 - MogoObuConstants.V2X_WARNING_TYPE.CLW.toString() -> { - alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_CLW.poiType) - ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_CLW.poiType) - alertContent = String.format(alertContent, direction.desc) - ttsContent = String.format(ttsContent, direction.desc) - } - //车辆失控预警 - MogoObuConstants.V2X_WARNING_TYPE.EVW.toString() -> { - alertContent = EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_EVW.poiType) - ttsContent = EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_EVW.poiType) - } + //车辆失控预警 + MogoObuConstants.V2X_WARNING_TYPE.CLW.toString() -> { + alertContent = + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_CLW.poiType) + ttsContent = + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_CLW.poiType) + alertContent = String.format(alertContent, direction.desc) + ttsContent = String.format(ttsContent, direction.desc) + } + //车辆失控预警 + MogoObuConstants.V2X_WARNING_TYPE.EVW.toString() -> { + alertContent = + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_EVW.poiType) + ttsContent = + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_EVW.poiType) + } - // 这里处理固定的提示信息,包括了<紧急车辆提醒> - else -> { //TODO + // 这里处理固定的提示信息,包括了<紧急车辆提醒> + else -> { //TODO // ttsContent = EventTypeEnumNew.getWarningTts(appId.toString()) // alertContent = EventTypeEnumNew.getWarningContent(appId.toString()) - } - } - - when (status) { - // 添加,更新 add的时候,可能级别是2, - MogoObuConstants.STATUS.ADD, - MogoObuConstants.STATUS.UPDATE -> { - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "new handleSdkObu appId2 = $appId --- level = $level ---ttsContent = $ttsContent --- alertContent = $alertContent --- direction = $direction" - ) - if (level == 2 || level == 3) { - //不显示弹框,其它保留 - CallerMsgBoxManager.saveMsgBox( - MsgBoxBean( - MsgBoxType.V2X, - V2XMsg( - appId, - alertContent, - ttsContent - ) - ).apply { - sourceType = DataSourceType.OBU - } - ) - CallerHmiManager.warningV2X( - appId, - alertContent, - ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 - (appId + direction.direction),//使用当前事件类型+方向记录tag,当发生变化的时候关闭当前弹出新的 - object : IMoGoWarningStatusListener { - override fun onShow() { - super.onShow() - if (changeVisualAngle) { - CallerVisualAngleManager.changeVisualAngle(TooClose) - } - } - - override fun onDismiss() { - // 关闭警告红边 - CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) - if (changeVisualAngle) { - CallerVisualAngleManager.changeVisualAngle(Default()) - } - } - }, - true, - 5000L - ) - //显示警告红边 - CallerHmiManager.showWarning(direction) - } - //更新周边车辆进行预警颜色变换,车辆实时移动和变色 ,UUID不需要匹配了 - TrafficDataConvertUtilsNew.cvxV2vThreatIndInfo2TrafficData(info)?.let { - CallerMapUIServiceManager.getMarkerService() - ?.updateITrafficThreatLevelInfo(it) - } - } - // 删除 - MogoObuConstants.STATUS.DELETE -> { - // 关闭警告红边 - CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) - // 移除顶部弹窗 - // CallerHmiManager.disableWarningV2X((appId + direction.direction)) - //更新周边车辆进行预警颜色变换,车辆实时移动和变色 - TrafficDataConvertUtilsNew.cvxV2vThreatIndInfo2TrafficData(info)?.let { - it.threatLevel = 0x01 - CallerMapUIServiceManager.getMarkerService() - ?.updateITrafficThreatLevelInfo(it) - } - } } } - /** - * 处理红绿灯 - */ - private fun handlerTrafficLight(appId: Int, status: Int, lights: List) { - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "handlerTrafficLight --- status = $status ---lights.size = ${lights.size} ---lights = $lights ---appId = $appId" - ) - when (status) { - // 添加 - MogoObuConstants.STATUS.ADD, - MogoObuConstants.STATUS.UPDATE - -> { - if (lights != null && lights.isNotEmpty()) { - changeTrafficLightStatus(appId, lights) - } + when (status) { + // 添加,更新 add的时候,可能级别是2, + MogoObuConstants.STATUS.ADD, + MogoObuConstants.STATUS.UPDATE -> { + CallerLogger.d( + "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", + "new handleSdkObu appId2 = $appId --- level = $level ---ttsContent = $ttsContent --- alertContent = $alertContent --- direction = $direction" + ) + if (level == 2 || level == 3) { + //不显示弹框,其它保留 + CallerMsgBoxManager.saveMsgBox( + MsgBoxBean( + MsgBoxType.V2X, + V2XMsg( + appId, + alertContent, + ttsContent + ) + ).apply { + sourceType = DataSourceType.OBU + } + ) + CallerHmiManager.warningV2X( + appId, + alertContent, + ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 + (appId + direction.direction),//使用当前事件类型+方向记录tag,当发生变化的时候关闭当前弹出新的 + object : IMoGoWarningStatusListener { + override fun onShow() { + super.onShow() + if (changeVisualAngle) { + CallerVisualAngleManager.changeVisualAngle(TooClose) + } + } + + override fun onDismiss() { + // 关闭警告红边 + CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) + if (changeVisualAngle) { + CallerVisualAngleManager.changeVisualAngle(Default()) + } + } + }, + true, + 5000L + ) + //显示警告红边 + CallerHmiManager.showWarning(direction) } - // 删除 - MogoObuConstants.STATUS.DELETE -> { - // 移除顶部弹窗 - CallerHmiManager.disableWarningTrafficLight() - CallerHmiManager.disableWarningV2X(appId.toString()) - isShowGreenWave = false - isShowRunRedLight = false - isYellowLight = false + //更新周边车辆进行预警颜色变换,车辆实时移动和变色 ,UUID不需要匹配了 + TrafficDataConvertUtilsNew.cvxV2vThreatIndInfo2TrafficData(info)?.let { + CallerMapUIServiceManager.getMarkerService() + ?.updateITrafficThreatLevelInfo(it) + } + } + // 删除 + MogoObuConstants.STATUS.DELETE -> { + // 关闭警告红边 + CallerHmiManager.showWarning(WarningDirectionEnum.ALERT_WARNING_NON) + // 移除顶部弹窗 + // CallerHmiManager.disableWarningV2X((appId + direction.direction)) + //更新周边车辆进行预警颜色变换,车辆实时移动和变色 + TrafficDataConvertUtilsNew.cvxV2vThreatIndInfo2TrafficData(info)?.let { + it.threatLevel = 0x01 + CallerMapUIServiceManager.getMarkerService() + ?.updateITrafficThreatLevelInfo(it) + } + } + } +} + +/** + * 处理红绿灯 + */ +private fun handlerTrafficLight(appId: Int, status: Int, lights: List) { + CallerLogger.d( + "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", + "handlerTrafficLight --- status = $status ---lights.size = ${lights.size} ---lights = $lights ---appId = $appId" + ) + when (status) { + // 添加 + MogoObuConstants.STATUS.ADD, + MogoObuConstants.STATUS.UPDATE + -> { + if (lights != null && lights.isNotEmpty()) { + changeTrafficLightStatus(appId, lights) + } + } + // 删除 + MogoObuConstants.STATUS.DELETE -> { + // 移除顶部弹窗 + CallerHmiManager.disableWarningTrafficLight() + CallerHmiManager.disableWarningV2X(appId.toString()) + isShowGreenWave = false + isShowRunRedLight = false + isYellowLight = false // lightCountDownRed = 1 // lightCountDownGreen = 1 // lightCountDownYellow = 1 - } } } +} - private var isRedLight = false - private var isGreenLight = false - private var isYellowLight = false - private var isShowGreenWave = false - private var isShowRunRedLight = false +private var isRedLight = false +private var isGreenLight = false +private var isYellowLight = false +private var isShowGreenWave = false +private var isShowRunRedLight = false // private var lightCountDownRed : Int = 1 // private var lightCountDownGreen : Int = 1 // private var lightCountDownYellow : Int = 1 - /** - * 修改红绿灯 - */ - @Synchronized - private fun changeTrafficLightStatus( - appId: Int, - lights: List - ) { - var ttsContent = "" - var alertContent = "" - //这里需要根据真实数据确定 index 取值方式 - val currentLight = lights[0] - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "changeTrafficLightStatus currentLight = $currentLight ----currentLight.light = ${currentLight.light} ---currentLight.phase = ${currentLight.phaseId} ---appId = $appId --countDown = ${currentLight.countDown.toInt()}" - ) - // 闯红灯预警,绿波通行和闯红灯是互斥的 - when (appId) { - 0 -> {//不可用 V2I_RLVW_VIOLATION_TYPE_UNAVAILABLE 无效 +/** + * 修改红绿灯 + */ +@Synchronized +private fun changeTrafficLightStatus( + appId: Int, + lights: List +) { + var ttsContent = "" + var alertContent = "" + //这里需要根据真实数据确定 index 取值方式 + val currentLight = lights[0] + CallerLogger.d( + "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", + "changeTrafficLightStatus currentLight = $currentLight ----currentLight.light = ${currentLight.light} ---currentLight.phase = ${currentLight.phaseId} ---appId = $appId --countDown = ${currentLight.countDown.toInt()}" + ) + // 闯红灯预警,绿波通行和闯红灯是互斥的 + when (appId) { + 0 -> {//不可用 V2I_RLVW_VIOLATION_TYPE_UNAVAILABLE 无效 + } + 1 -> {//闯红灯 V2I_RLVW_VIOLATION_TYPE_RUNNING_RED_LIGHT 一个红灯周期只显示一次 + if (!isShowRunRedLight) { + isShowRunRedLight = true + CallerHmiManager.disableWarningV2X(1667.toString()) + CallerLogger.d( + "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", + "changeTrafficLightStatus 闯红灯 --------> " + ) + ttsContent = + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType) + alertContent = + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType) + CallerMsgBoxManager.saveMsgBox( + MsgBoxBean( + MsgBoxType.V2X, + V2XMsg( + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, + alertContent, + ttsContent + ) + ).apply { + sourceType = DataSourceType.OBU + } + ) + + CallerHmiManager.warningV2X( + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, + alertContent, + ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 + EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, + null, + true, + 5000L + ) } - 1 -> {//闯红灯 V2I_RLVW_VIOLATION_TYPE_RUNNING_RED_LIGHT 一个红灯周期只显示一次 - if (!isShowRunRedLight) { - isShowRunRedLight = true - CallerHmiManager.disableWarningV2X(1667.toString()) - CallerLogger.d( - "$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}", - "changeTrafficLightStatus 闯红灯 --------> " + } + + 2 -> { //绿波通行引导 V2I_RLVW_VIOLATION_TYPE_NO_VIOLATION 一个绿灯周期只显示一次 100m的时候 + if (!isShowGreenWave) { + isShowGreenWave = true + CallerHmiManager.disableWarningV2X(1666.toString()) + + var minSpeedTemp = Math.round(currentLight.suggestMinSpeed * 3.6) + var maxSpeedTemp = Math.round(currentLight.suggestMaxSpeed * 3.6) + if (minSpeedTemp == maxSpeedTemp) { + minSpeedTemp -= 5 + } + + val adviceSpeed = "$minSpeedTemp - $maxSpeedTemp" + val adviceSpeedTts = "$minSpeedTemp 到 $maxSpeedTemp" + +// val adviceSpeed = +// "${Math.round(currentLight.suggestMinSpeed*3.6)} - ${Math.round(currentLight.suggestMaxSpeed*3.6)}" +// val adviceSpeedTts = +// "${Math.round(currentLight.suggestMinSpeed*3.6)} 到 ${Math.round(currentLight.suggestMaxSpeed*3.6)}" + + ttsContent = + String.format( + EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType), + adviceSpeedTts ) - ttsContent = - EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType) - alertContent = - EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType) + alertContent = + String.format( + EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType), + adviceSpeed + ) + + val maxSpeed = currentLight.suggestMaxSpeed + if (maxSpeed > 0) { CallerMsgBoxManager.saveMsgBox( MsgBoxBean( MsgBoxType.V2X, V2XMsg( - EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, + EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType, alertContent, ttsContent ) @@ -977,118 +1053,61 @@ class MogoPrivateObuNewManager private constructor() { ) CallerHmiManager.warningV2X( - EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, + EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType, alertContent, ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 - EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType, + appId.toString(), null, true, 5000L ) } } - - 2 -> { //绿波通行引导 V2I_RLVW_VIOLATION_TYPE_NO_VIOLATION 一个绿灯周期只显示一次 100m的时候 - if (!isShowGreenWave) { - isShowGreenWave = true - CallerHmiManager.disableWarningV2X(1666.toString()) - - var minSpeedTemp = Math.round(currentLight.suggestMinSpeed*3.6) - var maxSpeedTemp = Math.round(currentLight.suggestMaxSpeed*3.6) - if (minSpeedTemp == maxSpeedTemp) { - minSpeedTemp -= 5 - } - - val adviceSpeed = "$minSpeedTemp - $maxSpeedTemp" - val adviceSpeedTts = "$minSpeedTemp 到 $maxSpeedTemp" - -// val adviceSpeed = -// "${Math.round(currentLight.suggestMinSpeed*3.6)} - ${Math.round(currentLight.suggestMaxSpeed*3.6)}" -// val adviceSpeedTts = -// "${Math.round(currentLight.suggestMinSpeed*3.6)} 到 ${Math.round(currentLight.suggestMaxSpeed*3.6)}" - - ttsContent = - String.format( - EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType), - adviceSpeedTts - ) - alertContent = - String.format( - EventTypeEnumNew.getWarningContent(EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType), - adviceSpeed - ) - - val maxSpeed = currentLight.suggestMaxSpeed - if (maxSpeed > 0) { - CallerMsgBoxManager.saveMsgBox( - MsgBoxBean( - MsgBoxType.V2X, - V2XMsg( - EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType, - alertContent, - ttsContent - ) - ).apply { - sourceType = DataSourceType.OBU - } - ) - - CallerHmiManager.warningV2X( - EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType, - alertContent, - ttsContent,// 只有第一次才tts,防止更新的时候不断的提醒 - appId.toString(), - null, - true, - 5000L - ) - } - } - } - } - - when (currentLight.light) { - // 灯光不可用 - 0 -> { - CallerObuTrafficLightListenerManager.invokeObuTrafficLight(0) - } - // 红灯 - 2, 3 -> { - if (!isRedLight) { - CallerHmiManager.disableWarningV2X(appId.toString()) - isRedLight = true - } - isGreenLight = false - isYellowLight = false - CallerObuTrafficLightListenerManager.invokeObuTrafficLight(1) - val red = currentLight.countDown.toInt() - CallerHmiManager.changeCountdownRed(red) - } - - // 绿灯 - 4, 5, 6 -> { - if (!isGreenLight) { - CallerHmiManager.disableWarningV2X(appId.toString()) - isGreenLight = true - } - isRedLight = false - isYellowLight = false - CallerObuTrafficLightListenerManager.invokeObuTrafficLight(3) - val green = currentLight.countDown.toInt() - CallerHmiManager.changeCountdownGreen(green) - } - - // 黄灯 - 7, 8 -> { - if (!isYellowLight) { - isYellowLight = true - } - isRedLight = false - isGreenLight = false - CallerHmiManager.disableWarningV2X(appId.toString()) - CallerObuTrafficLightListenerManager.invokeObuTrafficLight(2) - val yellow = currentLight.countDown.toInt() - CallerHmiManager.changeCountdownYellow(yellow) - } } } + + when (currentLight.light) { + // 灯光不可用 + 0 -> { + CallerObuTrafficLightListenerManager.invokeObuTrafficLight(0) + } + // 红灯 + 2, 3 -> { + if (!isRedLight) { + CallerHmiManager.disableWarningV2X(appId.toString()) + isRedLight = true + } + isGreenLight = false + isYellowLight = false + CallerObuTrafficLightListenerManager.invokeObuTrafficLight(1) + val red = currentLight.countDown.toInt() + CallerHmiManager.changeCountdownRed(red) + } + + // 绿灯 + 4, 5, 6 -> { + if (!isGreenLight) { + CallerHmiManager.disableWarningV2X(appId.toString()) + isGreenLight = true + } + isRedLight = false + isYellowLight = false + CallerObuTrafficLightListenerManager.invokeObuTrafficLight(3) + val green = currentLight.countDown.toInt() + CallerHmiManager.changeCountdownGreen(green) + } + + // 黄灯 + 7, 8 -> { + if (!isYellowLight) { + isYellowLight = true + } + isRedLight = false + isGreenLight = false + CallerHmiManager.disableWarningV2X(appId.toString()) + CallerObuTrafficLightListenerManager.invokeObuTrafficLight(2) + val yellow = currentLight.countDown.toInt() + CallerHmiManager.changeCountdownYellow(yellow) + } + } +} diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XLimitingVelocityBroadcastReceiver.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XLimitingVelocityBroadcastReceiver.kt index 1395d3578f..5c2a231c3d 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XLimitingVelocityBroadcastReceiver.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XLimitingVelocityBroadcastReceiver.kt @@ -3,7 +3,11 @@ package com.mogo.eagle.core.function.hmi.receiver import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import com.mogo.eagle.core.function.call.hmi.CallerHmiManager +import android.view.View +import com.mogo.eagle.core.data.enums.DataSourceType +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.LimitingVelocityView_TAG +import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager +import com.mogo.eagle.core.function.call.v2x.CallerViewLimitingVelocityListenerManager import com.mogo.eagle.core.function.hmi.WaringConst import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI @@ -57,13 +61,13 @@ class V2XLimitingVelocityBroadcastReceiver : BroadcastReceiver() { * @param limitingVelocitySpeed 限速速度 */ private fun dispatchShowWaring(limitingVelocitySpeed: Int) { - CallerHmiManager.showLimitingVelocity(limitingVelocitySpeed, 1) + CallerViewLimitingVelocityListenerManager.invokeOnLimitingVelocityChange(limitingVelocitySpeed,DataSourceType.MAP) } /** * 关闭限速标志 */ private fun dispatchCloseWaring() { - CallerHmiManager.disableLimitingVelocity() + CallerHmiViewControlListenerManager.invokeVisible(LimitingVelocityView_TAG, View.GONE) } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt index 9f482ca275..8bd6b1baef 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt @@ -1,7 +1,6 @@ package com.mogo.eagle.core.function.hmi.ui import android.content.Context -import android.os.Bundle import android.text.TextUtils import android.util.Log import android.view.View @@ -31,13 +30,6 @@ import com.mogo.eagle.core.data.notice.NoticeNormalData import com.mogo.eagle.core.data.notice.NoticeTrafficStylePushData import com.mogo.eagle.core.data.report.ReportEntity import com.mogo.eagle.core.function.api.hmi.IMoGoHmiViewProxy -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.AutoPilotStatusView_TAG -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.CameraView_TAG -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.PerspectiveSwitchView_TAG -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.SpeedPanelView_TAG -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.ToolsView_TAG -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.TrafficLightView_TAG -import com.mogo.eagle.core.function.api.hmi.view.IViewLimitingVelocity import com.mogo.eagle.core.function.api.hmi.view.IViewTrafficLight import com.mogo.eagle.core.function.api.hmi.warning.IMoGoHmiProvider import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener @@ -87,7 +79,7 @@ import java.util.concurrent.atomic.AtomicReference class MoGoHmiFragment : MvpFragment(), IMoGoHmiProvider, IMoGoHmiViewProxy, - MoGoHmiContract.View{ + MoGoHmiContract.View { companion object { private const val TAG = "MoGoHmiFragment" @@ -97,9 +89,6 @@ class MoGoHmiFragment : MvpFragment(), // todo 需要统一数据源 红绿灯 View代理 private var mViewTrafficLight: IViewTrafficLight? = null - // todo 需要统一数据源 限速 View代理 - private var mViewLimitingVelocity: IViewLimitingVelocity? = null - private val lastSpeakJob by lazy { AtomicReference() } private var lastShowV2XJob: Job? = null @@ -107,9 +96,6 @@ class MoGoHmiFragment : MvpFragment(), override fun initViews() { - //设置StatusBar初始状态 - CallerHmiViewControlListenerManager.updateStatusBarRightView(StatusBarView.TAG,FunctionBuildConfig.isDemoMode, "demoMode", DemoModeView(requireContext())) - //todo 新超,封装至消息盒子 cbMsgBoxDriver.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { @@ -170,12 +156,6 @@ class MoGoHmiFragment : MvpFragment(), } } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - //todo 确认使用方 taxi bus 乘客/司机 - setProxyLimitingSpeedView(viewLimitingVelocity) - } - /** todo ----------------------------------------------**/ /** * 设置 红绿灯 代理View @@ -184,13 +164,6 @@ class MoGoHmiFragment : MvpFragment(), mViewTrafficLight = view } - /** - * 设置 限速 代理View - */ - override fun setProxyLimitingSpeedView(view: IViewLimitingVelocity) { - mViewLimitingVelocity = view - } - /** * ok * 工控机重启返回结果 @@ -236,23 +209,38 @@ class MoGoHmiFragment : MvpFragment(), } override fun setStatusBarDarkOrLight(light: Boolean) { - CallerHmiViewControlListenerManager.setStatusBarDarkOrLight(StatusBarView.TAG,light) + CallerHmiViewControlListenerManager.setStatusBarDarkOrLight(StatusBarView.TAG, light) } override fun updateStatusBarRightView(insert: Boolean, tag: String, viewGroup: ViewGroup) { - CallerHmiViewControlListenerManager.updateStatusBarRightView(StatusBarView.TAG,insert, tag, viewGroup) + CallerHmiViewControlListenerManager.updateStatusBarRightView( + StatusBarView.TAG, + insert, + tag, + viewGroup + ) } override fun updateStatusBarLeftView(insert: Boolean, tag: String, viewGroup: ViewGroup) { - CallerHmiViewControlListenerManager.updateStatusBarLeftView(StatusBarView.TAG,insert, tag, viewGroup) + CallerHmiViewControlListenerManager.updateStatusBarLeftView( + StatusBarView.TAG, + insert, + tag, + viewGroup + ) } override fun updateStatusBarDownloadView(insert: Boolean, tag: String, progress: Int) { - CallerHmiViewControlListenerManager.updateStatusBarDownloadView(StatusBarView.TAG,insert, tag, progress) + CallerHmiViewControlListenerManager.updateStatusBarDownloadView( + StatusBarView.TAG, + insert, + tag, + progress + ) } override fun updateMfStatus(tag: String, status: Boolean) { - CallerHmiViewControlListenerManager.updateMfStatus(StatusBarView.TAG,tag, status) + CallerHmiViewControlListenerManager.updateMfStatus(StatusBarView.TAG, tag, status) } override fun getLayoutId(): Int { @@ -271,30 +259,6 @@ class MoGoHmiFragment : MvpFragment(), DisplayEffectsHelper.getInstance().display() } - override fun setTrafficLightVrVisibility(visibility: Int) { - CallerHmiViewControlListenerManager.invokeVisible(TrafficLightView_TAG,visibility) - } - - override fun setToolsViewVisibility(visibility: Int) { - CallerHmiViewControlListenerManager.invokeVisible(ToolsView_TAG,visibility) - } - - override fun setSpeedChartViewVisibility(visibility: Int) { - CallerHmiViewControlListenerManager.invokeVisible(SpeedPanelView_TAG,visibility) - } - - override fun setAutopilotStatusViewVisibility(visibility: Int) { - CallerHmiViewControlListenerManager.invokeVisible(AutoPilotStatusView_TAG,visibility) - } - - override fun setPerspectiveSwitchViewVisibility(visibility: Int) { - CallerHmiViewControlListenerManager.invokeVisible(PerspectiveSwitchView_TAG,visibility) - } - - override fun setCameraViewVisibility(visibility: Int) { - CallerHmiViewControlListenerManager.invokeVisible(CameraView_TAG, visibility) - } - /** todo----------------------------------------------- **/ /** * 不展示顶部弹窗,其它保留 @@ -351,7 +315,7 @@ class MoGoHmiFragment : MvpFragment(), if (ttsContent != null && !TextUtils.isEmpty(ttsContent) && playTTS) { val last = lastSpeakJob.get() Log.d("CODE", "---- 0 ------: last: $last") - if (last != null && !last.isCompleted) { + if (last != null && !last.isCompleted) { Log.d("CODE", "---- 1 ------") return } @@ -452,40 +416,6 @@ class MoGoHmiFragment : MvpFragment(), mViewTrafficLight?.changeCountdownTrafficLightNum(readNum, yellowNum, greenNum) } - /** - * 控制展示限速标志及内容 - */ - override fun showLimitingVelocity(limitingSpeed: Int, limitSpeedSource: Int) { - // 控制 限速UI 展示 - if (HmiBuildConfig.isShowLimitingVelocityView) { - if (limitingSpeed > 0) { - mViewLimitingVelocity?.visibility = View.VISIBLE - mViewLimitingVelocity?.updateLimitingSpeed(limitingSpeed, limitSpeedSource) - tvLimitingSource?.visibility = View.VISIBLE - if (limitSpeedSource == 1) { - tvLimitingSource.text = "MAP" - } else if (limitSpeedSource == 2) { - tvLimitingSource.text = "RSU" - } - } else { - mViewLimitingVelocity?.visibility = View.INVISIBLE - mViewLimitingVelocity?.updateLimitingSpeed(0, limitSpeedSource) - tvLimitingSource?.visibility = View.INVISIBLE - } - } else { - disableLimitingVelocity() - tvLimitingSource?.visibility = View.GONE - } - } - - /** - * 控制关闭限速标志及内容 - */ - override fun disableLimitingVelocity() { - mViewLimitingVelocity?.visibility = View.GONE - mViewLimitingVelocity?.updateLimitingSpeed(0, 1) - } - /** * 展示指定方位上的红框预警 * @param direction diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt index 1674acdcb5..14e6d0cee2 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt @@ -1032,49 +1032,6 @@ internal class DebugSettingView @JvmOverloads constructor( * 设置Hmi点击监听 */ private fun setHmiCheckedChangeListener() { - /** - * 显示、隐藏迈速表 - */ - tbSpeedView.setOnCheckedChangeListener { _, isChecked -> - if (!isChecked) { - CallerHmiManager.setSpeedChartViewVisibility(View.VISIBLE) - } else { - CallerHmiManager.setSpeedChartViewVisibility(View.GONE) - } - } - - /** - * 显示、隐藏“自动驾驶控制按钮” - */ - tbAutopilotStatusView.setOnCheckedChangeListener { _, isChecked -> - if (!isChecked) { - CallerHmiManager.setAutopilotStatusViewVisibility(View.VISIBLE) - } else { - CallerHmiManager.setAutopilotStatusViewVisibility(View.GONE) - } - } - - /** - * 显示、隐藏视角切换按钮 - */ - tbPerspectiveSwitchView.setOnCheckedChangeListener { _, isChecked -> - if (!isChecked) { - CallerHmiManager.setPerspectiveSwitchViewVisibility(View.VISIBLE) - } else { - CallerHmiManager.setPerspectiveSwitchViewVisibility(View.GONE) - } - } - - /** - * 显示、隐藏工具箱 - */ - tbCheckStatusView.setOnCheckedChangeListener { _, isChecked -> - if (!isChecked) { - CallerHmiManager.setToolsViewVisibility(View.VISIBLE) - } else { - CallerHmiManager.setToolsViewVisibility(View.GONE) - } - } /** * 隐藏、显示小地图 diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/SOPSettingView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/SOPSettingView.kt index e6afb2b7b2..0ae1263047 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/SOPSettingView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/SOPSettingView.kt @@ -10,6 +10,7 @@ import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.data.config.HmiBuildConfig import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsFuncConfigListener +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsFuncConfigListenerManager import com.mogo.eagle.core.function.call.hmi.CallerHmiManager @@ -19,6 +20,7 @@ import com.mogo.eagle.core.utilcode.kotlin.currentPadding import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils import com.mogo.eagle.core.utilcode.util.ToastUtils import com.mogo.eagle.core.function.business.routeoverlay.RouteStrategy +import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.hmi.ui.widget.DemoModeView import com.mogo.eagle.core.utilcode.util.UiThreadHandler import kotlinx.android.synthetic.main.view_debug_setting.view.* @@ -150,7 +152,7 @@ internal class SOPSettingView @JvmOverloads constructor( HmiBuildConfig.isShowLimitingVelocityView = true } else { HmiBuildConfig.isShowLimitingVelocityView = false - CallerHmiManager.disableLimitingVelocity() + CallerHmiViewControlListenerManager.invokeVisible(IViewControlListener.LimitingVelocityView_TAG,View.GONE) } } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt index 84400ca732..2e8b24e018 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt @@ -2,14 +2,11 @@ package com.mogo.eagle.core.function.hmi.ui.tools import android.content.Context import android.util.AttributeSet -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.ToolsView_TAG -import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.function.hmi.ui.setting.ToolsView.Companion.toolsView class ToolsImageView(context: Context, attrs: AttributeSet?) : - androidx.appcompat.widget.AppCompatImageView(context, attrs), IViewControlListener { + androidx.appcompat.widget.AppCompatImageView(context, attrs) { override fun onAttachedToWindow() { super.onAttachedToWindow() @@ -19,17 +16,6 @@ class ToolsImageView(context: Context, attrs: AttributeSet?) : setOnClickListener{ toolsView.showToolsFloat(context) } - - CallerHmiViewControlListenerManager.addListener(ToolsView_TAG, this) } - override fun visible(v: Int) { - super.visible(v) - visibility = v - } - - override fun onDetachedFromWindow() { - super.onDetachedFromWindow() - CallerHmiViewControlListenerManager.removeListener(ToolsView_TAG) - } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/AutoPilotStatusView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/AutoPilotStatusView.kt index e6c453db80..2ff479a1c7 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/AutoPilotStatusView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/AutoPilotStatusView.kt @@ -8,14 +8,11 @@ import androidx.constraintlayout.widget.ConstraintLayout import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.AutoPilotStatusView_TAG import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.getCurWgs84Lat import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.getCurWgs84Lon import com.mogo.eagle.core.function.call.hmi.CallerHmiListenerManager -import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI @@ -33,7 +30,7 @@ class AutoPilotStatusView constructor( attrs: AttributeSet ) : ConstraintLayout(context, attrs), View.OnClickListener, - IMoGoAutopilotStatusListener, IViewControlListener { + IMoGoAutopilotStatusListener { companion object { const val TAG = "AutopilotStatusView" @@ -57,17 +54,10 @@ class AutoPilotStatusView constructor( setOnClickListener(this) // 自动驾驶状态监听 CallerAutoPilotStatusListenerManager.addListener(TAG, this) - CallerHmiViewControlListenerManager.addListener(AutoPilotStatusView_TAG, this) - CallerLogger.d("$M_HMI$TAG", "autopilotStatus: $mAutopilotStatus") setAutoPilotStatus(mAutopilotStatus) } - override fun visible(v: Int) { - super.visible(v) - visibility = v - } - override fun onClick(v: View?) { when (mAutopilotStatus) { 0 -> {// 不可自动驾驶,adas与工控机没有链接,或工控机异常 @@ -139,7 +129,6 @@ class AutoPilotStatusView constructor( override fun onDetachedFromWindow() { super.onDetachedFromWindow() CallerAutoPilotStatusListenerManager.removeListener(TAG) - CallerHmiViewControlListenerManager.removeListener(AutoPilotStatusView_TAG) } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/CameraView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/CameraView.kt index 70e5ae0f35..36337a284b 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/CameraView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/CameraView.kt @@ -2,15 +2,12 @@ package com.mogo.eagle.core.function.hmi.ui.widget import android.content.Context import android.util.AttributeSet -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.CameraView_TAG import com.mogo.eagle.core.function.call.biz.CallerFuncBizManager -import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.function.hmi.ui.setting.CameraLiveView.Companion.cameraLiveView class CameraView(context: Context, attrs: AttributeSet?) : - androidx.appcompat.widget.AppCompatImageView(context, attrs), IViewControlListener { + androidx.appcompat.widget.AppCompatImageView(context, attrs) { override fun onAttachedToWindow() { super.onAttachedToWindow() @@ -28,16 +25,6 @@ class CameraView(context: Context, attrs: AttributeSet?) : } } - CallerHmiViewControlListenerManager.addListener(CameraView_TAG, this) } - override fun visible(v: Int) { - super.visible(v) - visibility = v - } - - override fun onDetachedFromWindow() { - super.onDetachedFromWindow() - CallerHmiViewControlListenerManager.removeListener(CameraView_TAG) - } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/LimitingVelocityView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/LimitingVelocityView.kt index c766f7a029..6df4d6b3c2 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/LimitingVelocityView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/LimitingVelocityView.kt @@ -3,7 +3,14 @@ package com.mogo.eagle.core.function.hmi.ui.widget import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater -import com.mogo.eagle.core.function.api.hmi.view.IViewLimitingVelocity +import android.view.View +import android.widget.LinearLayout +import com.mogo.eagle.core.data.enums.DataSourceType +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener +import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.LimitingVelocityView_TAG +import com.mogo.eagle.core.function.api.v2x.ILimitingVelocityListener +import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager +import com.mogo.eagle.core.function.call.v2x.CallerViewLimitingVelocityListenerManager import com.mogo.eagle.core.function.hmi.R import kotlinx.android.synthetic.main.view_limiting_speed_vr.view.* @@ -11,17 +18,48 @@ import kotlinx.android.synthetic.main.view_limiting_speed_vr.view.* * 限速控件 */ class LimitingVelocityView @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = 0 -) : IViewLimitingVelocity(context, attrs, defStyleAttr) { + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : LinearLayout(context, attrs, defStyleAttr), ILimitingVelocityListener, IViewControlListener { + + companion object { + private const val TAG = "LimitingVelocityView" + } init { LayoutInflater.from(context).inflate(R.layout.view_limiting_speed_vr, this, true) } - override fun updateLimitingSpeed(limitingSpeed: Int, limitSource: Int) { - super.updateLimitingSpeed(limitingSpeed, limitSource) - tvLimitingVelocity.text = "$limitingSpeed" + override fun onAttachedToWindow() { + super.onAttachedToWindow() + CallerViewLimitingVelocityListenerManager.addListener(TAG, this) + CallerHmiViewControlListenerManager.addListener(LimitingVelocityView_TAG, this) } + + override fun onLimitingVelocityChange(limitingVelocity: Int, sourceType: DataSourceType) { + if (limitingVelocity > 0) { + tvLimitingVelocity.visibility = View.VISIBLE + tvLimitingSource.visibility = View.VISIBLE + tvLimitingVelocity.text = "$limitingVelocity" + tvLimitingSource.text = sourceType.name + } else { + tvLimitingVelocity.visibility = View.GONE + tvLimitingSource.visibility = View.GONE + tvLimitingSource.text = "" + } + } + + override fun visible(v: Int) { + super.visible(v) + tvLimitingVelocity.visibility = v + tvLimitingSource.visibility = v + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + CallerViewLimitingVelocityListenerManager.removeListener(TAG) + CallerHmiViewControlListenerManager.removeListener(LimitingVelocityView_TAG) + } + } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/PerspectiveSwitchView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/PerspectiveSwitchView.kt index 55e04f82ec..09cd83ed9a 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/PerspectiveSwitchView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/PerspectiveSwitchView.kt @@ -5,9 +5,6 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.view.View import android.widget.FrameLayout -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.PerspectiveSwitchView_TAG -import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager.getMapUIController import com.mogo.eagle.core.function.hmi.R import com.mogo.map.uicontroller.VisualAngleMode @@ -22,20 +19,13 @@ class PerspectiveSwitchView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 -) : FrameLayout(context, attrs, defStyleAttr), View.OnClickListener, IViewControlListener{ +) : FrameLayout(context, attrs, defStyleAttr), View.OnClickListener{ override fun onAttachedToWindow() { super.onAttachedToWindow() LayoutInflater.from(context).inflate(R.layout.view_perspective_switch, this, true) setBackgroundResource(R.drawable.module_switch_map_bg) setOnClickListener(this) - - CallerHmiViewControlListenerManager.addListener(PerspectiveSwitchView_TAG,this) - } - - override fun visible(v: Int) { - super.visible(v) - visibility = v } override fun onClick(v: View?) { @@ -53,9 +43,4 @@ class PerspectiveSwitchView @JvmOverloads constructor( } } - override fun onDetachedFromWindow() { - super.onDetachedFromWindow() - CallerHmiViewControlListenerManager.removeListener(PerspectiveSwitchView_TAG) - } - } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedPanelView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedPanelView.kt index 46dda6467e..17b6cd5978 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedPanelView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SpeedPanelView.kt @@ -6,11 +6,7 @@ import android.util.AttributeSet import android.view.Gravity import android.widget.FrameLayout import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener -import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.SpeedPanelView_TAG import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ20ListenerManager -import com.mogo.eagle.core.function.call.hmi.CallerHmiManager -import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.utilcode.util.UiThreadHandler @@ -25,7 +21,7 @@ class SpeedPanelView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 -) : FrameLayout(context, attrs, defStyleAttr), IMoGoChassisLocationGCJ02Listener,IViewControlListener { +) : FrameLayout(context, attrs, defStyleAttr), IMoGoChassisLocationGCJ02Listener { companion object { const val TAG = "SpeedPanelView" @@ -58,8 +54,6 @@ class SpeedPanelView @JvmOverloads constructor( override fun onAttachedToWindow() { super.onAttachedToWindow() - // 注册view控制显示隐藏监听 - CallerHmiViewControlListenerManager.addListener(SpeedPanelView_TAG,this) // 注册位置回调 CallerChassisLocationGCJ20ListenerManager.addListener(TAG, this) // 开启定时查询速度 @@ -89,15 +83,9 @@ class SpeedPanelView @JvmOverloads constructor( } } - override fun visible(v: Int) { - super.visible(v) - visibility = v - } - override fun onDetachedFromWindow() { super.onDetachedFromWindow() // 解除注册 - CallerHmiViewControlListenerManager.removeListener(SpeedPanelView_TAG) CallerChassisLocationGCJ20ListenerManager.removeListener(TAG) try { timerTask?.cancel() diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/StatusBarView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/StatusBarView.kt index 42079aa30b..3aad68006d 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/StatusBarView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/StatusBarView.kt @@ -6,6 +6,7 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.view.ViewGroup import android.widget.LinearLayout +import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.data.mofang.MfConstants import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener @@ -51,6 +52,7 @@ class StatusBarView @JvmOverloads constructor( //将状态窗口中的状态移到状态栏上 CallerDevaToolsManager.showStatusBar(context, status_container) + updateStatusBarRightView(FunctionBuildConfig.isDemoMode, "demoMode", DemoModeView(this.context)) } override fun onSkinModeChange(skinMode: Int) { diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/VipIdentificationView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/VipIdentificationView.kt index d9dd3ee643..47054ca428 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/VipIdentificationView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/VipIdentificationView.kt @@ -27,32 +27,14 @@ class VipIdentificationView : ConstraintLayout, IMoGoVipSetListener { attributeSet, defStyleAttr ) { - init(attributeSet, defStyleAttr) } - private var marginStart: Float = 0.0f - private var marginTop: Float = 0.0f - - private fun init(attrs: AttributeSet, defStyleAttr: Int) { + init { LayoutInflater.from(context).inflate(R.layout.view_vip_identification, this, true) - val a = context.obtainStyledAttributes( - attrs, - R.styleable.VipIdentificationView, - defStyleAttr, - 0 - ) - marginStart = a.getDimension(R.styleable.VipIdentificationView_marginStart, 0.0f) - marginTop = a.getDimension(R.styleable.VipIdentificationView_marginTop, 0.0f) - a.recycle() } override fun onAttachedToWindow() { super.onAttachedToWindow() - val lp = this.layoutParams as LayoutParams - lp.marginStart = marginStart.toInt() - lp.topMargin = marginTop.toInt() - this.layoutParams = lp - invalidate() CallVipSetListenerManager.addListener(TAG, this) } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml index b2dd4a6f0a..56b54cc6dd 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml @@ -20,45 +20,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:paddingTop="72dp"> - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml index d3969d4863..639cc50149 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml @@ -1274,54 +1274,6 @@ app:layout_constraintLeft_toRightOf="@+id/tbChangeCurrentCarIcon" app:layout_constraintTop_toTopOf="@id/tbChangeCurrentCarIcon" /> - - - - - - - - + android:layout_height="match_parent" + android:orientation="vertical"> + app:layout_constraintTop_toBottomOf="@+id/ivCameraIcon" /> + + + \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/values/attr.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/values/attr.xml index cb5e3610d1..7e72417466 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/values/attr.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/values/attr.xml @@ -69,9 +69,4 @@ @android:color/transparent - - - - - \ 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/events/V2XEventManager.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/V2XEventManager.kt index 711fde9e88..c67989c8b8 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 @@ -19,7 +19,7 @@ import com.mogo.eagle.core.data.map.entity.MarkerExploreWay import com.mogo.eagle.core.data.map.entity.MarkerShowEntity import com.mogo.eagle.core.data.map.entity.V2XMessageEntity import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity -import com.mogo.eagle.core.data.msgbox.DataSourceType +import com.mogo.eagle.core.data.enums.DataSourceType import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.V2XMsg diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/DataSourceType.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/DataSourceType.kt new file mode 100644 index 0000000000..7cc8ddb8fa --- /dev/null +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/enums/DataSourceType.kt @@ -0,0 +1,11 @@ +package com.mogo.eagle.core.data.enums + +enum class DataSourceType(name: String) { + DEFAULT("defalut"), + OBU("OBU"), + MAP("MAP"), + TELEMATIC("TELEMATIC"), + AICLOUD("AI云"), + SUMMARY("汇总")// V2X事件汇总 + +} \ No newline at end of file diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/DataSourceType.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/DataSourceType.kt deleted file mode 100644 index af15d0b8a7..0000000000 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/DataSourceType.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.mogo.eagle.core.data.msgbox - -enum class DataSourceType { - DEFAULT, - OBU, - TELEMATIC, - AICLOUD, - SUMMARY// V2X事件汇总 -} \ No newline at end of file diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/MsgBoxBean.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/MsgBoxBean.kt index 9c370be85d..0626508331 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/MsgBoxBean.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/msgbox/MsgBoxBean.kt @@ -1,5 +1,7 @@ package com.mogo.eagle.core.data.msgbox +import com.mogo.eagle.core.data.enums.DataSourceType + data class MsgBoxBean(val type: MsgBoxType, val bean: Any) { var timestamp: Long = 0 var bean2Json: String = "" diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/IMoGoHmiViewProxy.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/IMoGoHmiViewProxy.kt index 7dd525ac24..7b760ac015 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/IMoGoHmiViewProxy.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/IMoGoHmiViewProxy.kt @@ -1,7 +1,5 @@ package com.mogo.eagle.core.function.api.hmi -import com.mogo.eagle.core.function.api.hmi.view.IViewLimitingVelocity -import com.mogo.eagle.core.function.api.hmi.view.IViewNotification import com.mogo.eagle.core.function.api.hmi.view.IViewTrafficLight /** @@ -15,10 +13,4 @@ interface IMoGoHmiViewProxy { */ fun setProxyTrafficLightView(view: IViewTrafficLight) - /** - * 设置 限速 代理View - * @param view - */ - fun setProxyLimitingSpeedView(view: IViewLimitingVelocity) - } \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewControlListener.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewControlListener.kt index 4a1c67310f..2bdf8d3bce 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewControlListener.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewControlListener.kt @@ -5,12 +5,8 @@ import android.view.ViewGroup interface IViewControlListener { companion object{ - const val SpeedPanelView_TAG = "SpeedPanelView_TAG" - const val AutoPilotStatusView_TAG = "AutoPilotStatusView_TAG" - const val PerspectiveSwitchView_TAG = "PerspectiveSwitchView_TAG" - const val CameraView_TAG = "CameraView_TAG" - const val ToolsView_TAG = "ToolsView_TAG" const val TrafficLightView_TAG = "TrafficLightView_TAG" + const val LimitingVelocityView_TAG = "LimitingVelocityView_TAG" } /** --------- View --------- **/ diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewLimitingVelocity.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewLimitingVelocity.kt deleted file mode 100644 index c1b5499a1d..0000000000 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewLimitingVelocity.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.mogo.eagle.core.function.api.hmi.view - -import android.content.Context -import android.util.AttributeSet -import android.widget.LinearLayout - -/** - * 定义限速View具备的接口 - */ -abstract class IViewLimitingVelocity(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : - LinearLayout(context, attrs, defStyleAttr) { - - /** - * 更新限速数据 - * @param limitingSpeed 限速值,单位:km/h - * @param limitSource 限速来源 1:MAP, 2:RSU - */ - open fun updateLimitingSpeed(limitingSpeed: Int, limitSource: Int) {} -} \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoHmiProvider.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoHmiProvider.kt index 266eaa8fa6..928554ef5b 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoHmiProvider.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoHmiProvider.kt @@ -1,6 +1,5 @@ package com.mogo.eagle.core.function.api.hmi.warning -import android.view.View import android.view.ViewGroup import com.mogo.eagle.core.data.bindingcar.IPCUpgradeStateInfo import com.mogo.eagle.core.data.dispatch.DispatchAdasAutoPilotLocReceiverBean @@ -22,38 +21,6 @@ interface IMoGoHmiProvider : IMoGoHmiViewProxy { */ fun displayEffects() - /** - * 隐藏 脉速表 - * @param visibility View.VISIBLE, View.INVISIBLE,View.GONE - */ - fun setSpeedChartViewVisibility(visibility: Int) - - /** - * 隐藏 红绿灯UI - * @param visibility View.VISIBLE, View.INVISIBLE,View.GONE - */ - fun setTrafficLightVrVisibility(visibility: Int) - - /** - * 隐藏 自动驾驶触发 按钮 - * @param visibility View.VISIBLE, View.INVISIBLE,View.GONE - */ - fun setAutopilotStatusViewVisibility(visibility: Int) - - /** - * 隐藏 切换视角 按钮 - * @param visibility View.VISIBLE, View.INVISIBLE,View.GONE - */ - fun setPerspectiveSwitchViewVisibility(visibility: Int) - - /** - * 隐藏 工具箱 按钮 - * @param visibility View.VISIBLE, View.INVISIBLE,View.GONE - */ - fun setToolsViewVisibility(visibility: Int) - - fun setCameraViewVisibility(visibility: Int) - /** * 控制转向灯 */ @@ -135,19 +102,6 @@ interface IMoGoHmiProvider : IMoGoHmiViewProxy { */ fun changeCountdownTrafficLightNum(readNum: Int, yellowNum: Int, greenNum: Int) - /** - * 展示限速预警 - * - * @param limitingSpeed 限速速度 - * @param limitSpeedSource 限速来源 1:MAP, 2:RSU - */ - fun showLimitingVelocity(limitingSpeed: Int, limitSpeedSource: Int) - - /** - * 关闭限速预警 - */ - fun disableLimitingVelocity() - /** * 展示指定方位上的红框预警 * @param direction diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/ILimitingVelocityListener.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/ILimitingVelocityListener.kt new file mode 100644 index 0000000000..49bfecb6dd --- /dev/null +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/ILimitingVelocityListener.kt @@ -0,0 +1,10 @@ +package com.mogo.eagle.core.function.api.v2x + +import com.mogo.eagle.core.data.enums.DataSourceType + +/** + * 限速信息回掉 + */ +interface ILimitingVelocityListener { + fun onLimitingVelocityChange(limitingVelocity: Int,sourceType: DataSourceType) +} \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/LimitingVelocityListener.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/LimitingVelocityListener.kt deleted file mode 100644 index 4df12373e2..0000000000 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/LimitingVelocityListener.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.mogo.eagle.core.function.api.v2x - -/** - * 限速信息回掉 - */ -interface LimitingVelocityListener { - fun onLimitingVelocityChange(limitingVelocity: Int) -} \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/ObuLimitingSpeedListener.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/ObuLimitingSpeedListener.kt deleted file mode 100644 index 1fb84cdeaa..0000000000 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/v2x/ObuLimitingSpeedListener.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.mogo.eagle.core.function.api.v2x - -/** - * 限速信息 - */ -interface ObuLimitingSpeedListener { - fun onObuLimitingSpeedChange(limitingSpeed: Int) -} \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt index 1a1eedf412..b89e16b16d 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt @@ -1,23 +1,18 @@ package com.mogo.eagle.core.function.call.hmi -import android.view.View import android.view.ViewGroup import com.alibaba.android.arouter.launcher.ARouter import com.mogo.eagle.core.data.bindingcar.IPCUpgradeStateInfo import com.mogo.eagle.core.data.constants.MoGoFragmentPaths -import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_SLW -import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.V2I import com.mogo.eagle.core.data.dispatch.DispatchAdasAutoPilotLocReceiverBean import com.mogo.eagle.core.data.enums.WarningDirectionEnum import com.mogo.eagle.core.data.map.Infrastructure import com.mogo.eagle.core.data.notice.NoticeNormalData import com.mogo.eagle.core.data.notice.NoticeTrafficStylePushData import com.mogo.eagle.core.data.report.ReportEntity -import com.mogo.eagle.core.function.api.hmi.view.IViewLimitingVelocity import com.mogo.eagle.core.function.api.hmi.view.IViewTrafficLight import com.mogo.eagle.core.function.api.hmi.warning.IMoGoHmiProvider import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener -import com.zhjt.service_biz.BizConfig /** * @author xiaoyuzhou @@ -37,42 +32,6 @@ object CallerHmiManager { waringProviderApi?.displayEffects() } - /** - * 隐藏 脉速表 - * @param visibility View.VISIBLE, View.INVISIBLE,View.GONE - */ - fun setSpeedChartViewVisibility(visibility: Int) { - waringProviderApi?.setSpeedChartViewVisibility(visibility) - } - - /** - * 隐藏 自动驾驶触发 按钮 - * @param visibility View.VISIBLE, View.INVISIBLE,View.GONE - */ - fun setAutopilotStatusViewVisibility(visibility: Int) { - waringProviderApi?.setAutopilotStatusViewVisibility(visibility) - } - - /** - * 隐藏 切换视角 按钮 - * @param visibility View.VISIBLE, View.INVISIBLE,View.GONE - */ - fun setPerspectiveSwitchViewVisibility(visibility: Int) { - waringProviderApi?.setPerspectiveSwitchViewVisibility(visibility) - } - - /** - * 隐藏 工具箱 按钮 - * @param visibility View.VISIBLE, View.INVISIBLE,View.GONE - */ - fun setToolsViewVisibility(visibility: Int) { - waringProviderApi?.setToolsViewVisibility(visibility) - } - - fun setCameraViewVisibility(visibility: Int) { - waringProviderApi?.setCameraViewVisibility(visibility) - } - /** * 控制转向灯功能 */ @@ -200,24 +159,6 @@ object CallerHmiManager { waringProviderApi?.changeCountdownTrafficLightNum(readNum, yellowNum, greenNum) } - /** - * 展示限速预警 - * - * @param limitingSpeed 限速速度 - * @param limitSpeedSource 限速来源 1:MAP, 2:RSU - */ - @BizConfig(V2I, "", BIZ_SLW) - fun showLimitingVelocity(limitingSpeed: Int, limitSpeedSource: Int) { - waringProviderApi?.showLimitingVelocity(limitingSpeed, limitSpeedSource) - } - - /** - * 关闭限速预警 - */ - fun disableLimitingVelocity() { - waringProviderApi?.disableLimitingVelocity() - } - /** * 展示指定方位上的红框预警 * @param direction @@ -346,14 +287,6 @@ object CallerHmiManager { waringProviderApi?.setProxyTrafficLightView(view) } - /** - * 设置 限速 代理View - * @param view - */ - fun setProxyLimitingSpeedView(view: IViewLimitingVelocity) { - waringProviderApi?.setProxyLimitingSpeedView(view) - } - /** * 展示工控机监控上报数据 * @param errorReportList 错误级别上报数据列表 diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallLimitingVelocityListenerManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallLimitingVelocityListenerManager.kt deleted file mode 100644 index 726288cd2d..0000000000 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallLimitingVelocityListenerManager.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.mogo.eagle.core.function.call.v2x - -import com.mogo.eagle.core.function.api.v2x.LimitingVelocityListener -import com.mogo.eagle.core.function.call.base.CallerBase - -/** - * 限速信息监听 - */ -object CallLimitingVelocityListenerManager : CallerBase() { - - private const val TAG = "CallLimitingVelocityListenerManager" - - private var mCurrentLimitingVelocity = 0 - - override fun doSomeAfterAddListener(tag: String, listener: LimitingVelocityListener) { - listener.onLimitingVelocityChange(mCurrentLimitingVelocity) - } - - fun invokeOnLimitingVelocityChange(limitingVelocity: Int) { - this.mCurrentLimitingVelocity = limitingVelocity - M_LISTENERS.forEach { - val tag = it.key - //LogUtils.dTag(TAG, "invokeOnLimitingVelocityChange tag is : $tag") - val listener = it.value - listener.onLimitingVelocityChange(limitingVelocity) - } - } - -} \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallObuLimitingSpeedListenerManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallObuLimitingSpeedListenerManager.kt deleted file mode 100644 index 1a33b7af68..0000000000 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallObuLimitingSpeedListenerManager.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.mogo.eagle.core.function.call.v2x - -import com.mogo.eagle.core.function.api.v2x.ObuLimitingSpeedListener -import com.mogo.eagle.core.function.call.base.CallerBase -import java.util.concurrent.ConcurrentHashMap - -/** - * 限速信息监听 - */ -object CallObuLimitingSpeedListenerManager : CallerBase(){ - - private const val TAG = "CallObuLimitingSpeedListenerManager" - private val M_TRAFFIC_LIGHT_LISTENER: ConcurrentHashMap = - ConcurrentHashMap() - private var mObuLimitSpeed = 0 - - fun invokeOnObuLimitingSpeedChange(limitingSpeed: Int) { - this.mObuLimitSpeed = limitingSpeed - M_TRAFFIC_LIGHT_LISTENER.forEach { - val tag = it.key - val listener = it.value - listener.onObuLimitingSpeedChange(limitingSpeed) - } - } - -} \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallerLimitingVelocityListenerManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallerLimitingVelocityListenerManager.kt new file mode 100644 index 0000000000..4d9211b39c --- /dev/null +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallerLimitingVelocityListenerManager.kt @@ -0,0 +1,28 @@ +package com.mogo.eagle.core.function.call.v2x + +import com.mogo.eagle.core.data.enums.DataSourceType +import com.mogo.eagle.core.function.api.v2x.ILimitingVelocityListener +import com.mogo.eagle.core.function.call.base.CallerBase + +/** + * 限速信息监听 + */ +object CallerLimitingVelocityListenerManager : CallerBase() { + + private var mCurrentLimitingVelocity = 0 + private var sourceType = DataSourceType.DEFAULT + + override fun doSomeAfterAddListener(tag: String, listener: ILimitingVelocityListener) { + listener.onLimitingVelocityChange(mCurrentLimitingVelocity, sourceType) + } + + fun invokeOnLimitingVelocityChange(limitingVelocity: Int, sourceType: DataSourceType) { + this.mCurrentLimitingVelocity = limitingVelocity + this.sourceType = sourceType + M_LISTENERS.forEach { + val listener = it.value + listener.onLimitingVelocityChange(limitingVelocity, sourceType) + } + } + +} \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallerViewLimitingVelocityListenerManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallerViewLimitingVelocityListenerManager.kt new file mode 100644 index 0000000000..cdfbe782b8 --- /dev/null +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/v2x/CallerViewLimitingVelocityListenerManager.kt @@ -0,0 +1,28 @@ +package com.mogo.eagle.core.function.call.v2x + +import com.mogo.eagle.core.data.enums.DataSourceType +import com.mogo.eagle.core.function.api.v2x.ILimitingVelocityListener +import com.mogo.eagle.core.function.call.base.CallerBase + +/** + * 限速信息监听 + */ +object CallerViewLimitingVelocityListenerManager : CallerBase() { + + private var mCurrentLimitingVelocity = 0 + private var sourceType = DataSourceType.DEFAULT + + override fun doSomeAfterAddListener(tag: String, listener: ILimitingVelocityListener) { + listener.onLimitingVelocityChange(mCurrentLimitingVelocity, sourceType) + } + + fun invokeOnLimitingVelocityChange(limitingVelocity: Int, sourceType: DataSourceType) { + this.mCurrentLimitingVelocity = limitingVelocity + this.sourceType = sourceType + M_LISTENERS.forEach { + val listener = it.value + listener.onLimitingVelocityChange(limitingVelocity, sourceType) + } + } + +} \ No newline at end of file From 66db271f6c16ec8c1921950b794427f16c989184 Mon Sep 17 00:00:00 2001 From: zhongchao Date: Mon, 30 Jan 2023 22:29:40 +0800 Subject: [PATCH 30/48] [2.13.0-arch-opt] merg --- .../src/main/res/layout/bus_base_fragment.xml | 1 + OCH/mogo-och-noop/build.gradle | 19 ++++++++---- .../java/com/mogo/och/noop/OCHConstants.java | 2 +- .../java/com/mogo/och/noop/OchNoopFragment.kt | 3 +- .../main/res/layout/och_noop_fragment_hmi.xml | 12 +++---- .../main/res/layout/taxi_base_fragment.xml | 1 + app/productFlavors/fPadLenovo.gradle | 2 +- .../eagle/function/biz/FuncBizProvider.kt | 6 ++-- .../v2x/speedlimit/SpeedLimitDispatcher.kt | 2 +- .../mogo-core-function-hmi/build.gradle | 1 - .../receiver/V2XWarningBroadcastReceiver.kt | 4 ++- .../function/hmi/ui/tools/ToolsImageView.kt | 2 +- .../hmi/ui/widget/AutoPilotStatusView.kt | 7 +---- .../function/main/MainLauncherActivity.java | 6 +++- .../res/layout/view_limiting_speed_vr.xml | 8 ++--- .../business}/SpeedLimitDataManager.java | 31 +++++++------------ .../eagle/core/function/map/MapFragment.kt | 3 ++ 17 files changed, 52 insertions(+), 58 deletions(-) rename core/function-impl/{mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit => mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business}/SpeedLimitDataManager.java (61%) diff --git a/OCH/mogo-och-bus/src/main/res/layout/bus_base_fragment.xml b/OCH/mogo-och-bus/src/main/res/layout/bus_base_fragment.xml index 8cc5bfec82..da6d779a3b 100644 --- a/OCH/mogo-och-bus/src/main/res/layout/bus_base_fragment.xml +++ b/OCH/mogo-och-bus/src/main/res/layout/bus_base_fragment.xml @@ -68,6 +68,7 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/hmi_traffic_light_layout_margin_top" android:layout_marginEnd="@dimen/hmi_traffic_light_layout_margin_right" + android:visibility="gone" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/OCH/mogo-och-noop/build.gradle b/OCH/mogo-och-noop/build.gradle index d9254953fe..835c4f0715 100644 --- a/OCH/mogo-och-noop/build.gradle +++ b/OCH/mogo-och-noop/build.gradle @@ -1,5 +1,10 @@ -apply plugin: 'com.android.library' -apply plugin: 'com.alibaba.arouter' +plugins { + id 'com.android.library' + id 'kotlin-android' + id 'kotlin-android-extensions' + id 'kotlin-kapt' + id 'com.alibaba.arouter' +} android { compileSdkVersion rootProject.ext.android.compileSdkVersion @@ -13,10 +18,11 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" - - javaCompileOptions { - annotationProcessorOptions { - arguments = [AROUTER_MODULE_NAME: project.getName()] + //ARouter apt 参数 + kapt { + useBuildCache = false + arguments { + arg("AROUTER_MODULE_NAME", project.getName()) } } } @@ -43,6 +49,7 @@ dependencies { implementation rootProject.ext.dependencies.arouter annotationProcessor rootProject.ext.dependencies.aroutercompiler + kapt rootProject.ext.dependencies.aroutercompiler if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { implementation rootProject.ext.dependencies.mogoutils diff --git a/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OCHConstants.java b/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OCHConstants.java index b0893ba9f8..8a5d17c35a 100644 --- a/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OCHConstants.java +++ b/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OCHConstants.java @@ -12,5 +12,5 @@ class OCHConstants { /** * arouter 路由地址 */ - public static final String PATH = "/och/noop/api"; + public static final String PATH = "/noop/api"; } diff --git a/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OchNoopFragment.kt b/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OchNoopFragment.kt index 26b72274dc..745f4e0ab3 100644 --- a/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OchNoopFragment.kt +++ b/OCH/mogo-och-noop/src/main/java/com/mogo/och/noop/OchNoopFragment.kt @@ -3,7 +3,7 @@ package com.mogo.och.noop import android.view.View import com.mogo.commons.mvp.MvpFragment import com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugView -import kotlinx.android.synthetic.main.fragment_hmi.* +import kotlinx.android.synthetic.main.och_noop_fragment_hmi.* class OchNoopFragment : MvpFragment(), OchNoopContract.View { @@ -25,7 +25,6 @@ class OchNoopFragment : MvpFragment(), } override fun initViews() { - viewShowDebugView.setOnLongClickListener { ToggleDebugView.toggleDebugView.toggle(requireContext()) true diff --git a/OCH/mogo-och-noop/src/main/res/layout/och_noop_fragment_hmi.xml b/OCH/mogo-och-noop/src/main/res/layout/och_noop_fragment_hmi.xml index fb1bec67f4..34c117a11e 100644 --- a/OCH/mogo-och-noop/src/main/res/layout/och_noop_fragment_hmi.xml +++ b/OCH/mogo-och-noop/src/main/res/layout/och_noop_fragment_hmi.xml @@ -67,8 +67,7 @@ android:layout_marginTop="@dimen/module_mogo_autopilot_status_margin_top" android:elevation="@dimen/dp_10" app:layout_constraintLeft_toLeftOf="@+id/viewSpeedChart" - app:layout_constraintTop_toBottomOf="@+id/viewSpeedChart" - app:layout_goneMarginStart="@dimen/module_mogo_autopilot_status_margin_left" /> + app:layout_constraintTop_toBottomOf="@+id/viewSpeedChart"/> + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toBottomOf="@+id/ivCameraIcon" /> diff --git a/app/productFlavors/fPadLenovo.gradle b/app/productFlavors/fPadLenovo.gradle index 3f81f59165..1ad7d6b469 100644 --- a/app/productFlavors/fPadLenovo.gradle +++ b/app/productFlavors/fPadLenovo.gradle @@ -24,7 +24,7 @@ project.android.productFlavors { buildConfigField 'int', 'GPS_PROVIDER', "1" // 构建的应用身份类型,具体查看 README.md APP_IDENTITY_MODE规则 - buildConfigField 'String', 'APP_IDENTITY_MODE', "\"Taxi_Driver_Base\"" + buildConfigField 'String', 'APP_IDENTITY_MODE', "\"FPad_Noop_Base\"" // 连接的工控机IP地址 buildConfigField 'String', 'ADAS_CONNECT_IP', "\"192.168.1.104\"" // 构建的是否是演示(美化)模式 diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/FuncBizProvider.kt b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/FuncBizProvider.kt index 528509bea4..d0831a75ef 100644 --- a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/FuncBizProvider.kt +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/FuncBizProvider.kt @@ -10,7 +10,6 @@ import com.mogo.eagle.function.biz.dispatch.DispatchAutoPilotManager.Companion.d import com.mogo.eagle.function.biz.monitoring.CronTaskManager.Companion.cronTaskManager import com.mogo.eagle.function.biz.notice.NoticeSocketManager.Companion.noticeSocketManager import com.mogo.eagle.function.biz.notice.network.NoticeNetWorkManager -import com.mogo.eagle.function.biz.v2x.speedlimit.SpeedLimitDataManager import com.mogo.eagle.function.biz.v2x.speedlimit.SpeedLimitDispatcher import com.mogo.eagle.function.biz.v2x.trafficlight.core.MogoTrafficLightManager import com.mogo.eagle.function.biz.v2x.trafficlight.core.TrafficLightDispatcher @@ -28,10 +27,9 @@ class FuncBizProvider : IMoGoFuncBizProvider { cronTaskManager.startCronTask() MogoTrafficLightManager.INSTANCE.initServer(context) - TrafficLightDispatcher.INSTANCE.initServer(context) //todo 红绿灯中心模块放入dataCenter VipCarManager.INSTANCE.initServer(context) - SpeedLimitDataManager.getInstance().start() - SpeedLimitDispatcher.INSTANCE.initLimit(context) + TrafficLightDispatcher.INSTANCE.initServer(context) //todo 宏宇 放入dataCenter + SpeedLimitDispatcher.INSTANCE.initLimit(context) //todo 宏宇,放入dataCenter // RedLightWarningManager.INSTANCE.listenTrafficLight() } diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDispatcher.kt b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDispatcher.kt index 47e491ac75..cc61f8f8b3 100644 --- a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDispatcher.kt +++ b/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDispatcher.kt @@ -34,7 +34,7 @@ class SpeedLimitDispatcher : ILimitingVelocityListener { /** * 地图限速数据 */ - @BizConfig(FuncBizConfig.V2I, "", FuncBizConfig.BIZ_SLW) +// @BizConfig(FuncBizConfig.V2I, "", FuncBizConfig.BIZ_SLW) //todo arrow 重新考虑放的位置 override fun onLimitingVelocityChange(limitingVelocity: Int, sourceType: DataSourceType) { when (sourceType) { // obu 优先级高于 map,体现链路能力 DataSourceType.OBU -> { diff --git a/core/function-impl/mogo-core-function-hmi/build.gradle b/core/function-impl/mogo-core-function-hmi/build.gradle index cfbb042e0e..d5bdc3d080 100644 --- a/core/function-impl/mogo-core-function-hmi/build.gradle +++ b/core/function-impl/mogo-core-function-hmi/build.gradle @@ -108,7 +108,6 @@ dependencies { api project(':core:function-impl:mogo-core-function-chat') api project(':core:function-impl:mogo-core-function-datacenter') api project(':core:function-impl:mogo-core-function-biz') - api project(':core:mogo-core-function-call') api project(':libraries:mogo-adas') api project(':libraries:map-usbcamera') diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XWarningBroadcastReceiver.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XWarningBroadcastReceiver.kt index 30f289c218..fefd2b4366 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XWarningBroadcastReceiver.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/receiver/V2XWarningBroadcastReceiver.kt @@ -4,6 +4,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log +import com.mogo.eagle.core.data.enums.DataSourceType import com.mogo.eagle.core.data.enums.EventTypeEnumNew import com.mogo.eagle.core.function.call.hmi.CallerHmiManager import com.mogo.eagle.core.function.hmi.WaringConst @@ -13,6 +14,7 @@ import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.V2XMsg import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager +import com.mogo.eagle.core.function.call.v2x.CallerViewLimitingVelocityListenerManager /** * V2X 预警广播接收。用于跨应用,跨进程,内部也可以通过这种方式弹出预警提示框 @@ -76,7 +78,7 @@ class V2XWarningBroadcastReceiver : BroadcastReceiver() { tag: String? ) { if (EventTypeEnumNew.TYPE_USECASE_ID_IVP_RED.poiType == v2xType.toString()) { - CallerHmiManager.showLimitingVelocity(1, 1) + CallerViewLimitingVelocityListenerManager.invokeOnLimitingVelocityChange(1,DataSourceType.MAP) } if (alertContent.isNullOrEmpty() || ttsContent.isNullOrEmpty()) { Log.d("MsgBox-V2XWarningBR", "alertContent或ttsContent为空!") diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt index 2e8b24e018..5623ea7559 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/ToolsImageView.kt @@ -10,9 +10,9 @@ class ToolsImageView(context: Context, attrs: AttributeSet?) : override fun onAttachedToWindow() { super.onAttachedToWindow() + scaleType = ScaleType.CENTER setBackgroundResource(R.drawable.module_ext_check) setImageResource(R.drawable.icon_tools_nor) - scaleType = ScaleType.CENTER setOnClickListener{ toolsView.showToolsFloat(context) } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/AutoPilotStatusView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/AutoPilotStatusView.kt index 2ff479a1c7..76b47b683c 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/AutoPilotStatusView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/AutoPilotStatusView.kt @@ -38,18 +38,13 @@ class AutoPilotStatusView constructor( private var mAutopilotStatus: Int = 0 - override fun onAttachedToWindow() { - super.onAttachedToWindow() + init{ initView(context) } private fun initView(context: Context) { setBackgroundResource(R.drawable.module_hmi_autopilot_status_bg) LayoutInflater.from(context).inflate(R.layout.view_autopilot_status, this, true) - - val lp = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT) - layoutParams = lp - // 设置点击监听 setOnClickListener(this) // 自动驾驶状态监听 diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainLauncherActivity.java b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainLauncherActivity.java index d87460910c..18977a81a3 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainLauncherActivity.java +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/main/MainLauncherActivity.java @@ -149,10 +149,14 @@ public class MainLauncherActivity extends MainActivity implements IMogoIntentLis ochProvider = (IMoGoFunctionProvider) ARouter.getInstance() .build("/driver/api") .navigation(getContext()); - } else { + } else if(AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)){ ochProvider = (IMoGoFunctionProvider) ARouter.getInstance() .build("/passenger/api") .navigation(getContext()); + } else { + ochProvider = (IMoGoFunctionProvider) ARouter.getInstance() + .build("/noop/api") + .navigation(getContext()); } } // 处理一个机器多个屏幕方案 diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_limiting_speed_vr.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_limiting_speed_vr.xml index 1b5042bf60..e3c35e2bfc 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_limiting_speed_vr.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_limiting_speed_vr.xml @@ -14,9 +14,7 @@ android:gravity="center" android:text="60" android:textColor="#FFFFFF" - android:textSize="@dimen/dp_60" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toBottomOf="@+id/ivCameraIcon" /> + android:textSize="@dimen/dp_60"/> + android:visibility="gone" /> \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDataManager.java b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/SpeedLimitDataManager.java similarity index 61% rename from core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDataManager.java rename to core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/SpeedLimitDataManager.java index 385cfb841e..950ed0e66f 100644 --- a/core/function-impl/mogo-core-function-biz/src/main/java/com/mogo/eagle/function/biz/v2x/speedlimit/SpeedLimitDataManager.java +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/SpeedLimitDataManager.java @@ -1,17 +1,15 @@ -package com.mogo.eagle.function.biz.v2x.speedlimit; - -import static com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.BIZ_SLW; -import static com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.V2I; +package com.mogo.eagle.core.function.business; import androidx.annotation.Nullable; +import com.mogo.eagle.core.data.enums.DataSourceType; import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener; import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ20ListenerManager; import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager; import com.mogo.eagle.core.function.call.v2x.CallerLimitingVelocityListenerManager; import com.mogo.eagle.core.utilcode.util.UiThreadHandler; -import com.zhjt.service_biz.BizConfig; +import java.util.Objects; import java.util.Timer; import java.util.TimerTask; @@ -25,8 +23,8 @@ import mogo.telematics.pad.MessagePad; public class SpeedLimitDataManager implements IMoGoChassisLocationGCJ02Listener { private final static String TAG = "SpeedLimitDataManager"; - private static SpeedLimitDataManager instance; - private MessagePad.GnssInfo mLocation; + private static volatile SpeedLimitDataManager instance; + private MessagePad.GnssInfo mLocation; private SpeedLimitDataManager() { } @@ -51,24 +49,19 @@ public class SpeedLimitDataManager implements IMoGoChassisLocationGCJ02Listener @Override public void run() { if (mLocation != null) { - if(CallerMapUIServiceManager.INSTANCE.getMapUIController()!=null){ + if (CallerMapUIServiceManager.INSTANCE.getMapUIController() != null) { getSpeedLimit(); } } } - @BizConfig(biz = V2I, dependentBizNode = "", bizNode = BIZ_SLW) private void getSpeedLimit() { -// if (!isShowObuLimitSpeedView) { - int speedLimit = CallerMapUIServiceManager.INSTANCE.getMapUIController().getLimitSpeed(mLocation.getLongitude(), mLocation.getLatitude(), (float) mLocation.getHeading()); - UiThreadHandler.post(() -> { - if (speedLimit > 0) { -// CallerHmiManager.INSTANCE.showLimitingVelocity(speedLimit, 1); - CallerLimitingVelocityListenerManager.INSTANCE.invokeOnLimitingVelocityChange(speedLimit); - - } - }); -// } + int speedLimit = Objects.requireNonNull(CallerMapUIServiceManager.INSTANCE.getMapUIController()).getLimitSpeed(mLocation.getLongitude(), mLocation.getLatitude(), (float) mLocation.getHeading()); + UiThreadHandler.post(() -> { + if (speedLimit > 0) { + CallerLimitingVelocityListenerManager.INSTANCE.invokeOnLimitingVelocityChange(speedLimit, DataSourceType.MAP); + } + }); } } diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/map/MapFragment.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/map/MapFragment.kt index a6cb1e9874..0591bc9c92 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/map/MapFragment.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/map/MapFragment.kt @@ -15,6 +15,7 @@ import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener import com.mogo.eagle.core.function.api.map.hd.IMoGoMapFragmentProvider import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener import com.mogo.eagle.core.function.business.MapPointCloudSubscriber +import com.mogo.eagle.core.function.business.SpeedLimitDataManager import com.mogo.eagle.core.function.business.identify.MapIdentifySubscriber import com.mogo.eagle.core.function.business.routeoverlay.MogoRouteOverlayManager import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager @@ -199,6 +200,8 @@ class MapFragment : MvpFragment(), MapIdentifySubscriber.instance MogoRouteOverlayManager.getInstance().init() MapPointCloudSubscriber.instance + SpeedLimitDataManager.getInstance().start() + // TODO GD地图业务需要与高精地图业务拆开 --- 扶风 queryInfStructure() } From a8cfaa8fff88a45f30770178abdbf1c4a6e3a401 Mon Sep 17 00:00:00 2001 From: donghongyu Date: Tue, 31 Jan 2023 10:43:13 +0800 Subject: [PATCH 31/48] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0]=20[Change]=20[?= =?UTF-8?q?=201=E3=80=81=E4=BF=AE=E5=A4=8D=E5=90=88=E5=B9=B6=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=20]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: donghongyu --- .../core/function/datacenter/obu/MogoPrivateObuNewManager.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuNewManager.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuNewManager.kt index c06aacde0b..503a372c83 100644 --- a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuNewManager.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/obu/MogoPrivateObuNewManager.kt @@ -18,7 +18,7 @@ import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager import com.mogo.eagle.core.function.call.obu.CallerObuListenerManager import com.mogo.eagle.core.function.call.obu.CallerObuTrafficLightListenerManager import com.mogo.eagle.core.function.call.v2x.CallerLimitingVelocityListenerManager -import com.mogo.eagle.core.function.obu.mogo.utils.TrafficDataConvertUtilsNew +import com.mogo.eagle.core.function.datacenter.obu.utils.TrafficDataConvertUtilsNew import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OBU import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr From 6bc41b01fa05162f5a4df680ad9e1e8e6d4410cb Mon Sep 17 00:00:00 2001 From: donghongyu Date: Tue, 31 Jan 2023 11:45:10 +0800 Subject: [PATCH 32/48] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0]=20[Change]=20[?= =?UTF-8?q?=201=E3=80=81TODO=20=E6=B8=85=E6=89=AB=E8=BD=A6=E9=99=90?= =?UTF-8?q?=E9=80=9F=E6=9C=89=E9=97=AE=E9=A2=98=20]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: donghongyu --- .../com/mogo/och/sweeper/view/SweeperTrafficDataView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java index 23cc010b44..580b3417e5 100644 --- a/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java +++ b/OCH/mogo-och-sweeper/src/main/java/com/mogo/och/sweeper/view/SweeperTrafficDataView.java @@ -147,8 +147,8 @@ public class SweeperTrafficDataView extends ConstraintLayout @Override public void onLimitingVelocityChange(int limitingVelocity, DataSourceType sourceType) { - //设置限速 - sweeperLimitingVelocity.updateLimitingSpeed(limitingVelocity, 0); + //设置限速 TODO @钟超 + //sweeperLimitingVelocity.updateLimitingSpeed(limitingVelocity, 0); } }; /** From e01716f30ac7f8ba7affa7c6ccf67d2314708852 Mon Sep 17 00:00:00 2001 From: renwj Date: Tue, 31 Jan 2023 12:20:42 +0800 Subject: [PATCH 33/48] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0][v2x]v2x=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/AndroidManifest.xml | 2 +- .../function/v2x/events/V2XEventManager.kt | 68 ++--------- .../v2x/events/alarm/V2XAlarmServer.java | 19 +-- .../function/v2x/events/bridge/BridgeApi.kt | 13 -- .../events/manager/IMoGoV2XMarkerManager.java | 21 ---- .../manager/IMoGoV2XPolylineManager.java | 31 ----- .../IMoGoV2XStatusChangedListener.java | 19 --- .../events/manager/IMoGoV2XStatusManager.java | 34 ------ .../events/manager/V2XStatusDescriptor.java | 70 ----------- .../v2x/events/manager/V2XStatusManager.java | 61 ---------- .../manager/impl/MoGoV2XMarkerManager.java | 88 +------------- .../manager/impl/MoGoV2XPolylineManager.java | 114 ------------------ .../manager/impl/MoGoV2XStatusManager.java | 100 --------------- .../v2x/events/marker/V2XMarkerAdapter.java | 24 ---- .../events/observer/CarLocationObserver.java | 13 -- .../observer/V2XOptimalRouteObserver.java | 50 -------- .../overlay/V2XOptimalRouteOverlay.java | 77 ------------ .../MarkerRemoveManager.kt} | 4 +- .../scenario/impl/V2XScenarioManager.java | 6 - .../scenario/scene/airoad/AiRoadMarker.kt | 9 +- .../scene/road/V2XAiRoadEventMarker.kt | 2 +- .../scene/road/V2XRoadEventMarker.java | 22 +--- .../scene/road/V2XRoadEventScenario.java | 33 +---- .../route/V2XOptimalRouteVREventMarker.java | 54 --------- .../route/V2XOptimalRouteVREventScenario.java | 106 ---------------- .../warning/V2XFrontWarningScenario.java | 2 - .../scene/warning/V2XWarningMarker.java | 19 --- .../v2x/events/scenario/view/IV2XMarker.java | 3 - .../{utils => test}/TestOnLineCarUtils.java | 2 +- .../TestV2XReceiver.java} | 13 +- .../function/v2x/events/utils/TrackUtils.java | 1 - 31 files changed, 42 insertions(+), 1038 deletions(-) delete mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XPolylineManager.java delete mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XStatusChangedListener.java delete mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XStatusManager.java delete mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/V2XStatusDescriptor.java delete mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/V2XStatusManager.java delete mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/impl/MoGoV2XPolylineManager.java delete mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/impl/MoGoV2XStatusManager.java delete mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/observer/CarLocationObserver.java delete mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/observer/V2XOptimalRouteObserver.java delete mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/overlay/V2XOptimalRouteOverlay.java rename core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/{marker/MarkerManager.kt => remove/MarkerRemoveManager.kt} (98%) delete mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/route/V2XOptimalRouteVREventMarker.java delete mode 100644 core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/route/V2XOptimalRouteVREventScenario.java rename core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/{utils => test}/TestOnLineCarUtils.java (99%) rename core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/{receiver/TestPanelBroadcastReceiver.java => test/TestV2XReceiver.java} (87%) diff --git a/core/function-impl/mogo-core-function-v2x/src/main/AndroidManifest.xml b/core/function-impl/mogo-core-function-v2x/src/main/AndroidManifest.xml index 6ccd24e6c8..246d716c51 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/AndroidManifest.xml +++ b/core/function-impl/mogo-core-function-v2x/src/main/AndroidManifest.xml @@ -2,7 +2,7 @@ - + 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 c67989c8b8..d8789a5797 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 @@ -36,10 +36,8 @@ import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager import com.mogo.eagle.core.function.v2x.events.alarm.* import com.mogo.eagle.core.function.v2x.events.bridge.* import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi.context -import com.mogo.eagle.core.function.v2x.events.consts.* import com.mogo.eagle.core.function.v2x.events.consts.V2XConst.* import com.mogo.eagle.core.function.v2x.events.manager.* -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.utils.* @@ -49,12 +47,10 @@ 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.function.v2x.road.V2XEventServiceApi import com.mogo.eagle.core.network.MoGoRetrofitFactory -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 import com.mogo.eagle.core.utilcode.util.* @@ -132,7 +128,6 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IMoGoTokenCallback, private fun unRegisterListener() { V2XManager.removeCallback(this) CallerChassisLocationGCJ20ListenerManager.removeListener(TAG) - mogoMarkersHandler.unregisterMarkerClickListener(CARD_TYPE_ROAD_CONDITION) } @@ -161,8 +156,8 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IMoGoTokenCallback, v2XMessageEntity.isOnlyShow = true v2XMessageEntity.isNeedAddLine = false v2XMessageEntity.content = roadEventEntity - val intent = Intent(V2XConst.BROADCAST_SCENE_HANDLER_ACTION) - intent.putExtra(V2XConst.BROADCAST_SCENE_EXTRA_KEY, v2XMessageEntity) + val intent = Intent(BROADCAST_SCENE_HANDLER_ACTION) + intent.putExtra(BROADCAST_SCENE_EXTRA_KEY, v2XMessageEntity) LocalBroadcastManager.getInstance(context()).sendBroadcast(intent) //埋点 TrackUtils.trackV2XMarkerClick(2) @@ -193,18 +188,6 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IMoGoTokenCallback, return null } - /** - * 刷新自车求助状态 - * - * @param isTrue - */ - private fun refreshMeSeekHelp(isTrue: Boolean) { - val entity = V2XMessageEntity() - entity.type = V2XMessageEntity.V2XTypeEnum.ALERT_CAR_FOR_HELP - entity.content = isTrue - V2XScenarioManager.getInstance().handlerMessage(entity) - } - override fun onChassisLocationGCJ02(gnssInfo: GnssInfo?) { val location = CallerMapLocationListenerManager.getCurrentLocation() ?: return BridgeApi.location.set(location) @@ -214,34 +197,12 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IMoGoTokenCallback, latitude = location.latitude ) } - V2XOptimalRouteObserver.getInstance().update(location) refreshCarState(location) } private fun refreshCarState(location: MogoLocation) { - V2XStatusManager.getInstance().location = location - val v2xPolyline = BridgeApi.v2xPolyline()?.mogoPolyline - val isRoadEventPOIShow = BridgeApi.v2xStatus()?.isRoadEventPOIShow ?: false - val v2xStatusManager = V2XStatusManager.getInstance() - if (v2xPolyline != null && (isRoadEventPOIShow) && v2xStatusManager.targetMoGoLatLng != null) { // 取出原有的绘制线的经纬度点 - // 取出原有的绘制线的经纬度点 - val pointsOdl: MutableList = v2xPolyline.points // 重新设置第一个坐标,也就是当前车辆位置 - // 重新设置第一个坐标,也就是当前车辆位置 - pointsOdl[0] = MogoLatLng(location.latitude, location.longitude) - v2xPolyline.points = pointsOdl - //CallerLogger.d("$M_V2X$TAG", "当前地图的缩放比例为:" + zoomLevel); - val zoomLevel: Float = CallerMapUIServiceManager.getMapUIController()?.zoomLevel ?: 0.0f - //CallerLogger.d("$M_V2X$TAG", "当前地图的缩放比例为:" + zoomLevel); - if (zoomLevel > 0 && zoomLevel <= 17) { // 缩放地图 - val context: Context = context() - MapUtils.zoomMap(v2xStatusManager.targetMoGoLatLng, context) - } - } - // 巡航处理 val v2XRoadEventEntity = V2XAlarmServer.getDriveFrontAlarmEvent( - BridgeApi.v2xMarker()?.v2XRoadEventEntityList, - V2XStatusManager.getInstance().location - ) + BridgeApi.v2xMarker()?.v2XRoadEventEntityList, location) if (v2XRoadEventEntity != null) { val distance = v2XRoadEventEntity.distance val min = if (EventTypeEnumNew.isCloudSocketEvent(v2XRoadEventEntity.poiType)) 0 else 5 @@ -287,9 +248,6 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IMoGoTokenCallback, is V2XEvent.ForwardsWarning -> { handleAdvanceWarningEvent(event) } - is V2XEvent.OptimalRoute -> { - handleOptimalRouteEvent(event) - } is V2XEvent.Marker -> { event.data.result?.let { handleRoadMarkerEvent(it) @@ -313,6 +271,9 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IMoGoTokenCallback, is V2XEvent.RoadEventX -> { handleRoadMarkerEvent(event.data.toRoadMarker()) } + else -> { + Logger.d(TAG, "other event: $event") + } } } private fun handleWarningTargetEvent(data: V2XWarningTarget) { @@ -335,17 +296,6 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IMoGoTokenCallback, } } - private fun handleOptimalRouteEvent(event: V2XEvent.OptimalRoute) { - val v2xMessageEntity: V2XMessageEntity = - V2XMessageEntity() // 控制类型 - v2xMessageEntity.type = V2XMessageEntity.V2XTypeEnum.ALERT_PUSH_VR_SHOW // 设置数据 - v2xMessageEntity.content = event.data // 控制展示状态 - v2xMessageEntity.isShowState = true - val intent = Intent(BROADCAST_SCENE_HANDLER_ACTION) - intent.putExtra(BROADCAST_SCENE_EXTRA_KEY, v2xMessageEntity) - LocalBroadcastManager.getInstance(Utils.getApp()).sendBroadcast(intent) - } - private fun handleAdvanceWarningEvent(event: V2XEvent.ForwardsWarning) { scope.launch { val message = event.data @@ -375,12 +325,10 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IMoGoTokenCallback, } 1003 -> { // 交叉路口碰撞预警 - /* - TODO xiaopeng 先注掉,编译通过 changeVisualAngle = true tempAppId = EventTypeEnumNew.TYPE_USECASE_ID_ICW.poiType.toInt() tempTts = EventTypeEnumNew.TYPE_USECASE_ID_ICW.tts - tempContent = EventTypeEnumNew.TYPE_USECASE_ID_ICW.content*/ + tempContent = EventTypeEnumNew.TYPE_USECASE_ID_ICW.content } 1004 -> { // 交叉路口碰撞预警 @@ -422,7 +370,7 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IMoGoTokenCallback, } } // 不显示弹框,其它保留 - if (tempContent.isNullOrEmpty() || tempTts.isNullOrEmpty()) { + if (tempContent.isEmpty() || tempTts.isEmpty()) { Log.d("MsgBox-V2XEventManager", "alertContent或ttsContent为空!") } CallerMsgBoxManager.saveMsgBox( diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/alarm/V2XAlarmServer.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/alarm/V2XAlarmServer.java index c4f2ca6de0..386e2116ec 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/alarm/V2XAlarmServer.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/alarm/V2XAlarmServer.java @@ -6,6 +6,7 @@ import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import com.mogo.eagle.core.data.map.MogoLocation; import com.mogo.eagle.core.data.map.entity.MarkerLocation; import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity; +import com.mogo.eagle.core.utilcode.mogo.logger.Logger; import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils; import java.util.Iterator; @@ -27,6 +28,8 @@ import io.netty.util.internal.ConcurrentSet; */ public class V2XAlarmServer { + private static final String TAG = "V2XAlarmServer"; + // 记录道路播报的事件 private static final ConcurrentSet showedEvents = new ConcurrentSet<>(); /** @@ -36,7 +39,7 @@ public class V2XAlarmServer { CopyOnWriteArrayList v2XRoadEventEntityList, MogoLocation currentLocation) { try { - Log.d("RWJ", "getDriveFrontAlarmEvent --- 1 ---" + currentLocation ); + Logger.d(TAG, "getDriveFrontAlarmEvent --- 1 ---" + currentLocation ); if (!showedEvents.isEmpty()) { Iterator iterator = showedEvents.iterator(); while (iterator.hasNext()) { @@ -53,18 +56,18 @@ public class V2XAlarmServer { } } } - Log.d("RWJ", "getDriveFrontAlarmEvent --- 2 ---" + currentLocation); + Logger.d(TAG, "getDriveFrontAlarmEvent --- 2 ---" + currentLocation); if (currentLocation != null && v2XRoadEventEntityList != null) { // 因为集合是按照距离排序后的所以这里检索出来第一个就发出警告 for (V2XRoadEventEntity v2XRoadEventEntity : v2XRoadEventEntityList) { // 0、道路事件必须有朝向,角度>=0; - Log.d("RWJ", "entity:" + v2XRoadEventEntity.getLocation()); + Logger.d(TAG, "entity:" + v2XRoadEventEntity.getLocation()); if (v2XRoadEventEntity.getLocation().getAngle() >= 0) { // 计算车辆距离指定气泡的距离 MarkerLocation eventLocation = v2XRoadEventEntity.getLocation(); // 1、判断是否到达了触发距离,20 ~ 500, double distance = v2XRoadEventEntity.getDistance(); - Log.d("RWJ", "distance:" + distance); + Logger.d(TAG, "distance:" + distance); if (distance <= 500) { if (EventTypeEnumNew.GHOST_PROBE.getPoiType().equals(v2XRoadEventEntity.getPoiType())) { if (distance > 25) { @@ -75,7 +78,7 @@ public class V2XAlarmServer { double carBearing = currentLocation.getBearing(); double eventBearing = eventLocation.getAngle(); double diffAngle = DrivingDirectionUtils.getAngleDiff(carBearing, eventBearing); - Log.d("RWJ", "car_bearing:" + carBearing + ",eventBearing:" + eventBearing + ",diffAngle:" + diffAngle); + Logger.d(TAG, "car_bearing:" + carBearing + ",eventBearing:" + eventBearing + ",diffAngle:" + diffAngle); if (diffAngle <= 20) { // 3、计算当前车辆行驶方向与事件位置之间夹角《20度,保证道路事件在车辆前方 double eventAngle = DrivingDirectionUtils.getDegreeOfCar2Poi( @@ -86,12 +89,12 @@ public class V2XAlarmServer { (int) currentLocation.getBearing() ); - Log.d("RWJ", "eventAngle:" + eventAngle); + Logger.d(TAG, "eventAngle:" + eventAngle); if (0 <= eventAngle && eventAngle <= 20) { if (showedEvents.contains(v2XRoadEventEntity)) { return null; } - Log.d("RWJ", "showed---"); + Logger.d(TAG, "showed---"); showedEvents.add(v2XRoadEventEntity); return v2XRoadEventEntity; } @@ -102,7 +105,7 @@ public class V2XAlarmServer { } } catch (Exception e) { e.printStackTrace(); - Log.w("RWJ", "error: " + e.getMessage()); + Logger.w(TAG, "error: " + e.getMessage()); } return null; } diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/bridge/BridgeApi.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/bridge/BridgeApi.kt index 566587fc86..8a9b602209 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/bridge/BridgeApi.kt +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/bridge/BridgeApi.kt @@ -23,10 +23,6 @@ internal object BridgeApi { ARouter.getInstance().build(MoGoV2XServicePaths.PATH_V2X_MARKER_MANAGER).navigation(context()) as? IMoGoV2XMarkerManager } - private val v2xPolyline by lazy { - ARouter.getInstance().build(MoGoV2XServicePaths.PATH_V2X_POLYLINE_MANAGER).navigation(context()) as? IMoGoV2XPolylineManager - } - private val v2xWarnPolyline by lazy { ARouter.getInstance().build(MoGoV2XServicePaths.PATH_V2X_WARN_POLYLINE_MANAGER).navigation(context()) as? IMoGoWarnPolylineManager } @@ -39,10 +35,6 @@ internal object BridgeApi { ARouter.getInstance().build(MoGoV2XServicePaths.PATH_V2X_STOP_POLYLINE_MANAGER).navigation(context()) as? IMoGoStopPolylineManager } - private val v2xStatus by lazy { - ARouter.getInstance().build(MoGoV2XServicePaths.PATH_V2X_STATUS_MANAGER).navigation(context()) as? IMoGoV2XStatusManager - } - fun init(context: Context) { this.context.set(WeakReference(context)) } @@ -51,14 +43,9 @@ internal object BridgeApi { fun v2xMarker() = v2xMarker - fun v2xPolyline() = v2xPolyline - fun v2xWarnPolyline() = v2xWarnPolyline fun v2xPersonWarnPolyline() = v2xPersonWarnPolyline fun v2xStopPolyline() = v2xStopPolyline - - fun v2xStatus() = v2xStatus - } \ 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/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 f82f7c4014..fdfe8dec63 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 @@ -19,11 +19,6 @@ import java.util.concurrent.CopyOnWriteArrayList; */ public interface IMoGoV2XMarkerManager extends IProvider { - /** - * 重新绘制最后一次的POI点 - */ - void drawableLastAllPOI(); - /** * 获取所有的道路事件点,探路事件,返回结果是按照距离当前车辆从近到远排列好的 * @@ -43,20 +38,4 @@ public interface IMoGoV2XMarkerManager extends IProvider { * @return */ IMogoMarker drawableAlarmPOI(Context context, V2XRoadEventEntity roadEventEntity, IMogoMarkerClickListener clickListener); - - /** - * 清除 道路事件 POI - */ - void clearAlarmPOI(); - - /** - * 清除 所有的 POI - */ - void clearALLPOI(); - - - /** - * 强制清除道路事件POI - */ - void forceClearAlarmPOI(); } diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XPolylineManager.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XPolylineManager.java deleted file mode 100644 index 00ccb22e7a..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XPolylineManager.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.manager; - -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.overlay.IMogoPolyline; - -/** - * author : donghongyu - * e-mail : 1358506549@qq.com - * date : 2020/4/17 9:49 PM - * desc : 当前车辆与道路事件的连接线 - * version: 1.0 - */ -public interface IMoGoV2XPolylineManager extends IProvider { - /** - * 绘制连接线,目标车,与当前车辆间连线 - * - * @param context - * @param roadEventEntity - */ - void drawablePolyline(Context context, V2XRoadEventEntity roadEventEntity); - - /** - * 移除连接线 - */ - void clearLine(); - - IMogoPolyline getMogoPolyline(); -} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XStatusChangedListener.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XStatusChangedListener.java deleted file mode 100644 index 964ce81d76..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XStatusChangedListener.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.manager; - -import com.alibaba.android.arouter.facade.template.IProvider; - -/** - * author : donghongyu - * e-mail : 1358506549@qq.com - * date : 2020/4/17 7:44 PM - * desc : 状态控制器监听 - * version: 1.0 - */ -public interface IMoGoV2XStatusChangedListener extends IProvider { - - /** - * @param descriptor 状态类型 - * @param isTrue true - v2x ui show - */ - void onStatusChanged(V2XStatusDescriptor descriptor, boolean isTrue); -} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XStatusManager.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XStatusManager.java deleted file mode 100644 index 473b65bf7b..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/IMoGoV2XStatusManager.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.manager; - -import com.alibaba.android.arouter.facade.template.IProvider; - -/** - * author : donghongyu - * e-mail : 1358506549@qq.com - * date : 2020/4/17 7:20 PM - * desc : V2X 状态管理 - * version: 1.0 - */ -public interface IMoGoV2XStatusManager extends IProvider { - /** - * 地图区域 V2X道路预警POI 是否在展示 - */ - boolean isRoadEventPOIShow(); - - /** - * 设置 V2X道路预警POI 是否在展示 - * - * @param tag - * @param show - */ - void setRoadEventPOIShow(String tag, boolean show); - - /** - * 地图区域 推送的 POI 是否在展示 - * - * @param tag - * @param show - */ - void setPushPOIShow(String tag, boolean show); - -} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/V2XStatusDescriptor.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/V2XStatusDescriptor.java deleted file mode 100644 index 2174ed12c4..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/V2XStatusDescriptor.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.manager; - -/** - * @author congtaowang - * @since 2020-01-04 - *

    - * 状态描述 - */ -public enum V2XStatusDescriptor { - - /** - * 地图 V2X道路预警POI - */ - RoadEventPOI_UI, - - /** - * 按钮 V2X道路预警 - */ - RoadEventButton_UI, - - /** - * 头部 V2X道路预警 UI - */ - RoadEventWindow_UI, - - /** - * 头部 V2X的道路直播 UI - */ - RoadLiveCarWindow_UI, - - /** - * 地图 他人车辆故障求助POI - */ - OtherSeekHelpPOI_UI, - - /** - * 头部 他人车辆故障求助 UI 是否在展示 - */ - OtherSeekHelpWindow_UI, - - /** - * 右侧2/3 V2X 场景动画 UI 是否在展示 - */ - V2XAnimationWindow_UI, - - /** - * 右侧2/3 左下角 模拟直播车机 UI 是否在展示 - */ - LiveCarWindow_UI, - - /** - * 右侧2/3 左下角 模拟直播车机 UI 是否在展示 - */ - V2XRoadVideo_UI, - - /** - * 推送的POI - */ - PushWindowPOI_UI, - - /** - * 推送的弹窗 - */ - PushWindow_UI, - - /** - * 疲劳驾驶弹窗 - */ - FatigueDrivingWindow_UI -} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/V2XStatusManager.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/V2XStatusManager.java deleted file mode 100644 index 541a2090a7..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/V2XStatusManager.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.manager; - -import com.mogo.eagle.core.data.map.MogoLatLng; -import com.mogo.eagle.core.data.map.MogoLocation; -import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity; - -/** - * author : donghongyu - * e-mail : 1358506549@qq.com - * date : 2020/4/3 2:34 PM - * desc : V2X状态管理 - * version: 1.0 - */ -public class V2XStatusManager { - private static V2XStatusManager mV2XStatusManager; - // 正在进行的告警事件详情 - private V2XRoadEventEntity mAlarmInfo; - - private MogoLocation mLocation; - - private V2XStatusManager() { - } - - /** - * 获取操作实体 - */ - public static synchronized V2XStatusManager getInstance() { - synchronized (V2XStatusManager.class) { - if (mV2XStatusManager == null) { - mV2XStatusManager = new V2XStatusManager(); - } - } - return mV2XStatusManager; - } - - public void setAlarmInfo(V2XRoadEventEntity eventEntity) { - this.mAlarmInfo = eventEntity; - } - - // 获取目标事件经纬度 - public MogoLatLng getTargetMoGoLatLng() { - if (mAlarmInfo != null) { - return new MogoLatLng( - mAlarmInfo.getLocation().getLat(), - mAlarmInfo.getLocation().getLon() - ); - } - return null; - } - - public MogoLocation getLocation() { - if (mLocation == null) { - mLocation = new MogoLocation(); - } - return mLocation; - } - - public void setLocation(MogoLocation mLocation) { - this.mLocation = mLocation; - } -} 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 ffa58677e6..627ddfed5d 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 @@ -1,15 +1,10 @@ package com.mogo.eagle.core.function.v2x.events.manager.impl; import static com.mogo.commons.module.ServiceConst.CARD_TYPE_NOVELTY; -import static com.mogo.eagle.core.function.v2x.events.consts.V2XConst.V2X_EVENT_ALARM_POI; import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_V2X; - import android.content.Context; - import com.alibaba.android.arouter.facade.annotation.Route; import com.mogo.cloud.commons.utils.CoordinateUtils; -import com.mogo.commons.AbsMogoApplication; -import com.mogo.commons.module.status.MogoStatusManager; import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import com.mogo.eagle.core.data.map.MogoLatLng; import com.mogo.eagle.core.data.map.MogoLocation; @@ -17,26 +12,20 @@ import com.mogo.eagle.core.data.map.entity.MarkerExploreWay; import com.mogo.eagle.core.data.map.entity.MarkerLocation; import com.mogo.eagle.core.data.map.entity.MarkerShowEntity; import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity; +import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager; import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager; -import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi; import com.mogo.eagle.core.function.v2x.events.consts.MoGoV2XServicePaths; import com.mogo.eagle.core.function.v2x.events.manager.IMoGoV2XMarkerManager; -import com.mogo.eagle.core.function.v2x.events.manager.IMoGoV2XPolylineManager; -import com.mogo.eagle.core.function.v2x.events.manager.IMoGoV2XStatusManager; -import com.mogo.eagle.core.function.v2x.events.manager.V2XStatusManager; import com.mogo.eagle.core.function.v2x.events.marker.V2XMarkerAdapter; import com.mogo.eagle.core.function.v2x.events.utils.EntityUtilsKt; import com.mogo.eagle.core.function.v2x.events.utils.MapUtils; -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 com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; 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 java.util.List; import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; @@ -54,25 +43,16 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager { private static final String TAG = "MoGoV2XMarkerManager"; // 记录所有的:新鲜事儿的道路事件点、探路事件 - private static final CopyOnWriteArraySet mV2XRoadEventEntityArrayList = new CopyOnWriteArraySet<>(); - + private final CopyOnWriteArraySet mV2XRoadEventEntityArrayList = new CopyOnWriteArraySet<>(); @Override - public void drawableLastAllPOI() { - // 清除连接线 - IMoGoV2XPolylineManager polylineManager = BridgeApi.INSTANCE.v2xPolyline(); - if (polylineManager != null) { - polylineManager.clearLine(); - } - clearAlarmPOI(); - V2XManager.INSTANCE.forceRefresh(); - } + public void init(Context context) {} @Override public CopyOnWriteArrayList getV2XRoadEventEntityList() { CopyOnWriteArrayList roadEventEntities = new CopyOnWriteArrayList<>(); // 当前车辆数据 - MogoLocation currentLocation = V2XStatusManager.getInstance().getLocation(); + MogoLocation currentLocation = CallerMapLocationListenerManager.INSTANCE.getCurrentLocation(); if (currentLocation != null) { // 重新计算距离 for (V2XRoadEventEntity v2XRoadEventEntity : mV2XRoadEventEntityArrayList) { @@ -133,12 +113,7 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager { @Override public IMogoMarker drawableAlarmPOI(Context context, V2XRoadEventEntity roadEventEntity, IMogoMarkerClickListener clickListener) { try { - IMoGoV2XStatusManager v2xStatus = BridgeApi.INSTANCE.v2xStatus(); - if (v2xStatus != null) { - v2xStatus.setRoadEventPOIShow(TAG, true); - } // 清除原来的大而全的新鲜事儿 - clearAlarmPOI(); if (roadEventEntity.getLocation() != null) { // 道路事件,或者水波纹扩散效果 MogoMarkerOptions optionsRipple = new MogoMarkerOptions() @@ -155,25 +130,11 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager { markerShowEntity.setMarkerType(CARD_TYPE_NOVELTY); optionsRipple.icons(V2XMarkerAdapter.getV2XRoadEventViewGif(context, roadEventEntity)); optionsRipple.period(1); - IMogoMarker ret = null; - if (MogoStatusManager.getInstance().isVrMode()) { - ret = Objects.requireNonNull(CallerMapUIServiceManager.INSTANCE.getMarkerService()).drawMarker(markerShowEntity); - } else { - optionsRipple.icon(V2XMarkerAdapter.getV2XRoadEventViewPng(context, roadEventEntity)); - IMogoMarkerManager marker = CallerMapUIServiceManager.INSTANCE.getMarkerManager(context); - if (marker != null) { - ret = marker.addMarker(V2X_EVENT_ALARM_POI, optionsRipple); - } - } + IMogoMarker ret = Objects.requireNonNull(CallerMapUIServiceManager.INSTANCE.getMarkerService()).drawMarker(markerShowEntity); // 当前Marker设置为最上面 if (ret != null) { ret.setToTop(); } - // 绘制连接线 - IMoGoV2XPolylineManager polylineManager = BridgeApi.INSTANCE.v2xPolyline(); - if (polylineManager != null) { - polylineManager.drawablePolyline(context, roadEventEntity); - } // 缩放地图 MapUtils.zoomMap( new MogoLatLng(roadEventEntity.getLocation().getLat(), @@ -189,43 +150,4 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager { } return null; } - - @Override - public void clearAlarmPOI() { -// boolean isRoadEventPOIShow = false; -// IMoGoV2XStatusManager v2xStatus = BridgeApi.INSTANCE.v2xStatus(); -// if (v2xStatus != null) { -// isRoadEventPOIShow = v2xStatus.isRoadEventPOIShow(); -// } -// if (isRoadEventPOIShow) { -// v2xStatus.setRoadEventPOIShow(TAG, false); -// if (mAlarmInfoMarker != null) { -// mAlarmInfoMarker.remove(); -// } -// } - } - - @Override - public void clearALLPOI() { - try { - IMogoMarkerManager markerManager = CallerMapUIServiceManager.INSTANCE.getMarkerManager(AbsMogoApplication.getApp()); - if (markerManager != null) { - markerManager.removeMarkers(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public void forceClearAlarmPOI() { -// if (mAlarmInfoMarker != null) { -// mAlarmInfoMarker.remove(); -// } - } - - @Override - public void init(Context context) { - - } } diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/impl/MoGoV2XPolylineManager.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/impl/MoGoV2XPolylineManager.java deleted file mode 100644 index 91318099b4..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/impl/MoGoV2XPolylineManager.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.manager.impl; - -import android.content.Context; - -import com.alibaba.android.arouter.facade.annotation.Route; -import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity; -import com.mogo.eagle.core.function.v2x.events.consts.MoGoV2XServicePaths; -import com.mogo.eagle.core.function.v2x.events.manager.IMoGoV2XPolylineManager; -import com.mogo.eagle.core.function.v2x.events.manager.V2XStatusManager; -import com.mogo.map.overlay.IMogoPolyline; - -/** - * author : donghongyu - * e-mail : 1358506549@qq.com - * date : 2020/4/17 10:00 PM - * desc : 当前车辆与道路事件的连接线 - * version: 1.0 - */ -@Route(path = MoGoV2XServicePaths.PATH_V2X_POLYLINE_MANAGER) -public class MoGoV2XPolylineManager implements IMoGoV2XPolylineManager { - private static final String TAG = "MoGoV2XPolylineManager"; - private static IMogoPolyline mMogoPolyline; - - @Override - public void drawablePolyline(Context context, V2XRoadEventEntity roadEventEntity) { -// try { -// if (mMogoPolyline != null) { -// mMogoPolyline.remove(); -// } -// boolean isRoadEventPOIShow = false; -// boolean isOtherSeekHelpPOIShow = false; -// IMoGoV2XStatusManager v2xStatus = BridgeApi.INSTANCE.v2xStatus(); -// if (v2xStatus != null) { -// isRoadEventPOIShow = v2xStatus.isRoadEventPOIShow(); -// isOtherSeekHelpPOIShow = v2xStatus.isOtherSeekHelpPOIShow(); -// } -// boolean isVrMode = false; -// IMogoStatusManager statusManager = BridgeApi.INSTANCE.statusManager(); -// if (statusManager != null) { -// isVrMode = statusManager.isVrMode(); -// } - -// if ((isRoadEventPOIShow -// || isOtherSeekHelpPOIShow) -// && V2XStatusManager.getInstance().getTargetMoGoLatLng() != null -// && !isVrMode -// ) { -// // 连接线参数 -// MogoPolylineOptions options = new MogoPolylineOptions().setGps(true); -// -// // 渐变色 -// List colors = new ArrayList<>(); -// -// if (EventTypeEnum.ALERT_TRAFFIC_LIGHT_SUGGEST.getPoiType().equals(roadEventEntity.getPoiType()) -// || EventTypeEnum.ALERT_TRAFFIC_LIGHT_WARNING.getPoiType().equals(roadEventEntity.getPoiType()) -// || EventTypeEnum.FOURS_BLOCK_UP.getPoiType().equals(roadEventEntity.getPoiType()) -// || EventTypeEnum.ALERT_CAR_TROUBLE_WARNING.getPoiType().equals(roadEventEntity.getPoiType())) { -// colors.add(0xFFFFA31A); -// colors.add(0xFFFFA31A); -// } else { -// colors.add(0xFFE32F46); -// colors.add(0xFFE32F46); -// } -// // 线条粗细,渐变,渐变色值 -// options.width(10).useGradient(true).colorValues(colors); -// -// // 当前车辆位置 -// MogoLatLng carLocation = new MogoLatLng( -// CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lat(), -// CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lon() -// ); -// -// if (carLocation != null) { -// options.add(carLocation); -// } else { -// options.add(V2XStatusManager.getInstance().getLocation()); -// } -// // 目标车辆、道路事件位置 -// options.add(V2XStatusManager.getInstance().getTargetMoGoLatLng()); -// -// // 绘制线的对象 -// IMogoOverlayManager overlay = MogoOverlayManager.getInstance(); -// if (overlay != null) { -// mMogoPolyline = overlay.addPolyline(options); -// } -// } -// } catch (Exception e) { -// e.printStackTrace(); -// } - } - - @Override - public void clearLine() { - if (mMogoPolyline != null) { - mMogoPolyline.remove(); - mMogoPolyline = null; - V2XStatusManager.getInstance().setAlarmInfo(null); - } - } - - @Override - public void init(Context context) { - - } - - /** - * @return 绘制连接线的对象 - */ - @Override - public IMogoPolyline getMogoPolyline() { - return mMogoPolyline; - } - -} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/impl/MoGoV2XStatusManager.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/impl/MoGoV2XStatusManager.java deleted file mode 100644 index 9f04357bb1..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/manager/impl/MoGoV2XStatusManager.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.manager.impl; - -import android.content.Context; - -import com.alibaba.android.arouter.facade.annotation.Route; -import com.mogo.eagle.core.function.v2x.events.consts.MoGoV2XServicePaths; -import com.mogo.eagle.core.function.v2x.events.manager.IMoGoV2XStatusChangedListener; -import com.mogo.eagle.core.function.v2x.events.manager.IMoGoV2XStatusManager; -import com.mogo.eagle.core.function.v2x.events.manager.V2XStatusDescriptor; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * author : donghongyu - * e-mail : 1358506549@qq.com - * date : 2020/4/17 7:34 PM - * desc : - * version: 1.0 - */ -@Route(path = MoGoV2XServicePaths.PATH_V2X_STATUS_MANAGER) -public class MoGoV2XStatusManager implements IMoGoV2XStatusManager { - private static final String TAG = "MoGoV2XStatusManager"; - - /** - * 状态记录 - */ - private static final Map mStatus = new ConcurrentHashMap<>(); - - /** - * 回调集合 - */ - private static final Map> mListeners = new ConcurrentHashMap<>(); - - /** - * 状态类型修改记录 - */ - private static final Map mModifier = new ConcurrentHashMap<>(); - - // 查询状态存储情况 - private boolean get_bool_val(V2XStatusDescriptor descriptor) { - Boolean val = mStatus.get(descriptor); - return val == null ? false : val; - } - - @Override - public boolean isRoadEventPOIShow() { - return get_bool_val(V2XStatusDescriptor.RoadEventPOI_UI); - } - - @Override - public void setRoadEventPOIShow(String tag, boolean show) { - mStatus.put(V2XStatusDescriptor.RoadEventPOI_UI, show); - invokeStatusChangedListener(V2XStatusDescriptor.RoadEventPOI_UI, show); - recordStatusModifier(tag, V2XStatusDescriptor.RoadEventPOI_UI); - } - - - @Override - public void setPushPOIShow(String tag, boolean show) { - mStatus.put(V2XStatusDescriptor.PushWindowPOI_UI, show); - invokeStatusChangedListener(V2XStatusDescriptor.PushWindowPOI_UI, show); - recordStatusModifier(tag, V2XStatusDescriptor.PushWindowPOI_UI); - } - - /** - * 调用所有存储的监听 - * - * @param descriptor - * @param status - */ - private void invokeStatusChangedListener(V2XStatusDescriptor descriptor, boolean status) { - if (mListeners.containsKey(descriptor)) { - List listeners = mListeners.get(descriptor); - if (listeners != null) { - for (IMoGoV2XStatusChangedListener listener : listeners) { - if (listener != null) { - listener.onStatusChanged(descriptor, status); - } - } - } - } - } - - /** - * 记录状态 - * - * @param tag - * @param descriptor - */ - private void recordStatusModifier(String tag, V2XStatusDescriptor descriptor) { - mModifier.put(descriptor, tag); - } - - @Override - public void init(Context context) { - - } -} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/V2XMarkerAdapter.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/V2XMarkerAdapter.java index eb6107c2db..12a6e872f0 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/V2XMarkerAdapter.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/V2XMarkerAdapter.java @@ -2,12 +2,10 @@ package com.mogo.eagle.core.function.v2x.events.marker; import android.content.Context; import android.graphics.Bitmap; - import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity; import com.mogo.eagle.core.function.v2x.R; import com.mogo.eagle.core.function.v2x.events.view.V2XMarkerRoadEventView; - import java.util.ArrayList; /** @@ -26,28 +24,6 @@ public class V2XMarkerAdapter { return new V2XMarkerRoadEventView(context, alarmInfo).setBackground(imageRes).getView(); } - /** - * 返回道路事件静态的图,因为车机性能不行,会卡顿 - */ - public static Bitmap getV2XRoadEventViewPng(Context context, V2XRoadEventEntity alarmInfo) { - Bitmap bitmap; - if (EventTypeEnumNew.ALERT_TRAFFIC_LIGHT_SUGGEST.getPoiType().equals(alarmInfo.getPoiType()) - || EventTypeEnumNew.ALERT_TRAFFIC_LIGHT_WARNING.getPoiType().equals(alarmInfo.getPoiType()) - || EventTypeEnumNew.FOURS_BLOCK_UP.getPoiType().equals(alarmInfo.getPoiType()) - || EventTypeEnumNew.ALERT_CAR_TROUBLE_WARNING.getPoiType().equals(alarmInfo.getPoiType())) { - bitmap = getV2XRoadEventMarkerView( - context, - alarmInfo, - R.drawable.v_to_x_warning_circle_orange_00040); - } else { - bitmap = getV2XRoadEventMarkerView( - context, - alarmInfo, - R.drawable.v_to_x_warning_circle_red_00040); - } - return bitmap; - } - /** * 返回道路事件gif序列图集合 */ diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/observer/CarLocationObserver.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/observer/CarLocationObserver.java deleted file mode 100644 index 06e910f8e9..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/observer/CarLocationObserver.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.observer; - -import com.mogo.eagle.core.data.map.MogoLocation; - -/** - * @author donghongyu - * @date 4/9/21 2:14 PM - * 当前车辆位置观察者接口 - */ -public abstract class CarLocationObserver { - // 更新状态 - public abstract void update(MogoLocation carLocation); -} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/observer/V2XOptimalRouteObserver.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/observer/V2XOptimalRouteObserver.java deleted file mode 100644 index a67b45437a..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/observer/V2XOptimalRouteObserver.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.observer; - -import com.mogo.eagle.core.data.map.MogoLatLng; -import com.mogo.eagle.core.data.map.MogoLocation; -import com.mogo.eagle.core.function.v2x.events.overlay.V2XOptimalRouteOverlay; -import java.util.List; - -/** - * @author donghongyu - * @date 4/9/21 2:38 PM - * 最优路线推荐 - */ -public class V2XOptimalRouteObserver extends CarLocationObserver { - public static String TYPE = "V2XOptimalRouteObserver"; - - private static V2XOptimalRouteObserver v2XOptimalRouteObserver; - //最优路线覆盖物绘制 - private V2XOptimalRouteOverlay mV2XOptimalRouteOverlay; - // 要绘制的数据 - private List polylinePoint; - - public static V2XOptimalRouteObserver getInstance() { - if (v2XOptimalRouteObserver == null) { - synchronized (V2XOptimalRouteObserver.class) { - if (v2XOptimalRouteObserver == null) { - v2XOptimalRouteObserver = new V2XOptimalRouteObserver(); - } - } - } - return v2XOptimalRouteObserver; - } - - private V2XOptimalRouteObserver() { - mV2XOptimalRouteOverlay = new V2XOptimalRouteOverlay(); - } - - /** - * 设置推荐路线 - * - * @param polylinePoint 推荐的路线 - */ - public void setPolylinePoint(List polylinePoint) { - this.polylinePoint = polylinePoint; - } - - @Override - public void update(MogoLocation carLocation) { - mV2XOptimalRouteOverlay.draw(carLocation, polylinePoint); - } -} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/overlay/V2XOptimalRouteOverlay.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/overlay/V2XOptimalRouteOverlay.java deleted file mode 100644 index d922119aff..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/overlay/V2XOptimalRouteOverlay.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.overlay; - -import com.mogo.commons.AbsMogoApplication; -import com.mogo.eagle.core.data.map.MogoLatLng; -import com.mogo.eagle.core.data.map.MogoLocation; -import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager; -import com.mogo.commons.utils.LocationUtils; -import com.mogo.eagle.core.utilcode.util.ColorUtils; -import com.mogo.map.overlay.IMogoOverlayManager; -import com.mogo.map.overlay.IMogoPolyline; -import com.mogo.map.overlay.MogoPolylineOptions; - -import java.util.ArrayList; -import java.util.List; - -/** - * 最优路线推荐的图覆盖物 - * - * @author donghongyu - * @date 4/8/21 6:06 PM - */ -public class V2XOptimalRouteOverlay { - private IMogoPolyline mMoGoPolyline; - // 连接线参数 - private MogoPolylineOptions mPolylineOptions; - // 线路径集合 - private List mPolylinePointList; - // 渐变色 - private List mPolylineColors; - - public V2XOptimalRouteOverlay() { - mPolylineOptions = new MogoPolylineOptions(); - // 绘制路径集合 - mPolylinePointList = new ArrayList<>(); - // 引导线颜色 - mPolylineColors = new ArrayList<>(); - } - - /** - * 绘制最优路线 - * - * @param polylinePoint 要绘制的经纬度度集合 - */ - public IMogoPolyline draw(MogoLocation carLocal, List polylinePoint) { - if (mMoGoPolyline != null) { - mMoGoPolyline.remove(); - mPolylinePointList.clear(); - mPolylineColors.clear(); - } - if (polylinePoint != null) { - - // 将当前车辆位置放进去 - mPolylinePointList.add(new MogoLatLng(carLocal.getLatitude(), carLocal.getLongitude())); - // 过滤后台推送的推荐路线集合 - for (MogoLatLng polyline : polylinePoint) { - //需要剔除已经行驶过的经纬度,这里需要比对推荐路线集合中的点是否在当前车辆行驶方向前面如果不在则抛弃 - if (LocationUtils.isPointOnCarFront(carLocal, polyline)) { - mPolylinePointList.add(polyline); - } - } - - mPolylineColors.addAll(ColorUtils.getGradientAlpha("#002965ED", "#FF2965ED", "#002965ED", mPolylinePointList.size())); - - // 替换路径集合 - mPolylineOptions.points(mPolylinePointList); - // 线条粗细,渐变,渐变色值 - mPolylineOptions.width(25).useGradient(true).colorValues(mPolylineColors); - // 绘制线 - IMogoOverlayManager overlay = CallerMapUIServiceManager.INSTANCE.getOverlayManager(AbsMogoApplication.getApp()); - if (overlay != null) { - mMoGoPolyline = overlay.addPolyline(mPolylineOptions); - } - } - return mMoGoPolyline; - } - -} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/MarkerManager.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/remove/MarkerRemoveManager.kt similarity index 98% rename from core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/MarkerManager.kt rename to core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/remove/MarkerRemoveManager.kt index f738b3ab34..238af1abca 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/marker/MarkerManager.kt +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/remove/MarkerRemoveManager.kt @@ -1,4 +1,4 @@ -package com.mogo.eagle.core.function.v2x.events.marker +package com.mogo.eagle.core.function.v2x.events.remove import android.os.Handler import android.os.HandlerThread @@ -52,7 +52,7 @@ data class MarkerWrapper(val id: String, val lon: Double, val lat: Double, val c } } -object MarkerManager { +object MarkerRemoveManager { private const val TAG = "MarkerManager" diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/impl/V2XScenarioManager.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/impl/V2XScenarioManager.java index 1928101ce5..1f43cac2e9 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/impl/V2XScenarioManager.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/impl/V2XScenarioManager.java @@ -13,7 +13,6 @@ import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager; import com.mogo.eagle.core.function.v2x.events.consts.V2XConst; import com.mogo.eagle.core.function.v2x.events.scenario.IV2XScenarioManager; import com.mogo.eagle.core.function.v2x.events.scenario.scene.road.V2XRoadEventScenario; -import com.mogo.eagle.core.function.v2x.events.scenario.scene.route.V2XOptimalRouteVREventScenario; import com.mogo.eagle.core.function.v2x.events.scenario.scene.warning.V2XFrontWarningScenario; import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; import com.mogo.eagle.core.utilcode.util.ThreadUtils; @@ -21,7 +20,6 @@ import com.mogo.eagle.core.utilcode.util.Utils; import com.mogo.map.uicontroller.IMogoMapUIController; import com.mogo.map.uicontroller.VisualAngleMode; -import java.util.concurrent.atomic.AtomicReference; /** * author : donghongyu @@ -68,10 +66,6 @@ public class V2XScenarioManager implements IV2XScenarioManager { case V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_WARNING: mV2XScenario = new V2XRoadEventScenario(); break; - case V2XMessageEntity.V2XTypeEnum.ALERT_PUSH_VR_SHOW: - sceneChange(); - mV2XScenario = new V2XOptimalRouteVREventScenario(); - break; case V2XMessageEntity.V2XTypeEnum.ALERT_THE_FRONT_WEAKNESS: if (HmiBuildConfig.isShowCloudWeaknessTrafficView) { //默认关闭云端弱势交通 sceneChange(); 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 ef0cb94abc..e1eb7d8be3 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 @@ -18,14 +18,11 @@ import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils import com.mogo.map.MogoMap import com.mogo.map.overlay.IMogoPolyline import com.mogo.map.overlay.MogoPolylineOptions -import mogo.telematics.pad.MessagePad import java.util.* -import java.util.concurrent.Executors -import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.ConcurrentHashMap -import com.mogo.eagle.core.function.v2x.events.marker.MarkerManager -import com.mogo.eagle.core.function.v2x.events.marker.MarkerWrapper +import com.mogo.eagle.core.function.v2x.events.remove.MarkerRemoveManager +import com.mogo.eagle.core.function.v2x.events.remove.MarkerWrapper /** * Ai云道路施工事件,道路颜色标记类 @@ -156,7 +153,7 @@ class AiRoadMarker { wrapper.addLine(line) } } - MarkerManager.addMarker(wrapper) + MarkerRemoveManager.addMarker(wrapper) } private fun removeLine() { diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XAiRoadEventMarker.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XAiRoadEventMarker.kt index 563aada462..1ad84664da 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XAiRoadEventMarker.kt +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XAiRoadEventMarker.kt @@ -6,7 +6,7 @@ import com.mogo.eagle.core.data.map.* import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi.context import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi.v2xMarker -import com.mogo.eagle.core.function.v2x.events.marker.MarkerWrapper +import com.mogo.eagle.core.function.v2x.events.remove.MarkerWrapper import com.mogo.map.* import com.mogo.map.marker.* import com.mogo.map.overlay.* diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventMarker.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventMarker.java index 4de55a0c84..a743246918 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventMarker.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventMarker.java @@ -10,8 +10,8 @@ import com.mogo.eagle.core.data.map.entity.MarkerLocation; import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity; import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi; import com.mogo.eagle.core.function.v2x.events.manager.IMoGoV2XMarkerManager; -import com.mogo.eagle.core.function.v2x.events.marker.MarkerWrapper; -import com.mogo.eagle.core.function.v2x.events.marker.MarkerManager; +import com.mogo.eagle.core.function.v2x.events.remove.MarkerWrapper; +import com.mogo.eagle.core.function.v2x.events.remove.MarkerRemoveManager; import com.mogo.eagle.core.function.v2x.events.scenario.scene.airoad.AiRoadMarker; import com.mogo.eagle.core.function.v2x.events.scenario.view.IV2XMarker; import com.mogo.map.marker.IMogoMarker; @@ -44,7 +44,7 @@ public class V2XRoadEventMarker implements IV2XMarker { ArrayList markers = new ArrayList<>(); markers.add(iMarker); String id = entity.getLocation().getLon() + "_" + entity.getLocation().getLat(); - MarkerManager.INSTANCE.addMarker(new MarkerWrapper(id, entity.getLocation().getLon(), entity.getLocation().getLat(), 0, markers, null)); + MarkerRemoveManager.INSTANCE.addMarker(new MarkerWrapper(id, entity.getLocation().getLon(), entity.getLocation().getLat(), 0, markers, null)); } else { Log.d("RWJ", "V2XRoadEventMarker:" + entity.getPoiType() + "--- return empty marker"); } @@ -101,20 +101,4 @@ public class V2XRoadEventMarker implements IV2XMarker { private boolean isDrawRoadLine(String poiType) { return EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGONG.getPoiType().equals(poiType); } - - @Override - public void clearPOI() { - // 移除线 -// IMoGoV2XPolylineManager polyLineManager = BridgeApi.INSTANCE.v2xPolyline(); -// if (polyLineManager != null) { -// polyLineManager.clearLine(); -// } -// IMoGoV2XMarkerManager v2xMarker = BridgeApi.INSTANCE.v2xMarker(); -// if (v2xMarker != null) { -// // 移除事件POI -// v2xMarker.clearAlarmPOI(); -// // 绘制上次的数据 -// v2xMarker.drawableLastAllPOI(); -// } - } } diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventScenario.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventScenario.java index 98998db728..7585e7f6c8 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventScenario.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/road/V2XRoadEventScenario.java @@ -1,14 +1,7 @@ package com.mogo.eagle.core.function.v2x.events.scenario.scene.road; - - -import android.util.Log; - -import com.mogo.cloud.commons.utils.CoordinateUtils; -import com.mogo.commons.analytics.AnalyticsUtils; import com.mogo.eagle.core.data.enums.EventTypeEnumNew; import com.mogo.eagle.core.data.enums.WarningDirectionEnum; -import com.mogo.eagle.core.data.map.MogoLocation; import com.mogo.eagle.core.data.map.entity.MarkerExploreWay; import com.mogo.eagle.core.data.map.entity.MarkerLocation; import com.mogo.eagle.core.data.map.entity.V2XMessageEntity; @@ -17,23 +10,16 @@ import com.mogo.eagle.core.data.msgbox.MsgBoxBean; import com.mogo.eagle.core.data.msgbox.MsgBoxType; import com.mogo.eagle.core.data.msgbox.V2XMsg; import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener; -import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ20ListenerManager; import com.mogo.eagle.core.function.call.hmi.CallerHmiManager; -import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager; import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager; import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager; -import com.mogo.eagle.core.function.v2x.events.consts.V2XConst; -import com.mogo.eagle.core.function.v2x.events.manager.V2XStatusManager; 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.eagle.core.network.utils.GsonUtil; -import java.util.HashMap; -import java.util.Map; +import com.mogo.eagle.core.utilcode.mogo.logger.Logger; import java.util.Objects; import java.util.concurrent.TimeUnit; -import mogo.telematics.pad.MessagePad; - /** * author : donghongyu @@ -52,7 +38,7 @@ public class V2XRoadEventScenario extends AbsV2XScenario imp @Override public void init(V2XMessageEntity v2XMessageEntity) { try { - Log.d(TAG, "v2XMessageEntity:" + GsonUtil.jsonFromObject(v2XMessageEntity)); + Logger.d(TAG, "v2XMessageEntity:" + GsonUtil.jsonFromObject(v2XMessageEntity)); V2XRoadEventEntity v2XRoadEventEntity = v2XMessageEntity.getContent(); if (v2XRoadEventEntity != null) { if (v2XMessageEntity.isShowState()) { @@ -91,18 +77,6 @@ public class V2XRoadEventScenario extends AbsV2XScenario imp } } showWindow(); - String poiType = entity.getContent().getPoiType(); - String lat = String.valueOf(entity.getContent().getLocation().getLat()); - String lon = String.valueOf(entity.getContent().getLocation().getLon()); - String infoId = entity.getContent().getNoveltyInfo().getInfoId(); - String style = "1"; - Map properties = new HashMap<>(); - properties.put("dbid", infoId); - properties.put("type", poiType); - properties.put("lng", lon); - properties.put("lat", lat); - properties.put("style", style); - AnalyticsUtils.track(V2XConst.V2X_ROAD_SHOW, properties); } } catch (Exception e) { e.printStackTrace(); @@ -118,7 +92,7 @@ public class V2XRoadEventScenario extends AbsV2XScenario imp String ttsText = content.getTts(); if (alarmText == null || alarmText.isEmpty() || ttsText == null || ttsText.isEmpty()) { - Log.d("MsgBox-V2XRoadScenario", "alertContent或ttsContent为空!"); + Logger.d("MsgBox-V2XRoadScenario", "alertContent或ttsContent为空!"); } String poiType = content.getPoiType(); if (EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGONG.getPoiType().equals(poiType) || @@ -155,7 +129,6 @@ public class V2XRoadEventScenario extends AbsV2XScenario imp IV2XMarker marker = getV2XMarker(); if (marker != null) { // 重置告警信息 - V2XStatusManager.getInstance().setAlarmInfo(getV2XMessageEntity().getContent()); marker.drawPOI(getV2XMessageEntity().getContent()); } } diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/route/V2XOptimalRouteVREventMarker.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/route/V2XOptimalRouteVREventMarker.java deleted file mode 100644 index e2e6c77c1f..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/route/V2XOptimalRouteVREventMarker.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.scenario.scene.route; - -import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_V2X; - -import com.mogo.eagle.core.function.v2x.events.bridge.BridgeApi; -import com.mogo.eagle.core.data.v2x.V2XOptimalRouteDataRes; -import com.mogo.eagle.core.function.v2x.events.manager.IMoGoV2XMarkerManager; -import com.mogo.eagle.core.function.v2x.events.observer.V2XOptimalRouteObserver; -import com.mogo.eagle.core.function.v2x.events.scenario.view.IV2XMarker; -import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; - -/** - * author : donghongyu - * e-mail : 1358506549@qq.com - * date : 2020/5/15 5:37 PM - * desc : 推送VR场景 - * version: 1.0 - */ -public class V2XOptimalRouteVREventMarker implements IV2XMarker { - private final String TAG = "V2XPushVREventMarker"; - - @Override - public void drawPOI(V2XOptimalRouteDataRes entity) { - CallerLogger.INSTANCE.d(M_V2X + TAG, "drawPOI 绘制VR Marker"); - - try { - // 清除道路事件 - IMoGoV2XMarkerManager v2xMarker = BridgeApi.INSTANCE.v2xMarker(); - if (v2xMarker != null) { - v2xMarker.clearAlarmPOI(); - } - // 绘制引导线 - V2XOptimalRouteObserver.getInstance() - .setPolylinePoint(entity.getGd_locus_list()); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public void clearPOI() { -// // 移除线 -// clearLine(); -// // 绘制上次的数据 -// IMoGoV2XMarkerManager v2xMarker = BridgeApi.INSTANCE.v2xMarker(); -// if (v2xMarker != null) { -// v2xMarker.drawableLastAllPOI(); -// } - } - - public void clearLine() { - V2XOptimalRouteObserver.getInstance().setPolylinePoint(null); - } -} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/route/V2XOptimalRouteVREventScenario.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/route/V2XOptimalRouteVREventScenario.java deleted file mode 100644 index 2e38a64747..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/scene/route/V2XOptimalRouteVREventScenario.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.scenario.scene.route; - -import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_V2X; - -import androidx.annotation.Nullable; - -import com.mogo.eagle.core.data.map.entity.V2XMessageEntity; -import com.mogo.eagle.core.data.msgbox.MsgBoxBean; -import com.mogo.eagle.core.data.msgbox.MsgBoxType; -import com.mogo.eagle.core.data.msgbox.V2XMsg; -import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener; -import com.mogo.eagle.core.function.call.hmi.CallerHmiManager; -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.bridge.BridgeApi; -import com.mogo.eagle.core.data.v2x.V2XOptimalRouteDataRes; -import com.mogo.eagle.core.function.v2x.events.manager.IMoGoV2XStatusManager; -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.eagle.core.network.utils.GsonUtil; - -import java.util.concurrent.TimeUnit; - -/** - * author : donghongyu - * e-mail : 1358506549@qq.com - * date : 2020/5/15 5:37 PM - * desc : 最优车道选择 - * version: 1.0 - * wiki : http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=52829799 - */ -public class V2XOptimalRouteVREventScenario - extends AbsV2XScenario - implements IMoGoWarningStatusListener { - private String TAG = "V2XPushVREventWindow"; - - public V2XOptimalRouteVREventScenario() { - setV2XMarker(new V2XOptimalRouteVREventMarker()); - } - - @Override - public void init(@Nullable V2XMessageEntity v2XMessageEntity) { - CallerLogger.INSTANCE.w(M_V2X + TAG, "处理推送VR:" + GsonUtil.jsonFromObject(v2XMessageEntity)); - if (!isSameScenario(v2XMessageEntity)) { - setV2XMessageEntity(v2XMessageEntity); - show(); - } else { - setV2XMessageEntity(v2XMessageEntity); - show(); - CallerLogger.INSTANCE.w(M_V2X + TAG, "要处理的场景已经存在,丢弃这次初始化"); - } - } - - @Override - public void show() { - V2XMessageEntity entity = getV2XMessageEntity(); - if (entity != null) { - V2XOptimalRouteDataRes content = entity.getContent(); - if (content != null) { - CallerMsgBoxManager.INSTANCE.saveMsgBox( - new MsgBoxBean( - MsgBoxType.V2X, - new V2XMsg(entity.getType() + "", - "为您推荐最优路线", - "已为您选择最优路线") - ) - ); - CallerHmiManager.INSTANCE.warningV2X(entity.getType() + "", - "为您推荐最优路线", "已为您选择最优路线", TAG, - this, !entity.isOnlyShow(), TimeUnit.SECONDS.toMillis(30)); - } - } - } - - @Override - public void drawPOI() { - IV2XMarker marker = getV2XMarker(); - if (marker != null) { - marker.drawPOI(getV2XMessageEntity().getContent()); - IMoGoV2XStatusManager v2xStatus = BridgeApi.INSTANCE.v2xStatus(); - if (v2xStatus != null) { - v2xStatus.setPushPOIShow(TAG, true); - } - } - } - - @Override - public void clearPOI() { -// if (getV2XMarker() != null) { -// getV2XMarker().clearPOI(); -// } -// IMoGoV2XStatusManager v2xStatus = BridgeApi.INSTANCE.v2xStatus(); -// if (v2xStatus != null) { -// v2xStatus.setPushPOIShow(TAG, false); -// } - } - - @Override - public void onShow() { - drawPOI(); - } - - @Override - public void onDismiss() { - } -} 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 85dc9db343..549e56d19f 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 @@ -7,9 +7,7 @@ import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; import android.util.Log; - import androidx.annotation.Nullable; - import com.mogo.eagle.core.data.enums.WarningDirectionEnum; import com.mogo.eagle.core.data.map.entity.V2XMessageEntity; import com.mogo.eagle.core.data.msgbox.MsgBoxBean; 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 fe3932017b..5bd251ea4e 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 @@ -2,9 +2,7 @@ package com.mogo.eagle.core.function.v2x.events.scenario.scene.warning; import static com.mogo.eagle.core.data.constants.DataTypes.TYPE_MARKER_CLOUD_STOP_LINE_DATA; import static com.mogo.eagle.core.data.constants.DataTypes.TYPE_MARKER_CLOUD_WARN_DATA; -import static com.mogo.eagle.core.function.v2x.events.consts.V2XConst.V2X_FRONT_WARNING_MARKER; import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_V2X; - import com.mogo.cloud.commons.utils.CoordinateUtils; import com.mogo.commons.AbsMogoApplication; import com.mogo.commons.module.status.MogoStatusManager; @@ -26,12 +24,10 @@ import com.mogo.map.overlay.IMogoPolyline; import com.mogo.commons.utils.Trigonometric; 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; import java.util.List; import java.util.Objects; - import mogo.telematics.pad.MessagePad; /** @@ -446,19 +442,4 @@ public class V2XWarningMarker implements IV2XMarker { } CallerLogger.INSTANCE.d(M_V2X + TAG, "车辆行驶轨迹" + latLng.getLongitude() + "," + latLng.getLatitude()); } - - @Override - public void clearPOI() { - IMogoMarkerManager marker = CallerMapUIServiceManager.INSTANCE.getMarkerManager(AbsMogoApplication.getApp()); - if (marker != null) { - marker.removeMarkers(V2X_FRONT_WARNING_MARKER); - } - } - - public void clearLine() { - IMoGoWarnPolylineManager warnPolylineManager = BridgeApi.INSTANCE.v2xWarnPolyline(); - if (warnPolylineManager != null) { - warnPolylineManager.clearLine(); - } - } } diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/view/IV2XMarker.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/view/IV2XMarker.java index 5540ad2f79..8dcf008880 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/view/IV2XMarker.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/scenario/view/IV2XMarker.java @@ -10,7 +10,4 @@ package com.mogo.eagle.core.function.v2x.events.scenario.view; public interface IV2XMarker { void drawPOI(T entity); - - void clearPOI(); - } diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/TestOnLineCarUtils.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/test/TestOnLineCarUtils.java similarity index 99% rename from core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/TestOnLineCarUtils.java rename to core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/test/TestOnLineCarUtils.java index 62c8a64efa..0070ffbed8 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/TestOnLineCarUtils.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/test/TestOnLineCarUtils.java @@ -1,4 +1,4 @@ -package com.mogo.eagle.core.function.v2x.events.utils; +package com.mogo.eagle.core.function.v2x.events.test; import static com.mogo.eagle.core.data.map.entity.V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_WARNING; diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/receiver/TestPanelBroadcastReceiver.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/test/TestV2XReceiver.java similarity index 87% rename from core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/receiver/TestPanelBroadcastReceiver.java rename to core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/test/TestV2XReceiver.java index 59d5471e0f..70c5eae7c3 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/receiver/TestPanelBroadcastReceiver.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/test/TestV2XReceiver.java @@ -1,4 +1,4 @@ -package com.mogo.eagle.core.function.v2x.events.receiver; +package com.mogo.eagle.core.function.v2x.events.test; import android.content.BroadcastReceiver; import android.content.Context; @@ -12,7 +12,6 @@ import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity; import com.mogo.eagle.core.data.v2x.V2XOptimalRouteDataRes; import com.mogo.eagle.core.function.call.map.CallerSmpManager; import com.mogo.eagle.core.function.v2x.events.consts.V2XConst; -import com.mogo.eagle.core.function.v2x.events.utils.TestOnLineCarUtils; import java.util.List; @@ -21,8 +20,8 @@ import java.util.List; * * @author donghongyu */ -public class TestPanelBroadcastReceiver extends BroadcastReceiver { - private static final String TAG = V2XConst.MODULE_NAME + "_TestPanelBroadcastReceiver"; +public class TestV2XReceiver extends BroadcastReceiver { + private static final String TAG = "TestV2XReceiver"; private Context mContext; @@ -74,11 +73,7 @@ public class TestPanelBroadcastReceiver extends BroadcastReceiver { Intent intent = new Intent(V2XConst.BROADCAST_SCENE_HANDLER_ACTION); intent.putExtra(V2XConst.BROADCAST_SCENE_EXTRA_KEY, messageEntity); LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); - } /*else if (sceneType == 16) {//触发基于目的地预测的线路推荐 - V2XRefreshModel model = BridgeApi.INSTANCE.refreshModel(); - model. - V2XServiceManager.getV2XRefreshModel().queryRoadData("F803EB2046PZD00149"); - } */ else if (sceneType == 17) {//最优路线推荐 + } else if (sceneType == 17) {//最优路线推荐 V2XMessageEntity v2XMessageEntity = TestOnLineCarUtils.getV2XOptimalRoute(); diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/TrackUtils.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/TrackUtils.java index 87bf002efa..7d7f1a2244 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/TrackUtils.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/TrackUtils.java @@ -2,7 +2,6 @@ package com.mogo.eagle.core.function.v2x.events.utils; import com.mogo.commons.analytics.AnalyticsUtils; import com.mogo.eagle.core.function.v2x.events.consts.V2XConst; -import com.mogo.eagle.core.function.v2x.events.manager.V2XStatusManager; import java.util.HashMap; import java.util.Map; From d3f0ac654b8b618dbe979aeba2dcfa284eda077d Mon Sep 17 00:00:00 2001 From: zhongchao Date: Tue, 31 Jan 2023 15:26:32 +0800 Subject: [PATCH 34/48] [2.13.0-arch-opt] fix bug of limit speed and move view --- .../main/res/layout/bus_p_base_fragment.xml | 19 ---- .../och/bus/passenger/ExampleUnitTest.java | 34 +++---- .../src/main/res/layout/bus_base_fragment.xml | 25 ++++- .../java/com/mogo/och/noop/OchNoopFragment.kt | 39 +++----- .../main/res/layout/och_noop_fragment_hmi.xml | 95 ++++++------------- .../sweeper/view/SweeperTrafficDataView.java | 14 --- .../passenger/model/TaxiPassengerModel.java | 3 +- .../main/res/layout/taxi_p_base_fragment.xml | 19 ---- .../main/res/layout/taxi_base_fragment.xml | 16 ++++ .../hmi/ui/msgbox/DriverMsgBoxListView.kt | 2 +- .../msgbox/adapter/DriverMsgBoxListAdapter.kt | 24 +++-- .../hmi/ui/switch/DemoModeHiddenSwitch.kt | 18 ++-- .../hmi/ui/widget/LimitingVelocityView.kt | 16 ++-- .../function/hmi/ui/widget/VersionNameView.kt | 2 +- .../src/main/res/layout/fragment_hmi.xml | 40 +------- .../res/layout/view_limiting_speed_vr.xml | 10 +- 16 files changed, 136 insertions(+), 240 deletions(-) diff --git a/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_base_fragment.xml b/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_base_fragment.xml index 564aa1e394..95eaa395d2 100644 --- a/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_base_fragment.xml +++ b/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_base_fragment.xml @@ -26,16 +26,6 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/> - - - - - - Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file +//package com.mogo.och.bus.passenger; +// +//import org.junit.Test; +// +//import static org.junit.Assert.*; +// +///** +// * Example local unit test, which will execute on the development machine (host). +// * +// * @see Testing documentation +// */ +//public class ExampleUnitTest { +// @Test +// public void addition_isCorrect() { +// assertEquals(4, 2 + 2); +// } +//} \ No newline at end of file diff --git a/OCH/mogo-och-bus/src/main/res/layout/bus_base_fragment.xml b/OCH/mogo-och-bus/src/main/res/layout/bus_base_fragment.xml index da6d779a3b..fae3e46139 100644 --- a/OCH/mogo-och-bus/src/main/res/layout/bus_base_fragment.xml +++ b/OCH/mogo-och-bus/src/main/res/layout/bus_base_fragment.xml @@ -56,11 +56,27 @@ android:layout_width="120dp" android:layout_height="120dp" android:layout_marginTop="45dp" - android:layout_marginEnd="40dp" app:layout_constraintRight_toLeftOf="@id/viewTrafficLightVr" app:layout_constraintTop_toTopOf="parent" + tools:ignore="SpeakableTextPresentCheck" tools:visibility="visible" /> + + + + app:layout_constraintStart_toStartOf="parent" + tools:ignore="SpeakableTextPresentCheck" /> +