From d6086f1996af6472fa36781578f9423754e097c3 Mon Sep 17 00:00:00 2001 From: wangmingjun Date: Wed, 3 Aug 2022 16:35:50 +0800 Subject: [PATCH 01/30] =?UTF-8?q?[290=20bus/taxi]=201=E3=80=81=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E5=88=87=E6=8D=A2=E9=97=AE=E9=A2=98=202=E3=80=81bus?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E5=85=A8=E5=B1=80=E8=BD=A8=E8=BF=B9=E5=92=8C?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E5=9D=90=E6=A0=87=E8=AE=A1=E7=AE=97=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E7=AB=99=E7=82=B9=E8=BD=A8=E8=BF=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../passenger/bean/BusPassengerStation.java | 9 ++++ .../passenger/model/BusPassengerModel.java | 50 ++++++++++++++++--- .../presenter/BaseBusPassengerPresenter.java | 2 +- .../ui/BusPassengerBaseFragment.java | 1 - .../ui/BusPassengerMapDirectionView.java | 2 + .../ui/BusPassengerRouteFragment.java | 2 +- .../main/res/layout/bus_p_route_fragment.xml | 2 +- .../TaxiPassengerServingOrderPresenter.java | 6 +-- 8 files changed, 59 insertions(+), 15 deletions(-) diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/bean/BusPassengerStation.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/bean/BusPassengerStation.java index fa0aa2051c..5e1b8a74de 100644 --- a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/bean/BusPassengerStation.java +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/bean/BusPassengerStation.java @@ -12,6 +12,8 @@ public class BusPassengerStation { private String cityCode; private double lon; //高精坐标 private double lat; //高精坐标 + private double gcjLon; //高德坐标 + private double gcjLat; //高德坐标 private int businessType; //站点类型,9:taxi,10:bus private int status; private int siteId; @@ -72,6 +74,13 @@ public class BusPassengerStation { return cityCode; } + public double getGcjLon() { + return gcjLon; + } + + public double getGcjLat() { + return gcjLat; + } public int getBusinessType() { return businessType; diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java index 7d06ba2d26..6322d5dd04 100644 --- a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java @@ -84,6 +84,10 @@ public class BusPassengerModel { private double mLongitude, mLatitude; + List mStations = new ArrayList<>(); + private int mNextStationIndex = 0;// 要到达站的index + private List mTwoStationsRouts = new ArrayList<>(); + private BusPassengerModel() { } @@ -147,12 +151,21 @@ public class BusPassengerModel { mRouteLineInfoCallback.updateLineInfo(result.getName(),result.getRunningDur()); if (result.getSites() != null){ List stations = result.getSites(); + mStations.clear(); + mStations.addAll(stations); for (int i = 0; i< stations.size(); i++){ BusPassengerStation station = stations.get(i); if (station.getDrivingStatus() == STATION_STATUS_STOPPED && station.isLeaving() && i+1 < stations.size()){ mRouteLineInfoCallback.updateStationsInfo(stations,i+1,false); + if(mNextStationIndex != i+1){ + startRemainRouteInfo(); + } + mNextStationIndex = i+1; return; }else if (station.getDrivingStatus() == STATION_STATUS_STOPPED && !station.isLeaving()){ + if (i == 0){ + startOrStopRouteAndWipe(false); + } startOrStopCalculateRouteInfo(false); mRouteLineInfoCallback.updateStationsInfo(stations,i,true); return; @@ -354,7 +367,6 @@ public class BusPassengerModel { List routePoints = routeList.getWayPointsList(); if (null != routePoints && routePoints.size() > 0){ updateRoutePoints(routePoints); - startRemainRouteInfo(); setRouteLineMarker(); startToRouteAndWipe(); } @@ -366,18 +378,40 @@ public class BusPassengerModel { List latLngModels = CoordinateCalculateRouteUtil .coordinateConverterWgsToGcjListCommon(mContext,routePoints); mRoutePoints.addAll(latLngModels); + calculateTwoStationsRoute(); + } - float sumLength = CoordinateCalculateRouteUtil.calculateRouteSumLength(mRoutePoints); - SharedPrefsMgr.getInstance(mContext).putInt(BusPassengerConst.BUS_SP_KEY_ORDER_SUM_DIS,(int) sumLength); + private void calculateTwoStationsRoute(){ + //找出前往站对应的轨迹点,拿出两站点的集合 + CallerLogger.INSTANCE.d(M_BUS_P + TAG, "mRoutePoints.size() = " + mRoutePoints.size()); + if (mRoutePoints.size() > 0) { + if (mNextStationIndex <= mStations.size()-1 && mNextStationIndex - 1 >=0){ + mTwoStationsRouts.clear(); + BusPassengerStation stationNext = mStations.get(mNextStationIndex); + BusPassengerStation stationCur = mStations.get(mNextStationIndex - 1); + //当前站在轨迹中对应的点 + int currentRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndex(mRoutePoints + ,stationCur.getGcjLon(),stationCur.getGcjLat()); + //要前往的站在轨迹中对应的点 + int nextRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndex(mRoutePoints + ,stationNext.getGcjLon(),stationNext.getGcjLat()); + mTwoStationsRouts.addAll(mRoutePoints.subList(currentRouteIndex,nextRouteIndex)); + float sumLength = CoordinateCalculateRouteUtil.calculateRouteSumLength(mTwoStationsRouts); + SharedPrefsMgr.getInstance(mContext).putInt(BusPassengerConst.BUS_SP_KEY_ORDER_SUM_DIS,(int) sumLength); - if (mAutopilotPlanningCallback != null){ - mAutopilotPlanningCallback.updateTotalDistance(); + if (mAutopilotPlanningCallback != null){ + mAutopilotPlanningCallback.updateTotalDistance(); + } + } } } public void dynamicCalculateRouteInfo() { + //计算当前位置和下一站的剩余点集合 + //计算剩余点总里程和时间 + calculateTwoStationsRoute(); List lastPoints = CoordinateCalculateRouteUtil - .getRemainPointListByCompare(mRoutePoints,mLongitude,mLatitude); + .getRemainPointListByCompare(mTwoStationsRouts,mLongitude,mLatitude); float lastSumLength = 0; if (lastPoints.size() == 1){ //只是最后一个点,计算当前位置和最后一个点的距离 @@ -388,7 +422,7 @@ public class BusPassengerModel { lastSumLength = CoordinateCalculateRouteUtil.calculateRouteSumLength(lastPoints); } double lastTime = lastSumLength / BusPassengerConst.BUS_AVERAGE_SPEED * 3.6 ; //秒 - + CallerLogger.INSTANCE.d(M_BUS_P + TAG, "lastSumLength = " + lastSumLength); if (mAutopilotPlanningCallback != null){ mAutopilotPlanningCallback.routePlanningToNextStationChanged((long)lastSumLength,(long) lastTime); } @@ -441,7 +475,7 @@ public class BusPassengerModel { * @param isStart */ public void startOrStopCalculateRouteInfo(boolean isStart) { - CallerLogger.INSTANCE.d(M_BUS_P + TAG, "startOrStopOrderLoop() " + isStart); + CallerLogger.INSTANCE.d(M_BUS_P + TAG, "startOrStopCalculateRouteInfo() " + isStart); if (isStart) { BusPassengerModelLoopManager.getInstance().startCalculateRouteInfoLoop(); } else { diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/presenter/BaseBusPassengerPresenter.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/presenter/BaseBusPassengerPresenter.java index e3b32a6960..e139ae3dff 100644 --- a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/presenter/BaseBusPassengerPresenter.java +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/presenter/BaseBusPassengerPresenter.java @@ -139,7 +139,7 @@ public class BaseBusPassengerPresenter extends Presenter models, int haveArrivedIndex) { CallerLogger.INSTANCE.d(M_BUS_P + TAG, "routeResult:" + models.size() + " haveArrivedIndex = "+haveArrivedIndex); - mView.routeResult(models,haveArrivedIndex); + runOnUIThread(() ->mView.routeResult(models,haveArrivedIndex)); } @Override diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerBaseFragment.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerBaseFragment.java index b509bc789d..6e69bcc01e 100644 --- a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerBaseFragment.java +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerBaseFragment.java @@ -125,7 +125,6 @@ public abstract class BusPassengerBaseFragment 0){ diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerMapDirectionView.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerMapDirectionView.java index 825d6a646c..a663e20563 100644 --- a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerMapDirectionView.java +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerMapDirectionView.java @@ -298,6 +298,8 @@ public class BusPassengerMapDirectionView } public void clearCoordinatesLatLng(){ + textureList.clear(); + texIndexList.clear(); mCoordinatesLatLng.clear(); mLinePointsLatLng.clear(); } diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerRouteFragment.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerRouteFragment.java index a3ea8e9ebe..29ccf56f35 100644 --- a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerRouteFragment.java +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerRouteFragment.java @@ -248,8 +248,8 @@ public class BusPassengerRouteFragment extends if (currentStationIndex == 0 && isArrived){ //到达始发站且并未出发, 恢复站点marker 清楚路径 清空路径点 SharedPrefsMgr.getInstance(getContext()) .remove(BusPassengerConst.BUS_SP_KEY_ORDER_SUM_DIS); - clearPolyline(); if (mMapDirectionView != null) mMapDirectionView.clearCoordinatesLatLng(); + clearPolyline(); } if (stations.size() > 0){ diff --git a/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_route_fragment.xml b/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_route_fragment.xml index 61e9d4acf9..58ae13004c 100644 --- a/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_route_fragment.xml +++ b/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_route_fragment.xml @@ -7,7 +7,7 @@ Date: Wed, 3 Aug 2022 17:00:17 +0800 Subject: [PATCH 02/30] =?UTF-8?q?[290=20bus/taxi]taxi=E5=8F=B8=E6=9C=BA?= =?UTF-8?q?=E7=AB=AF=E5=BC=80=E5=A7=8B=E8=AE=A1=E7=AE=97=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E4=B8=BA0=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mogo/och/taxi/model/TaxiModel.java | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/TaxiModel.java b/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/TaxiModel.java index 90040dd0c8..5b151461f5 100644 --- a/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/TaxiModel.java +++ b/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/TaxiModel.java @@ -1287,30 +1287,32 @@ public class TaxiModel { * 实时计算当前剩余里程和时间 */ public void dynamicCalculateRouteInfo() { - List lastPoints = CoordinateCalculateRouteUtil - .getRemainPointListByCompare(mRoutePoints, mLongitude, mLatitude); + if (mRoutePoints.size() > 0){ + List lastPoints = CoordinateCalculateRouteUtil + .getRemainPointListByCompare(mRoutePoints, mLongitude, mLatitude); - float lastSumLength = 0; + float lastSumLength = 0; - if (lastPoints.size() == 1) { //只是最后一个点,计算当前位置和最后一个点的距离 - lastSumLength = CoordinateUtils.calculateLineDistance( - lastPoints.get(0).longitude, lastPoints.get(0).latitude, - mLongitude, mLatitude); - } else { - lastSumLength = CoordinateCalculateRouteUtil.calculateRouteSumLength(lastPoints); + if (lastPoints.size() == 1) { //只是最后一个点,计算当前位置和最后一个点的距离 + lastSumLength = CoordinateUtils.calculateLineDistance( + lastPoints.get(0).longitude, lastPoints.get(0).latitude, + mLongitude, mLatitude); + } else { + lastSumLength = CoordinateCalculateRouteUtil.calculateRouteSumLength(lastPoints); + } + + double lastTime = lastSumLength / TaxiConst.TAXI_AVERAGE_SPEED * 3.6; //秒 + Logger.d(M_TAXI + "dynamicCalculateRouteInfo" + , "---lastSumLength: " + lastSumLength + "----lastTime : " + lastTime + + " thread = "+ Thread.currentThread().getName()); + + mCurrentOCHOrder.decreaseTravelDistance(lastSumLength); + if (mOrderStatusCallback != null) { + mOrderStatusCallback.onCurrentOrderDistToEndChanged((long) lastSumLength, (long) lastTime); + } + + reportOrderRemain((long) lastSumLength, (long) lastTime); } - - double lastTime = lastSumLength / TaxiConst.TAXI_AVERAGE_SPEED * 3.6; //秒 - Logger.d(M_TAXI + "dynamicCalculateRouteInfo" - , "---lastSumLength: " + lastSumLength + "----lastTime : " + lastTime - + " thread = "+ Thread.currentThread().getName()); - - mCurrentOCHOrder.decreaseTravelDistance(lastSumLength); - if (mOrderStatusCallback != null) { - mOrderStatusCallback.onCurrentOrderDistToEndChanged((long) lastSumLength, (long) lastTime); - } - - reportOrderRemain((long) lastSumLength, (long) lastTime); } /** From 7afcde119fcbec15f52655b68760dc5923527275 Mon Sep 17 00:00:00 2001 From: wangmingjun Date: Wed, 3 Aug 2022 17:01:47 +0800 Subject: [PATCH 03/30] =?UTF-8?q?[290=20bus/taxi]bus=E4=B9=98=E5=AE=A2?= =?UTF-8?q?=E5=B1=8F=E5=BC=80=E5=A7=8B=E8=AE=A1=E7=AE=97=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E4=B8=BA0=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../passenger/model/BusPassengerModel.java | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java index 6322d5dd04..050cfe77aa 100644 --- a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java @@ -410,21 +410,23 @@ public class BusPassengerModel { //计算当前位置和下一站的剩余点集合 //计算剩余点总里程和时间 calculateTwoStationsRoute(); - List lastPoints = CoordinateCalculateRouteUtil - .getRemainPointListByCompare(mTwoStationsRouts,mLongitude,mLatitude); + if (mTwoStationsRouts.size() > 0){ + List lastPoints = CoordinateCalculateRouteUtil + .getRemainPointListByCompare(mTwoStationsRouts,mLongitude,mLatitude); - float lastSumLength = 0; - if (lastPoints.size() == 1){ //只是最后一个点,计算当前位置和最后一个点的距离 - lastSumLength = CoordinateUtils.calculateLineDistance( - lastPoints.get(0).longitude, lastPoints.get(0).latitude, - mLongitude, mLatitude); - }else { - lastSumLength = CoordinateCalculateRouteUtil.calculateRouteSumLength(lastPoints); - } - double lastTime = lastSumLength / BusPassengerConst.BUS_AVERAGE_SPEED * 3.6 ; //秒 - CallerLogger.INSTANCE.d(M_BUS_P + TAG, "lastSumLength = " + lastSumLength); - if (mAutopilotPlanningCallback != null){ - mAutopilotPlanningCallback.routePlanningToNextStationChanged((long)lastSumLength,(long) lastTime); + float lastSumLength = 0; + if (lastPoints.size() == 1){ //只是最后一个点,计算当前位置和最后一个点的距离 + lastSumLength = CoordinateUtils.calculateLineDistance( + lastPoints.get(0).longitude, lastPoints.get(0).latitude, + mLongitude, mLatitude); + }else { + lastSumLength = CoordinateCalculateRouteUtil.calculateRouteSumLength(lastPoints); + } + double lastTime = lastSumLength / BusPassengerConst.BUS_AVERAGE_SPEED * 3.6 ; //秒 + CallerLogger.INSTANCE.d(M_BUS_P + TAG, "lastSumLength = " + lastSumLength); + if (mAutopilotPlanningCallback != null){ + mAutopilotPlanningCallback.routePlanningToNextStationChanged((long)lastSumLength,(long) lastTime); + } } } From 44d06f8d7980ad78e629d7640e4ebe6d6ec8765e Mon Sep 17 00:00:00 2001 From: xuxinchao <13522809046@163.com> Date: Wed, 3 Aug 2022 17:06:21 +0800 Subject: [PATCH 04/30] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E5=8D=B1=E9=99=A9?= =?UTF-8?q?=E8=BD=A6=E8=BE=86=E9=A2=9C=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #D77F70FF改为#D65D5AFF --- .../core/function/map/identify/IdentifyOriginDataDrawer.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/map/identify/IdentifyOriginDataDrawer.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/map/identify/IdentifyOriginDataDrawer.kt index 1d88c5f1e3..559cc42620 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/map/identify/IdentifyOriginDataDrawer.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/map/identify/IdentifyOriginDataDrawer.kt @@ -72,7 +72,7 @@ class IdentifyOriginDataDrawer : Identify, IMoGoAutopilotStatusListener { //0是leading障碍物,障碍物车身红色提示 trackObj?.let { colorTrafficData[trackId] = PlanningTrack( - "#D77F70FF", + "#D65D5AFF", CallerAutoPilotStatusListenerManager.getCurWgs84SatelliteTime() ) } From 4789c426e7fee745db95c1235b233bd345cb546c Mon Sep 17 00:00:00 2001 From: renwj Date: Wed, 3 Aug 2022 16:52:39 +0800 Subject: [PATCH 05/30] =?UTF-8?q?[RouteOpt]=E6=9B=B4=E6=94=B9API=EF=BC=8C?= =?UTF-8?q?=E9=98=B2=E6=AD=A2=E6=8A=9B=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/service/routeoverlay/MogoRouteOverlayManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/MogoRouteOverlayManager.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/MogoRouteOverlayManager.java index e7f02e4f15..32de230e96 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/MogoRouteOverlayManager.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/MogoRouteOverlayManager.java @@ -77,7 +77,7 @@ public class MogoRouteOverlayManager implements return; } synchronized (queue) { - List items = queue.getLast(); + List items = queue.peekLast(); if (items != null && !items.isEmpty()) { RouteOverlayDrawer.getInstance().drawTrajectoryList(items, location.getBearing()); } From ebad7806e3bbf3d3dee19b553f38ff1f8e27de86 Mon Sep 17 00:00:00 2001 From: renwj Date: Wed, 3 Aug 2022 16:53:29 +0800 Subject: [PATCH 06/30] =?UTF-8?q?[CrashFix]=E4=BC=98=E5=8C=96=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E6=8D=95=E8=8E=B7=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [xxx] --- app/build.gradle | 2 +- .../com/mogo/launcher/MogoApplication.java | 3 +- .../com/mogo/launcher/crash/CrashSystem.java | 218 ++++++++++++++++++ config.gradle | 1 - .../mogo-core-function-hmi/build.gradle | 2 +- 5 files changed, 221 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/com/mogo/launcher/crash/CrashSystem.java diff --git a/app/build.gradle b/app/build.gradle index 5e7d53898b..4ca4d03f22 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -230,7 +230,7 @@ aspectjx { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) //Crash日志收集 - implementation rootProject.ext.dependencies.crashSdk +// implementation rootProject.ext.dependencies.crashSdk implementation rootProject.ext.dependencies.androidxappcompat implementation rootProject.ext.dependencies.arouter implementation rootProject.ext.dependencies.boostmultidex diff --git a/app/src/main/java/com/mogo/launcher/MogoApplication.java b/app/src/main/java/com/mogo/launcher/MogoApplication.java index 41ea4abeeb..8f87eca0de 100644 --- a/app/src/main/java/com/mogo/launcher/MogoApplication.java +++ b/app/src/main/java/com/mogo/launcher/MogoApplication.java @@ -1,9 +1,9 @@ package com.mogo.launcher; -import com.auto.zhidao.logsdk.CrashSystem; import com.mogo.eagle.core.function.main.MainMoGoApplication; import com.mogo.eagle.core.utilcode.mogo.logger.LogLevel; import com.mogo.eagle.core.utilcode.mogo.logger.Logger; +import com.mogo.launcher.crash.CrashSystem; /** * @author congtaowang @@ -17,7 +17,6 @@ public class MogoApplication extends MainMoGoApplication { protected void initCrashConfig() { CrashSystem crashSystem = CrashSystem.getInstance(this); crashSystem.init(); - //设置debug模式,日志不上传 crashSystem.setDebug(BuildConfig.DEBUG); } diff --git a/app/src/main/java/com/mogo/launcher/crash/CrashSystem.java b/app/src/main/java/com/mogo/launcher/crash/CrashSystem.java new file mode 100644 index 0000000000..91742834a7 --- /dev/null +++ b/app/src/main/java/com/mogo/launcher/crash/CrashSystem.java @@ -0,0 +1,218 @@ +package com.mogo.launcher.crash; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Environment; +import android.text.TextUtils; +import android.util.Log; + +import com.mogo.cloud.passport.MoGoAiCloudClientConfig; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.lang.Thread.UncaughtExceptionHandler; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +public class CrashSystem implements UncaughtExceptionHandler { + public static final String TAG = "CrashSystem"; + private String mAppPackage = null; + private String mAppVersionCode = null; + private String mAppVersionName = null; + private String mAppName = null; + private String mOsVersion = null; + private String mDeviceId = null; + private UncaughtExceptionHandler mDefaultHandler; + private final Map info = new HashMap(); + private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); + private boolean mDebug = false; + private final List callbackList = new ArrayList<>(); + + private static CrashSystem sCrashSystem = null; + + private static final Object lock = new Object(); + + public void init() { + this.mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler(this); + } + + + /** + * 是否收集记录crash信息 + * @param debug 是否是debug + */ + public void setDebug(boolean debug) { + this.mDebug = debug; + } + + /** + * 添加crash事件回调 + */ + public void addCallback(CrashCallback callback) { + if(callback != null) { + callbackList.add(callback); + } + } + + private CrashSystem(Context context) { + this.inflateSystemInfo(context); + } + + public static CrashSystem getInstance(Context context) { + CrashSystem crashSystem = sCrashSystem; + if(crashSystem == null) { + synchronized (lock) { + crashSystem = sCrashSystem; + if(crashSystem == null) { + crashSystem = new CrashSystem(context.getApplicationContext()); + sCrashSystem = crashSystem; + } + } + } + return crashSystem; + } + + @Override + public void uncaughtException(Thread thread, Throwable ex) { + try { + this.handleException(ex); + dispatchCrashError(); + } finally { + if (mDefaultHandler != null) { + mDefaultHandler.uncaughtException(thread, ex); + } + } + } + + /** + * 分发异常事件 + */ + private void dispatchCrashError() { + for (CrashCallback callback : callbackList) { + if(callback != null) { + callback.onCrashError(); + } + } + } + + private boolean handleException(Throwable ex) { + if(ex == null) { + return true; + } else { + String msg = ex.getLocalizedMessage(); + Log.e("CrashSystem", msg); + String filePath = saveCrashInfo2File(ex); + Log.i(TAG, "handleException: filePath = " + filePath); + return true; + } + } + + private String saveCrashInfo2File(Throwable ex) { + try { + if(!Environment.getExternalStorageState().equals("mounted")) { + return null; + } + File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "crash"); + if(!dir.exists()) { + dir.mkdir(); + } + String[] fileList = dir.list((dir1, name) -> name.contains(mAppPackage)); + if(fileList == null || fileList.length >= 20) { //避免crash日志一直重复 + return null; + } + String time = this.format.format(new Date()); + String fileName = "app-crash-" + this.mAppPackage + "-" + time + ".log"; + if(mDebug) { + fileName = "debug-" + fileName; + } + String fileTemp = fileName + ".temp"; + StringBuilder sb = new StringBuilder(); + Iterator> var4 = this.info.entrySet().iterator(); + String result; + while(var4.hasNext()) { + Entry entry = var4.next(); + String key = entry.getKey(); + result = entry.getValue(); + sb.append(key).append("=").append(result).append("\n"); + } + sb.append("TIME=").append(String.valueOf(System.currentTimeMillis())).append("\n"); + sb.append("fileName=").append(fileName).append("\n"); + Writer writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + ex.printStackTrace(pw); + for(Throwable cause = ex.getCause(); cause != null; cause = cause.getCause()) { + cause.printStackTrace(pw); + } + pw.close(); + result = writer.toString(); + sb.append(result); + FileOutputStream fos = null; + try { + File dest = new File(dir, fileTemp); + fos = new FileOutputStream(dest); + fos.write(sb.toString().getBytes()); + fos.flush(); + File file = new File(dir,fileName); + dest.renameTo(file); + return dir.getAbsolutePath() + File.separator + fileName; + } catch (IOException var13) { + var13.printStackTrace(); + } finally { + try { + if (fos != null) { + fos.close(); + } + } catch (IOException ignore) {} + } + } catch (Throwable ignore) { + } + return null; + } + + private void inflateSystemInfo(Context context) { + this.mAppPackage = context.getPackageName(); + PackageManager pm = context.getPackageManager(); + try { + PackageInfo packageInfo = pm.getPackageInfo(this.mAppPackage, 0); + this.mAppVersionCode = "" + packageInfo.versionCode; + this.mAppVersionName = packageInfo.versionName; + this.mAppPackage = packageInfo.packageName; + this.mAppName = packageInfo.applicationInfo.loadLabel(context.getPackageManager()).toString(); + this.mOsVersion = Build.DISPLAY; + String deviceId = MoGoAiCloudClientConfig.getInstance().getSn(); + if(TextUtils.isEmpty(deviceId)) { + deviceId = "11111111"; + } + this.mDeviceId = deviceId; + } catch (Exception var5) { + var5.printStackTrace(); + } + + this.info.put("appName",this.mAppName); + this.info.put("appPackageName", this.mAppPackage); + this.info.put("versionCode", this.mAppVersionCode); + this.info.put("versionName", this.mAppVersionName); + this.info.put("sn", this.mDeviceId); + this.info.put("DISPLAY", this.mOsVersion); + } + + public interface CrashCallback { + void onCrashError(); + } +} + diff --git a/config.gradle b/config.gradle index 1fb4d25a1b..183c9f761d 100644 --- a/config.gradle +++ b/config.gradle @@ -89,7 +89,6 @@ ext { jetbrainsannotationsjava5 : "org.jetbrains:annotations-java5:15.0", // crash - crashSdk : "com.zhidaoauto.crash.log:library:1.0.5", kotlinstdlibjdk7 : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${kotlin_version}", //探路使用的直播组件 diff --git a/core/function-impl/mogo-core-function-hmi/build.gradle b/core/function-impl/mogo-core-function-hmi/build.gradle index bad3ffbcc4..9822314159 100644 --- a/core/function-impl/mogo-core-function-hmi/build.gradle +++ b/core/function-impl/mogo-core-function-hmi/build.gradle @@ -62,7 +62,7 @@ dependencies { implementation rootProject.ext.dependencies.androidxroomktx //Crash日志收集 - implementation rootProject.ext.dependencies.crashSdk +// implementation rootProject.ext.dependencies.crashSdk implementation rootProject.ext.dependencies.boostmultidex debugImplementation rootProject.ext.dependencies.debugleakcanary From 789afc54718ff4edefa608d1316b7cfcf535199c Mon Sep 17 00:00:00 2001 From: wangmingjun Date: Wed, 3 Aug 2022 17:40:52 +0800 Subject: [PATCH 07/30] =?UTF-8?q?[290=20bus/taxi]taxi=E5=8F=B8=E6=9C=BA?= =?UTF-8?q?=E7=AB=AF=E8=BD=A8=E8=BF=B9=E6=95=B0=E6=8D=AE=E6=B8=85=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/mogo/och/taxi/model/TaxiModel.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/TaxiModel.java b/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/TaxiModel.java index 5b151461f5..a06c4210e4 100644 --- a/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/TaxiModel.java +++ b/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/TaxiModel.java @@ -1268,7 +1268,10 @@ public class TaxiModel { Logger.d(M_TAXI + TAG, "--------计算出sumLength开始---------- "); //转换成高德坐标系 - mRoutePoints = CoordinateCalculateRouteUtil.coordinateConverterWgsToGcjListCommon(mContext, models); + if (mRoutePoints.size() > 0){ + mRoutePoints.clear(); + } + mRoutePoints.addAll(CoordinateCalculateRouteUtil.coordinateConverterWgsToGcjListCommon(mContext, models)); startDynamicCalculateRouteInfo(); } From 7a5911988835d55f4a6452081fdbb85a641501a9 Mon Sep 17 00:00:00 2001 From: pangfan Date: Wed, 3 Aug 2022 19:38:44 +0800 Subject: [PATCH 08/30] =?UTF-8?q?[Bus/Taxi=20driver=20v2.9.0]opt=EF=BC=9A?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=89=93release=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OCH/mogo-och-bus-passenger/build.gradle | 16 +++++++--------- OCH/mogo-och-taxi-passenger/build.gradle | 16 +++++++--------- OCH/mogo-och-taxi/build.gradle | 16 +++++++--------- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/OCH/mogo-och-bus-passenger/build.gradle b/OCH/mogo-och-bus-passenger/build.gradle index 4bc7c0fd4c..f9be5b07ca 100644 --- a/OCH/mogo-och-bus-passenger/build.gradle +++ b/OCH/mogo-och-bus-passenger/build.gradle @@ -29,15 +29,13 @@ android { } buildTypes { - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - debug { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + debug { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } diff --git a/OCH/mogo-och-taxi-passenger/build.gradle b/OCH/mogo-och-taxi-passenger/build.gradle index d3b586a5ed..cd67326bc9 100644 --- a/OCH/mogo-och-taxi-passenger/build.gradle +++ b/OCH/mogo-och-taxi-passenger/build.gradle @@ -29,15 +29,13 @@ android { } buildTypes { - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - debug { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + debug { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } diff --git a/OCH/mogo-och-taxi/build.gradle b/OCH/mogo-och-taxi/build.gradle index 11d63d9a60..307d440922 100644 --- a/OCH/mogo-och-taxi/build.gradle +++ b/OCH/mogo-och-taxi/build.gradle @@ -29,15 +29,13 @@ android { } buildTypes { - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - debug { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + debug { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } From e7f57c1cfc6b894e9e1b7772a97646f553caa414 Mon Sep 17 00:00:00 2001 From: renwj Date: Wed, 3 Aug 2022 19:47:55 +0800 Subject: [PATCH 09/30] =?UTF-8?q?[V2X]=E4=BC=98=E5=8C=96V2X=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E5=9C=A8=E5=AD=90=E7=BA=BF=E7=A8=8B=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../functions/test/AutoPilotBadCaseTest.kt | 6 +-- .../com/mogo/functions/test/ReminderTest.kt | 53 ++++++++++++++++--- .../core/function/hmi/ui/MoGoHmiFragment.kt | 31 +++++------ .../eagle/core/utilcode/reminder/Reminder.kt | 29 ++++++---- .../reminder/api/impl/PopupWindowReminder.kt | 2 +- 5 files changed, 86 insertions(+), 35 deletions(-) diff --git a/app/src/androidTest/java/com/mogo/functions/test/AutoPilotBadCaseTest.kt b/app/src/androidTest/java/com/mogo/functions/test/AutoPilotBadCaseTest.kt index 766ef7cb4e..473cc51913 100644 --- a/app/src/androidTest/java/com/mogo/functions/test/AutoPilotBadCaseTest.kt +++ b/app/src/androidTest/java/com/mogo/functions/test/AutoPilotBadCaseTest.kt @@ -52,7 +52,7 @@ class AutoPilotBadCaseTest { it.timestamp = SimpleDateFormat("yyyyMMddHHmmss").format(Date()) index++ } - CallerDevaToolsManager.onReceiveBadCaseRecord(builder.build()) + // CallerDevaToolsManager.onReceiveBadCaseRecord(builder.build()) } .flowOn(Dispatchers.Default) .collect() @@ -86,7 +86,7 @@ class AutoPilotBadCaseTest { it.timestamp = SimpleDateFormat("yyyyMMddHHmmss").format(Date()) index++ } - CallerDevaToolsManager.onReceiveBadCaseRecord(builder.build()) + // CallerDevaToolsManager.onReceiveBadCaseRecord(builder.build()) } .flowOn(Dispatchers.Default) .collect() @@ -114,7 +114,7 @@ class AutoPilotBadCaseTest { it.timestamp = SimpleDateFormat("yyyyMMddHHmmss").format(Date()) index++ } - CallerDevaToolsManager.onReceiveBadCaseRecord(builder.build()) + // CallerDevaToolsManager.onReceiveBadCaseRecord(builder.build()) } .flowOn(Dispatchers.Default) .collect() diff --git a/app/src/androidTest/java/com/mogo/functions/test/ReminderTest.kt b/app/src/androidTest/java/com/mogo/functions/test/ReminderTest.kt index de9ad31d87..cb0356b507 100644 --- a/app/src/androidTest/java/com/mogo/functions/test/ReminderTest.kt +++ b/app/src/androidTest/java/com/mogo/functions/test/ReminderTest.kt @@ -20,6 +20,7 @@ import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener import com.mogo.eagle.core.function.hmi.notification.WarningFloat import com.mogo.eagle.core.function.hmi.notification.anim.DefaultAnimator import com.mogo.eagle.core.data.enums.SidePattern +import com.mogo.eagle.core.function.hmi.ui.* import com.mogo.eagle.core.function.main.MainLauncherActivity import com.mogo.eagle.core.utilcode.kotlin.shape import com.mogo.eagle.core.utilcode.reminder.Reminder @@ -27,14 +28,14 @@ import com.mogo.eagle.core.utilcode.reminder.api.impl.ActivityReminder import com.mogo.eagle.core.utilcode.reminder.api.impl.PopupWindowReminder import com.mogo.eagle.core.utilcode.reminder.api.impl.ViewReminder import com.mogo.eagle.core.utilcode.util.AppStateManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.* +import kotlinx.coroutines.flow.* import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import java.lang.Integer.min -import java.util.concurrent.TimeUnit +import java.util.concurrent.* +import java.util.concurrent.TimeUnit.MILLISECONDS @RunWith(AndroidJUnit4::class) @@ -64,6 +65,46 @@ class ReminderTest { return@runBlocking } + @Test + fun testShowWarningV2x() = runBlocking { + val f = ensureMoGoHmiFragmentShow() + + delay(5000) + (1 until 20).map { + it + }.asFlow() + .onEach { + f.showWarningV2X("10006", "test", "测试$it", "$it", null, true, 5000) + } + .flowOn(Dispatchers.Default) + .collect() + delay(3000000) + } + + private suspend fun ensureMoGoHmiFragmentShow(): MoGoHmiFragment = suspendCancellableCoroutine { + launch.onActivity { itx -> + val executor = Executors.newSingleThreadScheduledExecutor() + executor.scheduleAtFixedRate({ + var find = + itx.supportFragmentManager.fragments.find { it is MoGoHmiFragment } as? MoGoHmiFragment + while (find == null) { + find = + itx.supportFragmentManager.fragments.find { it is MoGoHmiFragment } as? MoGoHmiFragment + } + while (!find.isResumed) { + Thread.sleep(500) + } + it.resumeWith(Result.success(find)) + try { + Thread.sleep(500) + executor.shutdownNow() + } catch (e: Throwable) { + e.printStackTrace() + } + }, 50, 500, MILLISECONDS) + } + } + @Test fun testViewReminderOverride() = runBlocking(Dispatchers.Main) { launch.onActivity { @@ -357,14 +398,14 @@ class ReminderTest { } } - class TestPopupWindowReminder(private val anchor: View, private val popupWindow: PopupWindow): PopupWindowReminder(popupWindow) { + class TestPopupWindowReminder(private val anchor: View, override val popupWindow: PopupWindow): PopupWindowReminder(popupWindow) { override fun show() { popupWindow.showAtLocation(anchor, Gravity.CENTER, 0, 0) } } - class TestPopupWindowReminderOverride(private val anchor: View, private val popupWindow: PopupWindow): PopupWindowReminder(popupWindow) { + class TestPopupWindowReminderOverride(private val anchor: View, override val popupWindow: PopupWindow): PopupWindowReminder(popupWindow) { override fun show() { popupWindow.showAtLocation(anchor, Gravity.CENTER, 0, 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 aa21b0bfd5..8c0936b3aa 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 @@ -146,6 +146,8 @@ import java.util.* private var speakJob: Job? = null + private var showV2XJob: Job? = null + private var showingV2XTip: IReminder? = null private var roadVideoDialog: RoadVideoDialog? = null @@ -606,11 +608,9 @@ import java.util.* CallerLogger.e("$M_HMI$TAG", "Show warningContent is null or empty!") return } - speakJob?.safeCancel() val content = mViewNotificationProvider?.getNotificationView() ?: return content.setWarningIcon(EventTypeEnum.getWarningIcon(v2xType)) content.setWarningContent(warningContent) - var reminder: IReminder? = null Log.d("$M_HMI$TAG", "--- show v2x dialog 1 ---: info -> v2x-type: $v2xType : expireTime: $expireTime") Reminder.enqueue(this@MoGoHmiFragment, object : PopupWindowReminder(PopupWindow(content, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT).also { itx -> itx.isTouchable = false @@ -633,43 +633,44 @@ import java.util.* } }) { override fun show() { + showV2XJob?.safeCancel() + speakJob?.safeCancel() val parent = it.window.decorView parent.doOnAttach { Log.d("$M_HMI$TAG", "--- show v2x dialog 2 ---: info -> v2x-type: $v2xType : expireTime: $expireTime") popupWindow.showAtLocation(parent, content.layoutGravity, 0, 0) } } - override fun isOverride(): Boolean { return true } - }.also { itx -> reminder = itx }, object : IStateChangeListener { + }, object : IStateChangeListener { override fun onShow(reminder: IReminder) { listener?.onShow() + showingV2XTip = reminder + lifecycleScope.launch { + delay(expireTime) + }.also { itx -> + showV2XJob = itx + }.invokeOnCompletion { _ -> + reminder.hide() + } if (ttsContent != null && !TextUtils.isEmpty(ttsContent) && playTTS) { lifecycleScope.launch { speak(it, ttsContent) - }.also { - speakJob = it + }.also { itx -> + speakJob = itx } } } override fun onHide(reminder: IReminder) { listener?.onDismiss() + showingV2XTip = null showWarning(WarningDirectionEnum.ALERT_WARNING_NON) } }) - - if (reminder == null) { - return - } - showingV2XTip = reminder - lifecycleScope.launch { - delay(expireTime) - reminder?.hide() - } } } diff --git a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/reminder/Reminder.kt b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/reminder/Reminder.kt index f8aec8fd23..d0cbe616d3 100644 --- a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/reminder/Reminder.kt +++ b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/reminder/Reminder.kt @@ -100,17 +100,23 @@ object Reminder { if (key.isEmpty()) { throw IllegalStateException("reminder: ${reminder.javaClass.name}'s key can't be empty.") } - if (enqueued.contains(key)) { - return + synchronized(enqueued) { + if (enqueued.contains(key)) { + return + } + enqueued += key } - enqueued += key - attaches.getOrPut(attachTo) { - mutableListOf() - }.also { - it.add(WeakReference(reminder)) + synchronized(attaches) { + attaches.getOrPut(attachTo) { + mutableListOf() + }.also { + it.add(WeakReference(reminder)) + } } - listener?.let { - reminderListeners[reminder] = it + synchronized(reminderListeners) { + listener?.let { + reminderListeners[reminder] = it + } } scope.launch { if (reminder is ActivityReminder) { @@ -131,11 +137,14 @@ object Reminder { heap += reminder dequeueHeap() } else { - queue += reminder val pre = findPreShowedReminder() if (pre != null) { pre.hide() + queue.clear() + queue += reminder } else { + queue.clear() + queue += reminder dequeue() } } diff --git a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/reminder/api/impl/PopupWindowReminder.kt b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/reminder/api/impl/PopupWindowReminder.kt index 7e1045088c..65c063292e 100644 --- a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/reminder/api/impl/PopupWindowReminder.kt +++ b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/reminder/api/impl/PopupWindowReminder.kt @@ -4,7 +4,7 @@ import android.widget.PopupWindow import androidx.lifecycle.LifecycleOwner import com.mogo.eagle.core.utilcode.reminder.api.IReminder -abstract class PopupWindowReminder(val popupWindow: PopupWindow): IReminder { +abstract class PopupWindowReminder(open val popupWindow: PopupWindow): IReminder { override fun lifecycleOwner(): LifecycleOwner = popupWindow.lifecycleOwner From 05f4a8b3717fa806681b8d1873ab5b39533e69c6 Mon Sep 17 00:00:00 2001 From: zhongchao Date: Wed, 3 Aug 2022 18:50:13 +0800 Subject: [PATCH 10/30] ui problem --- .../hmi/ui/widget/TrafficDataView.java | 38 ++++++++++--------- .../src/main/res/layout/hmi_traffic_data.xml | 15 +++++++- .../res/values-xhdpi-2560x1440/dimens.xml | 4 ++ 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/TrafficDataView.java b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/TrafficDataView.java index 0f2d237421..f669c9487e 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/TrafficDataView.java +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/TrafficDataView.java @@ -42,6 +42,8 @@ public class TrafficDataView extends ConstraintLayout { private static final int MSG_SEND_UPDATE = 1; private volatile double acceleration; + private volatile float mBrake; + private volatile float mThrottle; @SuppressLint("HandlerLeak") private final Handler handler = new Handler() { @@ -49,10 +51,24 @@ public class TrafficDataView extends ConstraintLayout { public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); if (msg.what == MSG_SEND_UPDATE) { - java.text.DecimalFormat mFormat = new java.text.DecimalFormat("0.00"); + java.text.DecimalFormat mFormat = new java.text.DecimalFormat("0.0"); String accStr = mFormat.format(acceleration); - accTextView.setText("a: " + accStr); + if (acceleration > 0f) { + accTextView.setText(accStr); + } else { + accTextView.setText("—" + accStr); + } + + if (mBrake > 0) { + brakeStatus.setImageResource(R.drawable.traffic_data_brake); + } else if (mThrottle >= 0 && mBrake == 0) { + brakeStatus.setImageResource(R.drawable.traffic_data_accelerator); + } else { + brakeStatus.setImageResource(R.drawable.traffic_data_empty); + } + } + handler.sendEmptyMessageDelayed(MSG_SEND_UPDATE, 1000L); } }; @@ -76,12 +92,12 @@ public class TrafficDataView extends ConstraintLayout { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); + handler.sendEmptyMessageDelayed(MSG_SEND_UPDATE, 1000L); CallerAutopilotVehicleStateListenerManager.INSTANCE.addListener(TAG, mIMoGoAutopilotVehicleStateListener); CallerAutopilotCarStatusListenerManager.INSTANCE.addListener(TAG, gnssInfo -> { if (gnssInfo != null) { acceleration = gnssInfo.getAcceleration(); } - handler.sendEmptyMessageDelayed(MSG_SEND_UPDATE, 1000L); }); } @@ -162,25 +178,13 @@ public class TrafficDataView extends ConstraintLayout { @Override public void onAutopilotBrake(float brake) { CallerLogger.INSTANCE.d(TAG, "刹车:" + brake); - ThreadUtils.runOnUiThread(() -> { - if (brake > 0) { - brakeStatus.setImageResource(R.drawable.traffic_data_brake); - } else { - brakeStatus.setImageResource(R.drawable.traffic_data_empty); - } - }); + mBrake = brake; } @Override public void onAutopilotThrottle(float throttle) { CallerLogger.INSTANCE.d(TAG, "油门:" + throttle); - ThreadUtils.runOnUiThread(() -> { - if (throttle > 0) { - brakeStatus.setImageResource(R.drawable.traffic_data_accelerator); - } else { - brakeStatus.setImageResource(R.drawable.traffic_data_empty); - } - }); + mThrottle = throttle; } }; diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/hmi_traffic_data.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/hmi_traffic_data.xml index e96bc08d6a..754b67fde0 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/hmi_traffic_data.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/hmi_traffic_data.xml @@ -73,8 +73,19 @@ android:id="@+id/speedAccTextView" android:layout_width="wrap_content" android:layout_height="@dimen/dp_56" - android:layout_marginLeft="@dimen/dp_42" - android:text="a: " + android:layout_marginEnd="@dimen/dp_80" + android:gravity="end" + android:textColor="#fff" + android:textSize="@dimen/dp_40" + app:layout_constraintBottom_toBottomOf="@+id/brakeStatus" + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toTopOf="@+id/brakeStatus"/> + + 12px + 14px 20px 22px 43px + 50px 57px + 60px 72px + 80px 88px 26px 30px From 72d5cd8d884cbf87a9b09b1a7cae8ad1f77dde31 Mon Sep 17 00:00:00 2001 From: zhongchao Date: Wed, 3 Aug 2022 19:43:07 +0800 Subject: [PATCH 11/30] ui --- .../eagle/core/function/hmi/ui/widget/TrafficDataView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/TrafficDataView.java b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/TrafficDataView.java index f669c9487e..fdde4791ac 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/TrafficDataView.java +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/TrafficDataView.java @@ -52,11 +52,11 @@ public class TrafficDataView extends ConstraintLayout { super.handleMessage(msg); if (msg.what == MSG_SEND_UPDATE) { java.text.DecimalFormat mFormat = new java.text.DecimalFormat("0.0"); - String accStr = mFormat.format(acceleration); + String accStr = mFormat.format(Math.abs(acceleration)); if (acceleration > 0f) { accTextView.setText(accStr); } else { - accTextView.setText("—" + accStr); + accTextView.setText("- " + accStr); } if (mBrake > 0) { From 4cbf7d9083b828a1d577c9003a636c0101fe9696 Mon Sep 17 00:00:00 2001 From: zhongchao Date: Wed, 3 Aug 2022 20:16:32 +0800 Subject: [PATCH 12/30] fix trafficdataview ui logic problem --- .../hmi/ui/widget/TrafficDataView.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/TrafficDataView.java b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/TrafficDataView.java index fdde4791ac..cc2d7aa78d 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/TrafficDataView.java +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/TrafficDataView.java @@ -14,6 +14,7 @@ import androidx.annotation.Nullable; import androidx.constraintlayout.widget.ConstraintLayout; import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotVehicleStateListener; +import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager; import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarStatusListenerManager; import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotVehicleStateListenerManager; import com.mogo.eagle.core.function.hmi.R; @@ -58,15 +59,19 @@ public class TrafficDataView extends ConstraintLayout { } else { accTextView.setText("- " + accStr); } - - if (mBrake > 0) { - brakeStatus.setImageResource(R.drawable.traffic_data_brake); - } else if (mThrottle >= 0 && mBrake == 0) { - brakeStatus.setImageResource(R.drawable.traffic_data_accelerator); - } else { + int state = CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo().getState(); + if (state < 2) { + if (mBrake > 0) { + brakeStatus.setImageResource(R.drawable.traffic_data_brake); + } else if (mThrottle >= 0 && mBrake == 0) { + brakeStatus.setImageResource(R.drawable.traffic_data_accelerator); + } else { + brakeStatus.setImageResource(R.drawable.traffic_data_empty); + } + } + if (state == 2) { brakeStatus.setImageResource(R.drawable.traffic_data_empty); } - } handler.sendEmptyMessageDelayed(MSG_SEND_UPDATE, 1000L); } From fea9f20480f5753036b028468d20e06ae4440c06 Mon Sep 17 00:00:00 2001 From: wangmingjun Date: Wed, 3 Aug 2022 20:28:35 +0800 Subject: [PATCH 13/30] =?UTF-8?q?[290=20bus/taxi]taxi=E5=8F=B8=E6=9C=BA?= =?UTF-8?q?=E7=AB=AF=E5=AE=8C=E6=88=90=E4=B8=80=E5=8D=95=E5=90=8E=E5=89=A9?= =?UTF-8?q?=E4=BD=99=E9=87=8C=E7=A8=8B=E5=92=8C=E6=97=B6=E9=97=B4=E6=B8=85?= =?UTF-8?q?=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/mogo/och/taxi/model/TaxiModel.java | 8 +++++--- .../mogo/och/taxi/ui/TaxiBeingServerdOrdersFragment.java | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/TaxiModel.java b/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/TaxiModel.java index a06c4210e4..b5c057b931 100644 --- a/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/TaxiModel.java +++ b/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/TaxiModel.java @@ -1208,8 +1208,10 @@ public class TaxiModel { @Override public void onAutopilotRotting(MessagePad.GlobalPathResp routeList) { - CallerLogger.INSTANCE.d(M_TAXI + TAG, "onAutopilotRotting = " - + GsonUtil.jsonFromObject(routeList)); + if (null != routeList && routeList.getWayPointsList() != null){ + CallerLogger.INSTANCE.d(M_TAXI + TAG, "getWayPointsList = " + + routeList.getWayPointsList().size()); + } if (null != routeList && routeList.getWayPointsList().size() > 0) { updateOrderRoute(routeList.getWayPointsList()); updateOrderRouteInfo(routeList.getWayPointsList()); @@ -1327,7 +1329,7 @@ public class TaxiModel { new TaxiServiceCallback() { @Override public void onSuccess(QueryOrderRouteResp data) { - if (data != null && data.data != null) { + if (data != null && data.data != null && mRoutePoints.size() == 0) { mRoutePoints.clear(); mRoutePoints.addAll(data.data); } diff --git a/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/ui/TaxiBeingServerdOrdersFragment.java b/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/ui/TaxiBeingServerdOrdersFragment.java index a5e09fe2dd..c1a2ec1ff7 100644 --- a/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/ui/TaxiBeingServerdOrdersFragment.java +++ b/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/ui/TaxiBeingServerdOrdersFragment.java @@ -167,6 +167,8 @@ public class TaxiBeingServerdOrdersFragment extends BaseTaxiUIFragment implement if (order.orderStatus == TaxiOrderStatusEnum.JourneyCompleted.getCode()) { mCurrentOrder = null; isHaveBeingOrder(false); + mDistanceAndTime2.setText("距离 - - 公里,用时 - - 分"); + mDistanceAndTime3.setText("距离 - - 公里,用时 - - 分"); return; } mOrderNo = order.orderNo; @@ -407,6 +409,8 @@ public class TaxiBeingServerdOrdersFragment extends BaseTaxiUIFragment implement if (status == TaxiOrderStatusEnum.None.getCode() || status == TaxiOrderStatusEnum.Cancel.getCode() || status == TaxiOrderStatusEnum.JourneyCompleted.getCode()) { isHaveBeingOrder(false); mCurrentOrder = null; + mDistanceAndTime2.setText("距离 - - 公里,用时 - - 分"); + mDistanceAndTime3.setText("距离 - - 公里,用时 - - 分"); } else { isHaveBeingOrder(true); } From 13deff1e2f6a389ef54b0524e1357a9653f693ef Mon Sep 17 00:00:00 2001 From: wangmingjun Date: Wed, 3 Aug 2022 20:32:21 +0800 Subject: [PATCH 14/30] =?UTF-8?q?[290=20bus/taxi]bus=E5=8F=B8=E6=9C=BA?= =?UTF-8?q?=E7=AB=AF=E4=BC=98=E5=8C=96=E8=BD=A8=E8=BF=B9=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mogo/och/bus/passenger/model/BusPassengerModel.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java index 050cfe77aa..4cf55d2582 100644 --- a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java @@ -409,7 +409,9 @@ public class BusPassengerModel { public void dynamicCalculateRouteInfo() { //计算当前位置和下一站的剩余点集合 //计算剩余点总里程和时间 - calculateTwoStationsRoute(); + if (mTwoStationsRouts.size() == 0){ + calculateTwoStationsRoute(); + } if (mTwoStationsRouts.size() > 0){ List lastPoints = CoordinateCalculateRouteUtil .getRemainPointListByCompare(mTwoStationsRouts,mLongitude,mLatitude); @@ -481,6 +483,7 @@ public class BusPassengerModel { if (isStart) { BusPassengerModelLoopManager.getInstance().startCalculateRouteInfoLoop(); } else { + mTwoStationsRouts.clear(); BusPassengerModelLoopManager.getInstance().stopCalculateRouteInfLoop(); } } From 7a496631abbb071173d3d93ba5f364594dc675ae Mon Sep 17 00:00:00 2001 From: yangyakun Date: Wed, 3 Aug 2022 20:52:31 +0800 Subject: [PATCH 15/30] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E3=80=81=E9=99=90=E5=88=B6=E5=A4=9A=E8=BF=9B=E7=A8=8B=E9=80=9A?= =?UTF-8?q?=E8=AE=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mulprocess/OrderServiceImpl.java | 8 ++- .../passenger/ui/leftmenu/LeftMenuOpen.kt | 56 +++++++++++++------ .../ui/leftmenu/OverlayLeftViewUtils.kt | 2 +- .../taxi/passenger/ui/video/VideoActivity.kt | 23 ++++++-- 4 files changed, 63 insertions(+), 26 deletions(-) diff --git a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/mulprocess/OrderServiceImpl.java b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/mulprocess/OrderServiceImpl.java index 73eb617d82..006be38689 100644 --- a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/mulprocess/OrderServiceImpl.java +++ b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/mulprocess/OrderServiceImpl.java @@ -2,15 +2,19 @@ package com.mogo.och.taxi.passenger.mulprocess; import android.os.RemoteException; +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.util.UiThreadHandler; import com.mogo.och.taxi.passenger.ui.leftmenu.LeftMenuOpen; import com.mogo.och.taxi.passenger.ui.leftmenu.OverlayLeftViewUtils; public class OrderServiceImpl extends ILeftMenuService.Stub { + public static final String TAG = "mulprocessOrderServiceImpl"; + @Override public void transmissionIndex(int index) throws RemoteException { - + CallerLogger.INSTANCE.d(SceneConstant.M_TAXI_P + TAG, "跨进程 transmissionIndex"+index); UiThreadHandler.getsUiHandler().post(() -> { OverlayLeftViewUtils.INSTANCE.transmissionIndexGet(index); }); @@ -18,11 +22,13 @@ public class OrderServiceImpl extends ILeftMenuService.Stub { @Override public void registerCallback(ICallback cb) throws RemoteException { + CallerLogger.INSTANCE.d(SceneConstant.M_TAXI_P + TAG, "跨进程 registerCallback"); LeftMenuOpen.INSTANCE.registerCallbackHost(cb); } @Override public void unRegisterCallback(ICallback cb) throws RemoteException { + CallerLogger.INSTANCE.d(SceneConstant.M_TAXI_P + TAG, "跨进程 unRegisterCallback"); LeftMenuOpen.INSTANCE.unregisterCallbackHost(cb); } diff --git a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/leftmenu/LeftMenuOpen.kt b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/leftmenu/LeftMenuOpen.kt index 18e823eb47..39cb1770a3 100644 --- a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/leftmenu/LeftMenuOpen.kt +++ b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/leftmenu/LeftMenuOpen.kt @@ -10,6 +10,8 @@ import android.view.MotionEvent import android.view.View import android.view.ViewGroup import android.view.WindowManager +import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger +import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_TAXI_P import com.mogo.eagle.core.utilcode.util.UiThreadHandler import com.mogo.eagle.core.utilcode.util.Utils import com.mogo.och.taxi.passenger.R @@ -25,6 +27,8 @@ import rx.schedulers.Schedulers @SuppressLint("StaticFieldLeak") object LeftMenuOpen { + const val TAG = "mulprocessLeftMenuOpen" + private var windowView: View? = null private var wl: WindowManager.LayoutParams? = null private var windowManager: WindowManager? = null @@ -43,7 +47,7 @@ object LeftMenuOpen { var checkIndex = OverlayLeftViewUtils.LIVE private var lastClickTime = 0L - private const val FAST_CLICK_DELAY_TIME = 1000 // 防止事件发送过快 + private const val FAST_CLICK_DELAY_TIME = 1300 // 防止事件发送过快 fun setValue( @@ -51,7 +55,8 @@ object LeftMenuOpen { wl: WindowManager.LayoutParams?, windowManager: WindowManager?, close: (view: View, windowManager: WindowManager?) -> Unit, - open: (view: View, windowManager: WindowManager?) -> Unit + open: (view: View, windowManager: WindowManager?) -> Unit, + isMainProcess: Boolean ) { this.open = open this.close = close @@ -61,7 +66,9 @@ object LeftMenuOpen { dragList.forEach { registerDragView(it) } - registerC() + if(!isMainProcess) { + registerC() + } } fun clearValue() { @@ -168,9 +175,9 @@ object LeftMenuOpen { fun registerDragView(view: View?) { if (view != null) { dragList.add(view) - if (orderService == null) { - registerC() - } +// if (orderService == null) { +// registerC() +// } view.setOnTouchListener(ItemViewTouchListener()) view.setOnClickListener { open?.let { it1 -> it1(windowView!!, windowManager) } @@ -193,6 +200,7 @@ object LeftMenuOpen { } fun transmissionIndex(index:Int){ + CallerLogger.d(M_TAXI_P + TAG, "tran--transmissionIndex---$index") if (orderService == null) { registerC() } @@ -200,22 +208,23 @@ object LeftMenuOpen { } fun registerCallbackHost(cb:ICallback?){ - if (orderService == null) { - registerC() - } +// if (orderService == null) { +// registerC() +// } cb?.let { - icallbacks?.register(it) + icallbacks.register(it) } } fun unregisterCallbackHost(cb:ICallback?){ cb?.let { - icallbacks?.unregister(it) + icallbacks.unregister(it) } } fun registerCallback(cb:ICallback?){ + CallerLogger.d(M_TAXI_P + TAG, "tran--registerCallback--注册") if (orderService == null) { registerC() } @@ -225,6 +234,7 @@ object LeftMenuOpen { } fun unregisterCallback(cb:ICallback?){ + CallerLogger.d(M_TAXI_P + TAG, "tran--unregisterCallback--反注册") cb?.let { orderService?.unRegisterCallback(it) } @@ -240,15 +250,20 @@ object LeftMenuOpen { Observable.empty().subscribeOn(Schedulers.io()) .subscribe(object : Observer { override fun onCompleted() { - val len = icallbacks.beginBroadcast() - for (i in 0 until len) { - try { - icallbacks.getBroadcastItem(i).onResult(meters, timeInSecond, speed) - } catch (e: RemoteException) { - e.printStackTrace() + CallerLogger.d(M_TAXI_P + TAG, "callCallBack$meters--$timeInSecond--$speed") + try { + val len = icallbacks.beginBroadcast() + for (i in 0 until len) { + try { + icallbacks.getBroadcastItem(i).onResult(meters, timeInSecond, speed) + } catch (e: RemoteException) { + e.printStackTrace() + } } + icallbacks.finishBroadcast() + }catch (e:Exception){ + CallerLogger.e(M_TAXI_P + TAG, "callCallBack${e.message}") } - icallbacks.finishBroadcast() } override fun onError(e: Throwable?) {} override fun onNext(t: String?) {} @@ -273,7 +288,12 @@ object LeftMenuOpen { * 主进程在显示是主动调用 * video进程在天津View是判断是否调用了 */ + @Synchronized private fun registerC() { + if(orderService!=null){ + return + } + CallerLogger.d(M_TAXI_P + TAG, "tran--registerC--获取jni") val resolver: ContentResolver = Utils.getApp().contentResolver cu = resolver.query( diff --git a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/leftmenu/OverlayLeftViewUtils.kt b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/leftmenu/OverlayLeftViewUtils.kt index 50a5e225b5..53ba767892 100644 --- a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/leftmenu/OverlayLeftViewUtils.kt +++ b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/leftmenu/OverlayLeftViewUtils.kt @@ -177,7 +177,7 @@ object OverlayLeftViewUtils { addTarget(context) - LeftMenuOpen.setValue(view, params, windowManager,::close,::open) + LeftMenuOpen.setValue(view, params, windowManager,::close,::open,isMainProcess) try { windowManager!!.addView(overlayView, params) checkProcess() diff --git a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/VideoActivity.kt b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/VideoActivity.kt index d3da306254..f2b1d190ea 100644 --- a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/VideoActivity.kt +++ b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/VideoActivity.kt @@ -11,6 +11,8 @@ import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.AppCompatImageView import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.RecyclerView +import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger +import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant import com.mogo.och.common.module.utils.DateTimeUtil import com.mogo.och.common.module.utils.NumberFormatUtil import com.mogo.och.taxi.passenger.R @@ -52,6 +54,7 @@ class VideoActivity : AppCompatActivity() { private lateinit var acivTitleIcon: AppCompatImageView private lateinit var tvTitle: TextView private var subscribe: Subscription?=null + private val TAG = "mulprocessVideoActivity" private val arrayListOf = ArrayList() @@ -352,7 +355,7 @@ class VideoActivity : AppCompatActivity() { } } - subscribe = Observable.interval(0, 8, TimeUnit.SECONDS) + subscribe = Observable.interval(2, 8, TimeUnit.SECONDS) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object : Observer { @@ -387,15 +390,13 @@ class VideoActivity : AppCompatActivity() { } } } - subscribe?.let { - if(it.isUnsubscribed){ - it.unsubscribe() - } - } + cancleSubscribe() } @Subscribe(threadMode = ThreadMode.MAIN) fun finishActivity(event: FinishActivity){ + CallerLogger.d(SceneConstant.M_TAXI_P + TAG, "finishActivity(event)") + cancleSubscribe() val intent = Intent() val parse = Uri.parse("mogo://launcher/main/switch2?type=launch") intent.data = parse @@ -405,6 +406,7 @@ class VideoActivity : AppCompatActivity() { } override fun onDestroy() { + CallerLogger.d(SceneConstant.M_TAXI_P + TAG, "onDestroy()") super.onDestroy() EventBus.getDefault().unregister(this) LeftMenuOpen.unregisterCallback(callBack) @@ -412,6 +414,15 @@ class VideoActivity : AppCompatActivity() { OverlayLeftViewUtils.dismissOverlayView(false) FloatingDistanceInfoUtils.dismissOverlayView() FixMemoryLeak.fixLeak(this) + cancleSubscribe() + } + + private fun cancleSubscribe(){ + subscribe?.let { + if(!it.isUnsubscribed){ + it.unsubscribe() + } + } } private fun releaseOnNewInstance() { From 109a194701286edb834f33166c19644acc36f835 Mon Sep 17 00:00:00 2001 From: renwj Date: Thu, 4 Aug 2022 10:06:24 +0800 Subject: [PATCH 16/30] =?UTF-8?q?[V2X]=E4=BC=98=E5=8C=96V2X=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/function/hmi/ui/MoGoHmiFragment.kt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) 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 8c0936b3aa..6922a189c9 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 @@ -74,7 +74,6 @@ import com.mogo.eagle.core.utilcode.kotlin.* import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils import com.mogo.eagle.core.utilcode.mogo.logger.* import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI -import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_V2X import com.mogo.eagle.core.utilcode.mogo.toast.TipToast import com.mogo.eagle.core.utilcode.reminder.* import com.mogo.eagle.core.utilcode.reminder.api.* @@ -144,9 +143,9 @@ import java.util.* private var adUpgradeDialog: AdUpgradeDialog?=null - private var speakJob: Job? = null + private var lastSpeakJob: Job? = null - private var showV2XJob: Job? = null + private var lastShowV2XJob: Job? = null private var showingV2XTip: IReminder? = null private var roadVideoDialog: RoadVideoDialog? = null @@ -633,8 +632,6 @@ import java.util.* } }) { override fun show() { - showV2XJob?.safeCancel() - speakJob?.safeCancel() val parent = it.window.decorView parent.doOnAttach { Log.d("$M_HMI$TAG", "--- show v2x dialog 2 ---: info -> v2x-type: $v2xType : expireTime: $expireTime") @@ -644,15 +641,21 @@ import java.util.* override fun isOverride(): Boolean { return true } + + override fun key(): String { + return v2xType + } }, object : IStateChangeListener { override fun onShow(reminder: IReminder) { listener?.onShow() + lastShowV2XJob?.safeCancel() + lastSpeakJob?.safeCancel() showingV2XTip = reminder lifecycleScope.launch { delay(expireTime) }.also { itx -> - showV2XJob = itx + lastShowV2XJob = itx }.invokeOnCompletion { _ -> reminder.hide() } @@ -660,7 +663,7 @@ import java.util.* lifecycleScope.launch { speak(it, ttsContent) }.also { itx -> - speakJob = itx + lastSpeakJob = itx } } } From d16fc6a98a03ceb6d3b320990771010909dadeb0 Mon Sep 17 00:00:00 2001 From: wangmingjun Date: Thu, 4 Aug 2022 10:20:12 +0800 Subject: [PATCH 17/30] =?UTF-8?q?[290=20bus/taxi]bus=E5=8F=B8=E6=9C=BA?= =?UTF-8?q?=E7=AB=AF=E4=BC=98=E5=8C=96=E8=BD=A8=E8=BF=B9=E8=AE=A1=E7=AE=97?= =?UTF-8?q?,=E5=8F=AA=E6=9C=89=E4=B8=A4=E4=B8=AA=E7=AB=99=E7=82=B9?= =?UTF-8?q?=E7=9A=84=E6=97=B6=E5=80=99=E4=BD=BF=E7=94=A8=E5=85=A8=E8=BD=A8?= =?UTF-8?q?=E8=BF=B9=EF=BC=8C=E6=9C=89=E5=A4=9A=E4=B8=AA=E7=AB=99=E7=82=B9?= =?UTF-8?q?=E7=9A=84=E6=97=B6=E5=80=99=E8=BF=9B=E8=A1=8C=E5=88=86=E6=AE=B5?= =?UTF-8?q?=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../passenger/model/BusPassengerModel.java | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java index 4cf55d2582..7ddfb2df9f 100644 --- a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java @@ -385,20 +385,26 @@ public class BusPassengerModel { //找出前往站对应的轨迹点,拿出两站点的集合 CallerLogger.INSTANCE.d(M_BUS_P + TAG, "mRoutePoints.size() = " + mRoutePoints.size()); if (mRoutePoints.size() > 0) { - if (mNextStationIndex <= mStations.size()-1 && mNextStationIndex - 1 >=0){ + if (mStations.size() > 2){ //两个站点以上要计算两个站点间的估计路线 + if (mNextStationIndex <= mStations.size()-1 && mNextStationIndex - 1 >=0){ + mTwoStationsRouts.clear(); + BusPassengerStation stationNext = mStations.get(mNextStationIndex); + BusPassengerStation stationCur = mStations.get(mNextStationIndex - 1); + //当前站在轨迹中对应的点 + int currentRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndex(mRoutePoints + ,stationCur.getGcjLon(),stationCur.getGcjLat()); + //要前往的站在轨迹中对应的点 + int nextRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndex(mRoutePoints + ,stationNext.getGcjLon(),stationNext.getGcjLat()); + mTwoStationsRouts.addAll(mRoutePoints.subList(currentRouteIndex,nextRouteIndex)); + } + }else { //只有两个站点的时候整个路线就是两个站点之间的轨迹 mTwoStationsRouts.clear(); - BusPassengerStation stationNext = mStations.get(mNextStationIndex); - BusPassengerStation stationCur = mStations.get(mNextStationIndex - 1); - //当前站在轨迹中对应的点 - int currentRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndex(mRoutePoints - ,stationCur.getGcjLon(),stationCur.getGcjLat()); - //要前往的站在轨迹中对应的点 - int nextRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndex(mRoutePoints - ,stationNext.getGcjLon(),stationNext.getGcjLat()); - mTwoStationsRouts.addAll(mRoutePoints.subList(currentRouteIndex,nextRouteIndex)); + mTwoStationsRouts.addAll(mRoutePoints); + } + if (mTwoStationsRouts.size() > 0){ float sumLength = CoordinateCalculateRouteUtil.calculateRouteSumLength(mTwoStationsRouts); SharedPrefsMgr.getInstance(mContext).putInt(BusPassengerConst.BUS_SP_KEY_ORDER_SUM_DIS,(int) sumLength); - if (mAutopilotPlanningCallback != null){ mAutopilotPlanningCallback.updateTotalDistance(); } From 1e27c6da97007887bf3deb9896d4e9beae87f3a3 Mon Sep 17 00:00:00 2001 From: renwj Date: Thu, 4 Aug 2022 10:16:26 +0800 Subject: [PATCH 18/30] =?UTF-8?q?[=E7=8A=B6=E6=80=81=E6=A0=8F]=E7=94=B1?= =?UTF-8?q?=E5=8D=95=E6=8E=92=E6=94=B9=E6=88=90=E5=8F=8C=E6=8E=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [状态栏]由单排改成双排 [状态栏]xxxx [状态栏]xxxx --- .../DevaToolsProvider.kt | 12 +-- .../status/StatusManager.kt | 94 ++++++++----------- .../status/entity/Status.kt | 16 ++-- .../status/ui/StatusView.kt | 18 +++- .../src/main/res/layout/layout_status_bar.xml | 9 +- .../core/function/hmi/ui/MoGoHmiFragment.kt | 6 +- .../src/main/res/layout/fragment_hmi.xml | 15 +-- .../api/devatools/IDevaToolsProvider.kt | 6 +- .../call/devatools/CallerDevaToolsManager.kt | 17 +--- .../rv/divider/CommonDividerItemDecoration.kt | 71 +++++++++----- 10 files changed, 141 insertions(+), 123 deletions(-) diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt index f483cb7346..df0a033bb4 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt @@ -3,7 +3,7 @@ package com.zhjt.mogo_core_function_devatools import android.annotation.SuppressLint import android.app.Activity import android.content.Context -import android.view.View +import android.view.* import com.alibaba.android.arouter.facade.annotation.Route import com.mogo.eagle.core.data.constants.MogoServicePaths import com.mogo.eagle.core.data.deva.chain.ChainLogParam @@ -102,12 +102,12 @@ class DevaToolsProvider : IDevaToolsProvider { upgradeManager.downLoadPackage(mContext!!, downloadKey,downloadUrl) } - override fun showStatusBar(ctx: Context, anchor: View) { - StatusManager.init(ctx, anchor) - StatusManager.show() + override fun showStatusBar(ctx: Context, container: ViewGroup) { + StatusManager.init(ctx) + StatusManager.show(container) } - override fun hideStatusBar() { - StatusManager.hide() + override fun hideStatusBar(container: ViewGroup) { + StatusManager.hide(container) } } \ 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/status/StatusManager.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/StatusManager.kt index 177854b555..f9cd867849 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/StatusManager.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/StatusManager.kt @@ -1,10 +1,9 @@ +@file:Suppress("COMPATIBILITY_WARNING") + package com.zhjt.mogo_core_function_devatools.status import android.content.* import android.view.* -import android.view.WindowManager.LayoutParams -import android.widget.* -import androidx.core.view.* import androidx.lifecycle.* import androidx.lifecycle.Lifecycle.Event import androidx.lifecycle.Lifecycle.Event.ON_CREATE @@ -13,7 +12,6 @@ import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener import com.mogo.eagle.core.function.call.autopilot.* import com.mogo.eagle.core.utilcode.kotlin.* import com.mogo.eagle.core.utilcode.util.* -import com.zhjt.mogo_core_function_devatools.ext.* import com.zhjt.mogo_core_function_devatools.status.entity.CanStatus import com.zhjt.mogo_core_function_devatools.status.entity.GpsStatus import com.zhjt.mogo_core_function_devatools.status.entity.IpcStatus @@ -29,11 +27,12 @@ import com.zhjt.mogo_core_function_devatools.status.flow.ipc.IpcImpl import com.zhjt.mogo_core_function_devatools.status.flow.nets.NetsImpl import com.zhjt.mogo_core_function_devatools.status.flow.rtk.RTKImpl import com.zhjt.mogo_core_function_devatools.status.flow.trace.TracingImpl -import com.zhjt.mogo_core_function_devatools.status.ui.* +import com.zhjt.mogo_core_function_devatools.status.ui.StatusView import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import mogo_msg.MogoReportMsg -import java.lang.ref.* +import java.util.concurrent.* + object StatusManager { @@ -41,18 +40,13 @@ object StatusManager { private lateinit var model: StatusModel - private var pop: PopupWindow? = null - private var timer: Job? = null - private var context: WeakReference? = null - - private var anchor: WeakReference? = null private var hasInit = false - private var oldX = 0 - private var oldY = 0 + private val listeners by lazy { CopyOnWriteArrayList() } + private val listener = object : IMoGoAutopilotStatusListener { override fun onAutopilotGuardian(guardianInfo: MogoReportMsg.MogoReportMessage?) { @@ -93,7 +87,7 @@ object StatusManager { } } - fun init(ctx: Context, anchor: View) { + fun init(ctx: Context) { if (hasInit) { return } @@ -110,26 +104,6 @@ object StatusManager { } } }) - context = WeakReference(ctx) - anchor.viewTreeObserver.addOnGlobalLayoutListener { - anchor.getLocationInWindow(IntArray(2).also { - val currentX = it[0] - val currentY = it[1] - var changed = false - if (oldX != currentX) { - oldX = currentX - changed = true - } - if (oldY != currentY) { - changed = true - oldY = currentY - } - if (changed && pop?.isShowing == true) { - pop?.update(getOffsetX(currentX), currentY + 130.PX, -1, -1) - } - }) - } - this.anchor = WeakReference(anchor) } private fun onCreate(ctx: Context) { @@ -153,35 +127,42 @@ object StatusManager { model.update(it) } } + f.onCreate() } - } - fun show() { - val anchor = this.anchor?.get() ?: return - context?.get()?.also { ctx -> - pop?.takeIf { it.isShowing }?.dismiss() - val content = StatusView(model, ctx) - content.doOnAttach { - for (f in flows) { - f.onCreate() - } - } - val out = IntArray(2) - anchor.getLocationInWindow(out) - ctx.normalPop(content, width = LayoutParams.WRAP_CONTENT, height = LayoutParams.WRAP_CONTENT, gravity = Gravity.END or Gravity.TOP, startX = getOffsetX(out[0]), startY = out[1] + 130.PX , isFocusable = false)?.also { - pop = it + model.status.observe(ctx.lifeCycleOwner) { + listeners.forEach { itx -> + itx.onStatusChanged(it.second, it.first != null) } } } - private fun getOffsetX(anchorX: Int): Int { - return ScreenUtils.getScreenWidth() - anchorX + 40.PX + + fun registerListener(listener: IStatusListener) { + listeners.add(listener) } - fun hide() { - pop?.takeIf { it.isShowing }?.dismiss() + + fun unRegisterListener(listener: IStatusListener) { + listeners.remove(listener) } + fun show(container: ViewGroup) { + if (container.childCount > 0) { + if (container.visibility != View.VISIBLE) { + container.visibility = View.VISIBLE + } + return + } + val child = StatusView(model, container.context) + container.addView(child, ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)) + } + + fun hide(container: ViewGroup) { + container.visibility = View.GONE + } + + private fun onDestroy(ctx: Context) { hasInit = false CallerAutoPilotStatusListenerManager.removeListener(TAG) @@ -190,7 +171,12 @@ object StatusManager { flows.forEach { it.onDestroy() } + listeners.clear() flows.clear() - pop?.takeIf { it.isShowing }?.dismiss() + } + + interface IStatusListener { + + fun onStatusChanged(data: List, hasException: Boolean) } } \ 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/status/entity/Status.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/entity/Status.kt index 562722debe..ff949723fb 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/entity/Status.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/entity/Status.kt @@ -3,12 +3,12 @@ package com.zhjt.mogo_core_function_devatools.status.entity import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.* -internal sealed class Status +sealed class Status /** * 工控机 */ -internal class IpcStatus(val enabled: Boolean = false): Status() { +class IpcStatus(val enabled: Boolean = false): Status() { override fun equals(other: Any?): Boolean { if (javaClass != other?.javaClass) return false @@ -26,7 +26,7 @@ internal class IpcStatus(val enabled: Boolean = false): Status() { } } -internal class NetStatus(val enabled: Boolean = false, var name: String? = null, val speed: Speed? = null): Status() { +class NetStatus(val enabled: Boolean = false, var name: String? = null, val speed: Speed? = null): Status() { class Speed(val tx: Int, val rx: Int) { override fun toString(): String { @@ -56,7 +56,7 @@ internal class NetStatus(val enabled: Boolean = false, var name: String? = null, /** * android系统定位状态 */ -internal class GpsStatus(val enabled: Boolean = false, val isGranted: Boolean = false): Status() { +class GpsStatus(val enabled: Boolean = false, val isGranted: Boolean = false): Status() { override fun equals(other: Any?): Boolean { if (javaClass != other?.javaClass) return false @@ -81,7 +81,7 @@ internal class GpsStatus(val enabled: Boolean = false, val isGranted: Boolean = /** * RTK/GNSS定位状态 */ -internal class RTKStatus(var enabled: Boolean = false, var desc: String = "RTK"): Status() { +class RTKStatus(var enabled: Boolean = false, var desc: String = "RTK"): Status() { override fun equals(other: Any?): Boolean { if (javaClass != other?.javaClass) return false @@ -102,7 +102,7 @@ internal class RTKStatus(var enabled: Boolean = false, var desc: String = "RTK") /** * Can总线 */ -internal class CanStatus(var enabled: Boolean = false): Status() { +class CanStatus(var enabled: Boolean = false): Status() { override fun equals(other: Any?): Boolean { if (javaClass != other?.javaClass) return false @@ -125,7 +125,7 @@ internal class CanStatus(var enabled: Boolean = false): Status() { /** * 寻迹/算路/未知 */ -internal class TracingStatus(var state: Tracing = UNKNOWN): Status() { +class TracingStatus(var state: Tracing = UNKNOWN): Status() { enum class Tracing(val code: String? = "") { /** @@ -188,7 +188,7 @@ internal class TracingStatus(var state: Tracing = UNKNOWN): Status() { } } -internal fun String.toState(): Tracing? { +fun String.toState(): Tracing? { return when(this) { "IMAP_TRA_EXIST" -> TRACK_FINDED "IMAP_TRA_LOADED" -> TRACK_LOADED diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/StatusView.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/StatusView.kt index 0adf523bb6..1eebcf28e9 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/StatusView.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/StatusView.kt @@ -5,6 +5,7 @@ import android.content.* import android.graphics.* import android.graphics.drawable.* import android.transition.* +import android.util.* import android.view.* import androidx.appcompat.widget.* import androidx.constraintlayout.widget.* @@ -42,7 +43,6 @@ internal class StatusView(private val model: StatusModel, ctx: Context): Constra } private fun init() { - isClickable = true dot.background = shape(solid = Color.parseColor("#F33F1D"), shape = GradientDrawable.OVAL, width = 30.PX, height = 30.PX) iv.also { it.background = ContextCompat.getDrawable(context, R.drawable.icon_dev_status_un_fold) @@ -59,13 +59,14 @@ internal class StatusView(private val model: StatusModel, ctx: Context): Constra moveDuration = 0 removeDuration = 0 } - itx.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) + itx.layoutManager = GridLayoutManager(context,4, GridLayoutManager.VERTICAL, false) itx.background = shape(solid = Color.parseColor("#80000000"), radius = 40.PX) itx.addItemDecoration( CommonDividerItemDecoration.Builder() .horizontalExternalSpace(38.PX) .verticalExternalSpace(30.PX) - .spanCountLRCare(false) + .verticalInnerSpace(20.PX) + .spanCountTBCare(false) .horizontalInnerSpace(50.PX) .build() ) @@ -90,6 +91,17 @@ internal class StatusView(private val model: StatusModel, ctx: Context): Constra } } + override fun onVisibilityChanged(changedView: View, visibility: Int) { + super.onVisibilityChanged(changedView, visibility) + if (changedView != this) { + if (visibility == View.VISIBLE) { + observer?.also { model.status.observeForever(it) } + } else { + observer?.also { model.status.removeObserver(it) } + } + } + } + private fun animate(expand: Boolean) { TransitionManager.beginDelayedTransition(this, AutoTransition().setDuration(200)) rv.visibility = if (expand) View.VISIBLE else View.INVISIBLE diff --git a/core/function-impl/mogo-core-function-devatools/src/main/res/layout/layout_status_bar.xml b/core/function-impl/mogo-core-function-devatools/src/main/res/layout/layout_status_bar.xml index baecaea7f1..ac03487212 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/res/layout/layout_status_bar.xml +++ b/core/function-impl/mogo-core-function-devatools/src/main/res/layout/layout_status_bar.xml @@ -8,13 +8,12 @@ @@ -24,7 +23,7 @@ android:layout_height="107px" android:layout_marginBottom="20px" app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent" + android:layout_marginTop="12px" app:layout_constraintStart_toEndOf="@+id/rv" app:layout_constraintEnd_toEndOf="parent" android:background="@drawable/icon_dev_status_un_fold"/> 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 6922a189c9..901e32a7bb 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 @@ -207,7 +207,7 @@ import java.util.* setProxyLimitingSpeedView(viewLimitingVelocity) setViewNotificationProvider(this) context?.also { - CallerDevaToolsManager.showStatusBar(it, vs_status_bar) + CallerDevaToolsManager.showStatusBar(it, statusBarContainer) } } @@ -1214,7 +1214,7 @@ import java.util.* } override fun showSmallFragment() { - CallerDevaToolsManager.hideStatusBar() + CallerDevaToolsManager.hideStatusBar(statusBarContainer) // 加载全览模式图层 val fragmentOverview = ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW) .navigation() as BaseFragment @@ -1229,7 +1229,7 @@ import java.util.* } override fun hideSmallFragment() { - context?.let { CallerDevaToolsManager.showStatusBar(it, vs_status_bar) } + context?.let { CallerDevaToolsManager.showStatusBar(it, statusBarContainer) } val fragmentOverview = ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW) .navigation() as BaseFragment activity?.supportFragmentManager?.beginTransaction() 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 ed3b74663e..64c1661753 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 @@ -147,6 +147,7 @@ android:layout_height="120px" android:layout_marginTop="30px" android:layout_marginEnd="40px" + android:background="@drawable/bg_waring_limiting_velocity" android:elevation="@dimen/dp_10" android:gravity="center" @@ -158,7 +159,7 @@ app:layout_constraintTop_toBottomOf="@+id/ivCameraIcon" app:layout_goneMarginEnd="40px" app:layout_goneMarginTop="40px" - tools:visibility="visible" /> + tools:visibility="gone" /> - + app:layout_goneMarginTop="30px" + app:layout_goneMarginEnd="40px"/> diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt index fcbafafc21..e5328f0dec 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt @@ -2,7 +2,7 @@ package com.mogo.eagle.core.function.api.devatools import android.app.Activity import android.content.Context -import android.view.View +import android.view.* import com.alibaba.android.arouter.facade.template.IProvider import com.mogo.eagle.core.data.deva.chain.ChainLogParam import com.mogo.eagle.core.data.deva.scene.SceneModule @@ -107,10 +107,10 @@ interface IDevaToolsProvider : IProvider { /** * 展示状态栏 */ - fun showStatusBar(ctx: Context, anchor: View) + fun showStatusBar(ctx: Context, container: ViewGroup) /** * 隐藏状态栏 */ - fun hideStatusBar() + fun hideStatusBar(container: ViewGroup) } \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt index 509a611781..71cc263d5c 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt @@ -150,27 +150,18 @@ object CallerDevaToolsManager { /** * 展示状态栏 */ - fun showStatusBar(ctx: Context, anchor: View) { + fun showStatusBar(ctx: Context, container: ViewGroup) { if (!AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) { - if (anchor.isLaidOut) { - devaToolsProviderApi?.showStatusBar(ctx, anchor) - } else { - anchor.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { - override fun onGlobalLayout() { - devaToolsProviderApi?.showStatusBar(ctx, anchor) - anchor.viewTreeObserver.removeOnGlobalLayoutListener(this) - } - }) - } + devaToolsProviderApi?.showStatusBar(ctx, container) } } /** * 隐藏状态栏 */ - fun hideStatusBar() { + fun hideStatusBar(container: ViewGroup) { if (!AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) { - devaToolsProviderApi?.hideStatusBar() + devaToolsProviderApi?.hideStatusBar(container) } } } \ No newline at end of file diff --git a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/rv/divider/CommonDividerItemDecoration.kt b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/rv/divider/CommonDividerItemDecoration.kt index 62a5dfd1d2..f1234c0b90 100644 --- a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/rv/divider/CommonDividerItemDecoration.kt +++ b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/rv/divider/CommonDividerItemDecoration.kt @@ -31,12 +31,15 @@ class CommonDividerItemDecoration internal constructor(builder: Builder) : ItemD private var mSpanCountTBCare = false private val mHorizontalExternalSpace: Int private val mVerticalExternalSpace: Int - private var mLastRight = 0 - private var mLastBottom = 0 private var mFromPosition = 0 private var mHorizontalDelta: Pair? = null private var mVerticalDelta: Pair? = null + private var mRightCache: HashMap = HashMap() + private var mLeftCache: HashMap = HashMap() + private var mBottomCache: HashMap = HashMap() + private var mTopCache: HashMap = HashMap() + /** * 外部间隔结束位置是否需要 */ @@ -84,23 +87,28 @@ class CommonDividerItemDecoration internal constructor(builder: Builder) : ItemD } } else { val averageDistance = (((spanCount - 1) * mHorizontalInnerSpace + 2 * mHorizontalExternalSpace + deltaHL + deltaHR) * 1.0f / spanCount).toInt() - Log.d("UUUU", "step::0::$averageDistance: lastRight: $mLastRight : state: $state " ) if (spanIndex == 0) { outRect.left = mHorizontalExternalSpace + deltaHL outRect.right = averageDistance - outRect.left - mLastRight = outRect.right - Log.d("UUUU", "step::1::$averageDistance: lastRight: $mLastRight" ) + if (state.didStructureChange()) { + mRightCache[position] = outRect.right + } + Log.d("UUUU", "step::1::$averageDistance: outRect.right: ${outRect.right} ::outRect.left: ${outRect.left}:: position: $position :: state: $state" ) } else if (spanIndex == spanCount - 1) { outRect.right = mHorizontalExternalSpace + deltaHR outRect.left = averageDistance - outRect.right - Log.d("UUUU", "step::2::$averageDistance: lastRight: $mLastRight ::outRect.left: ${outRect.left}" ) + Log.d("UUUU", "step::2::$averageDistance: outRect.right: ${outRect.right} ::outRect.left: ${outRect.left} :: position: $position :: state: $state" ) } else { - outRect.left = mHorizontalInnerSpace - mLastRight - outRect.right = averageDistance - outRect.left if (state.didStructureChange()) { - mLastRight = outRect.right + outRect.left = mHorizontalInnerSpace - (mRightCache[position - 1] ?: 0) + outRect.right = averageDistance - outRect.left + mLeftCache[position] = outRect.left + mRightCache[position] = outRect.right + } else { + outRect.left = mLeftCache[position]!! + outRect.right = mRightCache[position]!! } - Log.d("UUUU", "step::2::$averageDistance: lastRight: $mLastRight ::outRect.left: ${outRect.left}" ) + Log.d("UUUU", "step::2::$averageDistance: outRect.right: ${outRect.right} ::outRect.left: ${outRect.left} :: position: $position :: state: $state" ) } } //所在的行数 if (lookUp.getSpanGroupIndex(childPosition, spanCount) == lookUp.getSpanGroupIndex(mFromPosition, spanCount)) { @@ -130,15 +138,21 @@ class CommonDividerItemDecoration internal constructor(builder: Builder) : ItemD if (spanIndex == 0) { outRect.top = mVerticalExternalSpace + deltaVT outRect.bottom = averageDistance - outRect.top - mLastBottom = outRect.bottom + if (state.didStructureChange()) { + mBottomCache[position] = outRect.bottom + } } else if (spanIndex == spanCount - 1) { outRect.top = mVerticalExternalSpace + deltaVB outRect.bottom = averageDistance - outRect.top } else { - outRect.top = mVerticalInnerSpace - mLastBottom - outRect.bottom = averageDistance - outRect.top if (state.didStructureChange()) { - mLastBottom = outRect.bottom + outRect.top = mVerticalInnerSpace - (mBottomCache[position - 1] ?: 0 ) + outRect.bottom = averageDistance - outRect.top + mBottomCache[position] = outRect.bottom + mTopCache[position] = outRect.top + } else { + outRect.top = mTopCache[position]!! + outRect.bottom = mBottomCache[position]!! } } } @@ -223,15 +237,21 @@ class CommonDividerItemDecoration internal constructor(builder: Builder) : ItemD if (spanIndex == 0) { outRect.left = mHorizontalExternalSpace + deltaHL outRect.right = averageDistance - outRect.left - mLastRight = outRect.right + if (state.didStructureChange()) { + mRightCache[position] = outRect.right + } } else if (spanIndex == spanCount - 1) { outRect.right = mHorizontalExternalSpace + deltaHR outRect.left = averageDistance - outRect.right } else { - outRect.left = mHorizontalInnerSpace - mLastRight - outRect.right = averageDistance - outRect.left if (state.didStructureChange()) { - mLastRight = outRect.right + outRect.left = mHorizontalInnerSpace - (mRightCache[position - 1] ?: 0) + outRect.right = averageDistance - outRect.left + mLeftCache[position] = outRect.left + mRightCache[position] = outRect.right + } else { + outRect.left = mLeftCache[position]!! + outRect.right = mRightCache[position]!! } } } @@ -282,15 +302,22 @@ class CommonDividerItemDecoration internal constructor(builder: Builder) : ItemD if (spanIndex == 0) { outRect.top = mVerticalExternalSpace + deltaVT outRect.bottom = averageDistance - outRect.top - mLastBottom = outRect.bottom + if (state.didStructureChange()) { + mBottomCache[position] = outRect.bottom + } } else if (spanIndex == spanCount - 1) { outRect.top = mVerticalExternalSpace + deltaVB outRect.bottom = averageDistance - outRect.top } else { - outRect.top = mVerticalInnerSpace - mLastBottom - outRect.bottom = averageDistance - outRect.top + if (state.didStructureChange()) { - mLastBottom = outRect.bottom + outRect.top = mVerticalInnerSpace - (mBottomCache[position - 1] ?: 0) + outRect.bottom = averageDistance - outRect.top + mBottomCache[position] = outRect.bottom + mTopCache[position] = outRect.top + } else { + outRect.top = mTopCache[position]!! + outRect.bottom = mBottomCache[position]!! } } } From b4328d1c6d5ad5480395719deae807f97ac13182 Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Wed, 3 Aug 2022 18:56:00 +0800 Subject: [PATCH 19/30] =?UTF-8?q?[Update]=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E7=BB=98=E5=88=B6=E8=BD=A8=E8=BF=B9=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../taxi/model/NaviToDestinationModel.java | 17 +- config.gradle | 2 +- .../core/function/hmi/ui/MoGoHmiFragment.kt | 7 +- .../hmi/ui/widget/SteeringWheelView.java | 20 +- .../function/overview/vm/OverViewModel.kt | 4 +- .../core/function/smp/AMapCustomView.java | 522 ++++++++++++------ .../core/function/smp/MarkerDrawerManager.kt | 169 ++++++ .../function/smp/OverviewMapFragment.java | 6 + .../amap_bus_corner.png | Bin 0 -> 42264 bytes .../amap_bus_smooth_route.png | Bin 0 -> 879 bytes .../arrow_arrived_img.png | Bin 0 -> 443 bytes .../drawable-xhdpi-2560x1440/map_bus_icon.png | Bin 0 -> 7059 bytes .../res/drawable-xhdpi/amap_bus_corner.png | Bin 0 -> 42264 bytes .../drawable-xhdpi/amap_bus_smooth_route.png | Bin 0 -> 879 bytes .../res/drawable-xhdpi/arrow_arrived_img.png | Bin 0 -> 443 bytes .../main/res/drawable-xhdpi/map_bus_icon.png | Bin 0 -> 7059 bytes .../res/layout/module_overview_map_view.xml | 4 +- 17 files changed, 544 insertions(+), 207 deletions(-) create mode 100644 core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/MarkerDrawerManager.kt create mode 100644 core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi-2560x1440/amap_bus_corner.png create mode 100644 core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi-2560x1440/amap_bus_smooth_route.png create mode 100644 core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi-2560x1440/arrow_arrived_img.png create mode 100644 core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi-2560x1440/map_bus_icon.png create mode 100644 core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/amap_bus_corner.png create mode 100644 core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/amap_bus_smooth_route.png create mode 100644 core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/arrow_arrived_img.png create mode 100644 core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/map_bus_icon.png diff --git a/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/NaviToDestinationModel.java b/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/NaviToDestinationModel.java index e4e3a0f113..84a387ead4 100644 --- a/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/NaviToDestinationModel.java +++ b/OCH/mogo-och-taxi/src/main/java/com/mogo/och/taxi/model/NaviToDestinationModel.java @@ -14,7 +14,6 @@ import com.amap.api.navi.model.AMapLaneInfo; import com.amap.api.navi.model.AMapModelCross; import com.amap.api.navi.model.AMapNaviCameraInfo; import com.amap.api.navi.model.AMapNaviCross; -import com.amap.api.navi.model.AMapNaviInfo; import com.amap.api.navi.model.AMapNaviLocation; import com.amap.api.navi.model.AMapNaviRouteNotifyData; import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo; @@ -23,7 +22,6 @@ import com.amap.api.navi.model.AimLessModeCongestionInfo; import com.amap.api.navi.model.AimLessModeStat; import com.amap.api.navi.model.NaviInfo; import com.amap.api.navi.model.NaviLatLng; -import com.autonavi.tbt.TrafficFacilityInfo; import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; import com.mogo.eagle.core.utilcode.util.NetworkUtils; import com.mogo.eagle.core.utilcode.util.ToastUtils; @@ -279,6 +277,11 @@ public class NaviToDestinationModel implements AMapNaviListener { } + @Override + public void onGpsSignalWeak(boolean b) { + + } + @Override public void updateCameraInfo(AMapNaviCameraInfo[] aMapCameraInfos) { @@ -289,21 +292,11 @@ public class NaviToDestinationModel implements AMapNaviListener { } - @Override - public void onNaviInfoUpdated(AMapNaviInfo aMapNaviInfo) { - - } - @Override public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) { //已过时 } - @Override - public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) { - - } - @Override public void showCross(AMapNaviCross aMapNaviCross) { //显示放大图回调 diff --git a/config.gradle b/config.gradle index 183c9f761d..7a7963b54e 100644 --- a/config.gradle +++ b/config.gradle @@ -38,7 +38,7 @@ ext { // amapnavi3dmap : "com.amap.api:navi-3dmap:8.0.1_3dmap8.0.1", // amapsearch : "com.amap.api:search:7.9.0", // amaplocation : "com.amap.api:location:5.5.0", - amapnavi3dmap : "com.amap.api:navi-3dmap:7.2.0_3dmap7.2.0", + amapnavi3dmap : "com.amap.api:navi-3dmap:7.7.0_3dmap7.7.0", amapsearch : "com.amap.api:search:7.1.0", amaplocation : "com.amap.api:location:5.3.1", // json 转换 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 901e32a7bb..e4e5faa093 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 @@ -172,10 +172,11 @@ import java.util.* } } - /*ivCameraIcon?.setOnLongClickListener { - activity?.let { it1 -> CarcorderPreviewView.show(it1) } + ivCameraIcon?.setOnLongClickListener { + showSmallFragment() +// activity?.let { it1 -> CarcorderPreviewView.show(it1) } true - }*/ + } ivToolsIcon?.setOnClickListener { if (toolsViewFloat == null) { diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SteeringWheelView.java b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SteeringWheelView.java index 7fb56ed8d9..67594f090e 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SteeringWheelView.java +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SteeringWheelView.java @@ -129,14 +129,26 @@ public class SteeringWheelView extends ConstraintLayout { if (autopilotIV != null) { Log.d(TAG, "autopilotIV != null"); if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) { + if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) { + // TODO - autopilotIV.setImageResource(R.drawable.bg_auto); - + } else { + autopilotIV.setImageResource(R.drawable.bg_auto); + } } else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE) { - autopilotIV.setImageResource(R.drawable.bg_auto_nor); + if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) { + // TODO + } else { + autopilotIV.setImageResource(R.drawable.bg_auto_nor); + } } else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE) { - autopilotIV.setImageResource(R.drawable.bg_auto_nor); + if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) { + // TODO + + } else { + autopilotIV.setImageResource(R.drawable.bg_auto_nor); + } } } else { Log.d(TAG, "autopilotIV=null"); 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 6b5fb5c6fd..59440482c8 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 @@ -1,15 +1,17 @@ package com.mogo.eagle.core.function.overview.vm import androidx.lifecycle.* +import com.amap.api.maps.model.LatLng import com.mogo.eagle.core.data.map.Infrastructure import com.mogo.eagle.core.function.overview.OverviewDao +import io.reactivex.disposables.CompositeDisposable import kotlinx.coroutines.launch -import java.lang.Exception class OverViewModel( private val overviewDao: OverviewDao ) : ViewModel() { private val _infStructures = MutableLiveData>() + val infStructures get() = _infStructures 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 bc506d5711..41b6c130dc 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 @@ -2,9 +2,7 @@ package com.mogo.eagle.core.function.smp; import android.content.Context; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.Canvas; -import android.location.Location; import android.os.Bundle; import android.util.AttributeSet; import android.util.Log; @@ -20,26 +18,27 @@ import androidx.annotation.Nullable; import com.amap.api.maps.AMap; import com.amap.api.maps.CameraUpdate; import com.amap.api.maps.CameraUpdateFactory; -import com.amap.api.maps.CoordinateConverter; +import com.amap.api.maps.TextureMapView; import com.amap.api.maps.UiSettings; +import com.amap.api.maps.model.BitmapDescriptor; import com.amap.api.maps.model.BitmapDescriptorFactory; +import com.amap.api.maps.model.CameraPosition; import com.amap.api.maps.model.CustomMapStyleOptions; import com.amap.api.maps.model.LatLng; +import com.amap.api.maps.model.LatLngBounds; +import com.amap.api.maps.model.Marker; import com.amap.api.maps.model.MarkerOptions; import com.amap.api.maps.model.Polyline; -import com.amap.api.navi.AMapNavi; +import com.amap.api.maps.model.PolylineOptions; import com.amap.api.navi.AMapNaviListener; -import com.amap.api.navi.AMapNaviView; import com.amap.api.navi.AMapNaviViewListener; -import com.amap.api.navi.AMapNaviViewOptions; -import com.amap.api.navi.enums.NaviType; import com.amap.api.navi.model.AMapCalcRouteResult; import com.amap.api.navi.model.AMapLaneInfo; import com.amap.api.navi.model.AMapModelCross; import com.amap.api.navi.model.AMapNaviCameraInfo; import com.amap.api.navi.model.AMapNaviCross; -import com.amap.api.navi.model.AMapNaviInfo; import com.amap.api.navi.model.AMapNaviLocation; +import com.amap.api.navi.model.AMapNaviPathGroup; import com.amap.api.navi.model.AMapNaviRouteNotifyData; import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo; import com.amap.api.navi.model.AMapServiceAreaInfo; @@ -47,9 +46,7 @@ import com.amap.api.navi.model.AimLessModeCongestionInfo; import com.amap.api.navi.model.AimLessModeStat; import com.amap.api.navi.model.NaviInfo; import com.amap.api.navi.model.NaviLatLng; -import com.amap.api.navi.model.RouteOverlayOptions; -import com.autonavi.tbt.TrafficFacilityInfo; -import com.elegant.utils.UiThreadHandler; +import com.amap.api.navi.model.NaviPoi; import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo; import com.mogo.eagle.core.data.config.FunctionBuildConfig; import com.mogo.eagle.core.data.map.Infrastructure; @@ -67,9 +64,9 @@ import com.mogo.eagle.core.function.overview.InfStructureManager; import com.mogo.eagle.core.function.smp.view.ISmallMapDirectionView; import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils; import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils; -import com.mogo.eagle.core.utilcode.util.ThreadUtils; -import com.mogo.module.common.utils.DrivingDirectionUtils; -import com.zhidao.support.adas.high.AdasManager; +import com.mogo.eagle.core.utilcode.util.UiThreadHandler; +import com.zhidaoauto.map.sdk.open.query.LonLatPoint; +import com.zhidaoauto.map.sdk.open.tools.MapTools; import org.jetbrains.annotations.NotNull; @@ -79,6 +76,7 @@ import java.util.List; import java.util.Map; import ch.hsr.geohash.GeoHash; +import kotlin.Pair; import mogo.telematics.pad.MessagePad; import mogo_msg.MogoReportMsg; import system_master.SystemStatusInfo; @@ -94,8 +92,7 @@ public class AMapCustomView extends RelativeLayout implements IMoGoMapLocationListener, ISmallMapDirectionView, AMapNaviListener, AMapNaviViewListener { public static final String TAG = "AMapCustomView"; - private AMapNaviView mAMapNaviView; - protected AMapNavi mAMapNavi; + private TextureMapView mAMapView; private AMap mAMap; protected NaviLatLng mStartLatlng = new NaviLatLng(); protected NaviLatLng mEndLatlng = new NaviLatLng(); @@ -116,6 +113,27 @@ public class AMapCustomView private Map> pathMap = new HashMap(); private Map> posInfMap = new HashMap(); + // 独立路径导航 + private NaviPoi mStartPoi = null; + private NaviPoi mEndPoi = null; + private AMapNaviPathGroup mIndependentPathGroup = null; + private List mIndependentPointList = new ArrayList<>(); + + // =============绘制轨迹线相关============= + private Marker mCarMarker; + private Marker mStartMarker; + private Marker mEndMarker; + private Polyline mCustomPolyline; + // 计算索引并设置对应的Bitmap + BitmapDescriptor arrivedBitmap; + BitmapDescriptor unArrivedBitmap; + // 绘制轨迹线的集合 + private List textureList = new ArrayList<>(); + private List texIndexList = new ArrayList<>(); + + private MogoLocation mLocation; + private boolean isFirstLocation = true; + public AMapCustomView(Context context) { this(context, null); } @@ -136,16 +154,18 @@ public class AMapCustomView private void initView(Context context) { mContext = context; View smpView = LayoutInflater.from(context).inflate(R.layout.module_overview_map_view, this); - mAMapNaviView = smpView.findViewById(R.id.aMapNaviView); + mAMapView = smpView.findViewById(R.id.aMapView); overLayerView = findViewById(R.id.overLayer); - if(AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) { + if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) { overLayerView.setBackground(getResources().getDrawable(R.drawable.amap_reset)); - }else { + arrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.arrow_arrived_img); + unArrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.amap_bus_smooth_route); +// unArrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.amap_custom_smooth_route); + } else { overLayerView.setBackground(getResources().getDrawable(R.drawable.amap_reset_bus)); + arrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.arrow_arrived_img); + unArrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.amap_bus_smooth_route); } - mAMapNavi = AMapNavi.getInstance(context); - mAMapNavi.addAMapNaviListener(this); - mAMapNaviView.setAMapNaviViewListener(this); CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, mGoAutopilotStatusListener); CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, moGoAutopilotPlanningListener); initAMapView(context); @@ -153,18 +173,32 @@ public class AMapCustomView CallerMapLocationListenerManager.INSTANCE.addListener(TAG, this); //设置全览模式 overLayerView.setOnClickListener(v -> { - mAMapNaviView.displayOverview(); +// mAMapView.displayOverview(); + CallerHmiManager.INSTANCE.hideSmallFragment(); }); - // 注册定位监听 - CallerMapLocationListenerManager.INSTANCE.addListener(TAG, this); - CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, mGoAutopilotStatusListener); - CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, moGoAutopilotPlanningListener); } private void initAMapView(Context context) { Log.d(TAG, "initAMapView"); mCameraUpdate = CameraUpdateFactory.zoomTo(zoomLevel); - mAMap = mAMapNaviView.getMap(); + mAMap = mAMapView.getMap(); + mAMap.setOnMapLoadedListener(() -> { + Log.d(TAG, "---onMapLoaded---"); + CustomMapStyleOptions customMapStyleOptions = new CustomMapStyleOptions(); + // 加载自定义样式 + customMapStyleOptions.setEnable(true); + if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) { + customMapStyleOptions.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "over_view_style.data")); + customMapStyleOptions.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "over_view_style_extra.data")); + } else { + customMapStyleOptions.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "over_view_style_bus.data")); + customMapStyleOptions.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "over_view_style_extra_bus.data")); + } + // 设置自定义样式 + mAMap.setCustomMapStyle(customMapStyleOptions); + // 实时路况图层关闭,必须添加在loaded结束之后,其他位置不生效 + mAMap.setTrafficEnabled(false); + }); setUpMap(); customOptions(); } @@ -195,43 +229,68 @@ public class AMapCustomView * 自定义导航View和路况状态 */ private void customOptions() { - AMapNaviViewOptions options = mAMapNaviView.getViewOptions(); +// AMapNaviViewOptions options = mAMapView.getViewOptions(); //关闭自动绘制路线,自行绘制路线 // options.setAutoDrawRoute(false); //不显示导航界面 - options.setLayoutVisible(false); - options.setTilt(60); - //黑夜模式 - options.setNaviNight(true); - //导航全程光柱 - options.setTrafficBarEnabled(false); - //隐藏摄像头 - options.setCameraBubbleShow(false); - //转向箭头 - options.setNaviArrowVisible(false); +// options.setLayoutVisible(false); +// options.setTilt(60); +// //黑夜模式 +// options.setNaviNight(true); +// //导航全程光柱 +// options.setTrafficBarEnabled(false); +// //隐藏摄像头 +// options.setCameraBubbleShow(false); +// //转向箭头 +// options.setNaviArrowVisible(false); +// // 算路成功后自动进入全览模式 +// options.setAutoDisplayOverview(true); //指南针 // options.setCompassEnabled(false); // options.setTilt((int) tilt); - //自车车标 - options.setCarBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.map_car_icon)); - options.setFourCornersBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.amap_custom_corner)); - options.setStartPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.module_small_map_view_dir_start)); - options.setWayPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.icon_module_small_map_four_corners)); - options.setEndPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.module_small_map_view_dir_end)); - //与走过的路线 - options.setAfterRouteAutoGray(true); //路线纹理自定义 - RouteOverlayOptions routeOverlayOptions = new RouteOverlayOptions(); - routeOverlayOptions.setTurnArrowIs3D(false); - // 未知路段和导航路段颜色一样 - routeOverlayOptions.setUnknownTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.amap_custom_smooth_route));//未知路段 - routeOverlayOptions.setSmoothTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.amap_custom_smooth_route)); - routeOverlayOptions.setJamTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.custtexture_bad));//拥堵路段 - routeOverlayOptions.setVeryJamTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.custtexture_grayred));//超级拥堵路段 - routeOverlayOptions.setPassRoute(BitmapFactory.decodeResource(getResources(), R.drawable.amap_custom_pass_route));//走过的路段 - options.setRouteOverlayOptions(routeOverlayOptions); - mAMapNaviView.setTrafficLightsVisible(true); - mAMapNaviView.setViewOptions(options); +// RouteOverlayOptions routeOverlayOptions = new RouteOverlayOptions(); + if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) { + // TODO:("导航的配置需要删除") + mCarMarker = mAMap.addMarker(new MarkerOptions() + .icon(BitmapDescriptorFactory.fromResource(R.drawable.map_car_icon)) + .anchor(0.5f, 0.5f)); + +// //自车车标 +// options.setCarBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.map_car_icon)); +// options.setFourCornersBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.amap_custom_corner)); + // 未知路段和导航路段颜色一样 +// routeOverlayOptions.setUnknownTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.amap_custom_smooth_route));//未知路段 +// routeOverlayOptions.setSmoothTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.amap_custom_smooth_route)); + } else { + // TODO:("导航的配置需要删除") + mCarMarker = mAMap.addMarker(new MarkerOptions() + .icon(BitmapDescriptorFactory.fromResource(R.drawable.map_bus_icon)) + .anchor(0.5f, 0.5f)); + +// options.setCarBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.map_bus_icon)); +// options.setFourCornersBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.amap_bus_corner)); +// routeOverlayOptions.setUnknownTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.amap_bus_smooth_route));//未知路段 +// routeOverlayOptions.setSmoothTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.amap_bus_smooth_route)); + } + + mStartMarker = mAMap.addMarker(new MarkerOptions() + .icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_start))); + mEndMarker = mAMap.addMarker(new MarkerOptions() + .icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_end))); + +// options.setStartPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.module_small_map_view_dir_start)); +// options.setWayPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.icon_module_small_map_four_corners)); +// options.setEndPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.module_small_map_view_dir_end)); +// //与走过的路线 +// options.setAfterRouteAutoGray(true); +// routeOverlayOptions.setTurnArrowIs3D(false); +// routeOverlayOptions.setJamTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.custtexture_bad));//拥堵路段 +// routeOverlayOptions.setVeryJamTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.custtexture_grayred));//超级拥堵路段 +// routeOverlayOptions.setPassRoute(BitmapFactory.decodeResource(getResources(), R.drawable.amap_custom_pass_route));//走过的路段 +// options.setRouteOverlayOptions(routeOverlayOptions); +// mAMapView.setTrafficLightsVisible(true); +// mAMapView.setViewOptions(options); } private final IMoGoAutopilotStatusListener mGoAutopilotStatusListener = new IMoGoAutopilotStatusListener() { @@ -263,27 +322,24 @@ public class AMapCustomView @Override public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autoPilotStatusInfo) { - ThreadUtils.runOnUiThread(new Runnable() { - @Override - public void run() { - if (autoPilotStatusInfo == null) return; - int state = autoPilotStatusInfo.getState(); - //0 不能自动驾驶 1 可以自动驾驶,但是在人工干预 2 自动驾驶中 - if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) { - Log.d(TAG, "自动驾驶中 state=" + String.valueOf(state)); - if (sList.size() == 0 && eList.size() == 0 && mWayPointList.size() == 0) { - Log.d(TAG, "sendGlobalPathReq"); - AdasManager.getInstance().sendGlobalPathReq(); - } - } else { - int type = mAMapNavi.getNaviType(); - Log.d(TAG, "非自动驾驶状态,导航类型==" + String.valueOf(type)); - if (type == NaviType.GPS || type == NaviType.EMULATOR) { - mAMapNavi.stopNavi(); - } - } - } - }); +// ThreadUtils.runOnUiThread(() -> { +// if (autoPilotStatusInfo == null) return; +// int state = autoPilotStatusInfo.getState(); +// //0 不能自动驾驶 1 可以自动驾驶,但是在人工干预 2 自动驾驶中 +// if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) { +//// Log.d(TAG, "自动驾驶中 state=" + String.valueOf(state)); +// if (sList.size() == 0 && eList.size() == 0 && mWayPointList.size() == 0) { +// Log.d(TAG, "sendGlobalPathReq"); +// AdasManager.getInstance().sendGlobalPathReq(); +// } +// } else { +// int type = mAMapNavi.getNaviType(); +// Log.d(TAG, "非自动驾驶状态,导航类型==" + String.valueOf(type)); +// if (type == NaviType.GPS || type == NaviType.EMULATOR) { +// mAMapNavi.stopNavi(); +// } +// } +// }); } }; @@ -307,37 +363,62 @@ public class AMapCustomView calculate = true; Log.d(TAG, "onAutopilotRotting"); List list = globalPathResp.getWayPointsList(); - int minCount = 2; - if (list.size() >= minCount) { - calculate = true; - MessagePad.Location sLocation = (MessagePad.Location) list.get(0); - MessagePad.Location eLocation = (MessagePad.Location) list.get(list.size() - 1); - mStartLatlng = new NaviLatLng(sLocation.getLatitude(), sLocation.getLongitude()); - mEndLatlng = new NaviLatLng(eLocation.getLatitude(), eLocation.getLongitude()); - sList.clear(); - eList.clear(); - sList.add(mStartLatlng); - eList.add(mEndLatlng); +// int minCount = 2; +// if (list.size() >= minCount && sList.size() == 0 && eList.size() == 0 && mWayPointList.size() == 0) { +// calculate = true; +// MessagePad.Location sLocation = (MessagePad.Location) list.get(0); +// MessagePad.Location eLocation = (MessagePad.Location) list.get(list.size() - 1); +// mStartLatlng = new NaviLatLng(sLocation.getLatitude(), sLocation.getLongitude()); +// mEndLatlng = new NaviLatLng(eLocation.getLatitude(), eLocation.getLongitude()); +// mStartPoi = new NaviPoi("", new LatLng(sLocation.getLatitude(), sLocation.getLongitude()), ""); +// mEndPoi = new NaviPoi("", new LatLng(eLocation.getLatitude(), eLocation.getLongitude()), ""); +// sList.clear(); +// eList.clear(); +// sList.add(mStartLatlng); +// eList.add(mEndLatlng); +// +// mWayPointList.clear(); +// mIndependentPointList.clear(); +// for (int i = 1; i < list.size() - minCount; i++) { +// MessagePad.Location wayLoc = (MessagePad.Location) list.get(i); +// NaviLatLng way = new NaviLatLng(wayLoc.getLatitude(), wayLoc.getLongitude()); +// NaviPoi naviPoi = new NaviPoi("", new LatLng(wayLoc.getLatitude(), wayLoc.getLongitude()), ""); +// mWayPointList.add(way); +// mIndependentPointList.add(naviPoi); +// } +// } +// int strategy = 0; +// try { +// //再次强调,最后一个参数为true时代表多路径,否则代表单路径 +// strategy = mAMapNavi.strategyConvert(true, false, false, false, false); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// Log.d(TAG, "全局路径" + list.size() + ",起点:" + sList.toString() + ",终点:" + eList.toString() + ",经点:" + mWayPointList.toString()); +// //指定路径绘制导航路线 +// mAMapNavi.calculateDriveRoute(sList, eList, mWayPointList, strategy); - mWayPointList.clear(); - for (int i = 1; i < list.size() - minCount; i++) { - MessagePad.Location wayLoc = (MessagePad.Location) list.get(i); - NaviLatLng way = new NaviLatLng(wayLoc.getLatitude(), wayLoc.getLongitude()); - mWayPointList.add(way); - } - } - int strategy = 0; - try { - //再次强调,最后一个参数为true时代表多路径,否则代表单路径 - strategy = mAMapNavi.strategyConvert(true, false, false, false, false); - } catch (Exception e) { - e.printStackTrace(); - } - Log.d(TAG, "全局路径" + list.size() + ",起点:" + sList.toString() + ",终点:" + eList.toString() + ",经点:" + mWayPointList.toString()); - //指定路径绘制导航路线 - mAMapNavi.calculateDriveRoute(sList, eList, mWayPointList, strategy); - - drawInfrastructureMarkers(globalPathResp); + // 转成高德坐标系并存储 + MarkerDrawerManager.INSTANCE.updateRoutePoints(list, mContext); + List planningPointList = MarkerDrawerManager.INSTANCE.getPlanningPoints(); + UiThreadHandler.post(() -> { + displayCustomOverView(); + drawStartAndEndMarker(planningPointList); + }); + MarkerDrawerManager.INSTANCE.setCallback((points, locIndex) -> { + UiThreadHandler.post(() -> { + // 每1s刷新一下轨迹线 + if (points.size() > 0) { + drawPolyline(points , locIndex); + } else { + clearCustomPolyline(); + } + }); + }); + MarkerDrawerManager.INSTANCE.startLoopCalCarLocation(); + UiThreadHandler.post(() -> { + drawInfrastructureMarkers(globalPathResp); + }); } }; @@ -358,53 +439,19 @@ public class AMapCustomView @Override public void onLocationChanged(@org.jetbrains.annotations.Nullable MogoLocation location, int from) { - - } - - private void removeLocation(Location latLng) { - for (LatLng l : mCoordinatesLatLng) { - if (!isPointOnCarFront(latLng, l)) { - mCoordinatesLatLng.remove(l); - } + mLocation = location; + MarkerDrawerManager.INSTANCE.setLonLat(new Pair(location.getLongitude(), location.getLatitude())); + drawCarMarker(location); + if (isFirstLocation) { + displayCustomOverView(); + isFirstLocation = false; } } - public static boolean isPointOnCarFront(Location carLocal, LatLng pointLocal) { - double carLon = carLocal.getLongitude(); - double carLat = carLocal.getLatitude(); - double poiLon = pointLocal.longitude; - double poiLat = pointLocal.latitude; - float carAngle = carLocal.getBearing(); - - // 计算车辆与点之间的夹角 - int diffAngle = DrivingDirectionUtils.getDegreeOfCar2Poi( - carLon, carLat, poiLon, poiLat, (int) carAngle); - - return diffAngle <= 90; - } - - @Override public void drawablePolyline() { } - - public LatLng CoordinateConverterFrom84(Context mContext, MogoLatLng mogoLatLng) { - CoordinateConverter mCoordinateConverter = new CoordinateConverter(mContext); - mCoordinateConverter.from(CoordinateConverter.CoordType.GPS); - mCoordinateConverter.coord(new LatLng(mogoLatLng.lat, mogoLatLng.lon)); - return mCoordinateConverter.convert(); - } - - public List CoordinateConverterFrom84ForList(Context mContext, List mogoLatLngList) { - List list = new ArrayList<>(); - for (MogoLatLng m : mogoLatLngList) { - LatLng mogoLatLng = CoordinateConverterFrom84(mContext, m); - list.add(mogoLatLng); - } - return list; - } - @Override public void clearPolyline() { if (mPolyline != null) { @@ -412,6 +459,12 @@ public class AMapCustomView } } + public void clearCustomPolyline() { + if (mCustomPolyline != null) { + mCustomPolyline.remove(); + } + } + public void resetPolyLine() { mCoordinatesLatLng.clear(); if (mPolyline != null) { @@ -420,34 +473,34 @@ public class AMapCustomView } public void onCreateView(Bundle savedInstanceState) { - if (mAMapNaviView != null) { - mAMapNaviView.onCreate(savedInstanceState); + if (mAMapView != null) { + mAMapView.onCreate(savedInstanceState); } } public void onResume() { - if (mAMapNaviView != null) { - mAMapNaviView.onResume(); + if (mAMapView != null) { + mAMapView.onResume(); } } public void onPause() { - if (mAMapNaviView != null) { - mAMapNaviView.onPause(); + if (mAMapView != null) { + mAMapView.onPause(); } } public void onDestroy() { - if (mAMapNaviView != null) { - mAMapNaviView.onDestroy(); + if (mAMapView != null) { + mAMapView.onDestroy(); } - //since 1.6.0 不再在naviview destroy的时候自动执行AMapNavi.stopNavi();请自行执行 - if (mAMapNavi != null) { - mAMapNavi.stopNavi(); - mAMapNavi.destroy(); - } - if (mAMapNaviView != null) { - mAMapNaviView.onDestroy(); +// //since 1.6.0 不再在naviview destroy的时候自动执行AMapNavi.stopNavi();请自行执行 +// if (mAMapNavi != null) { +// mAMapNavi.stopNavi(); +// mAMapNavi.destroy(); +// } + if (mAMapView != null) { + mAMapView.onDestroy(); } } @@ -542,11 +595,6 @@ public class AMapCustomView Log.d(TAG, "onNaviInfoUpdate"); } - @Override - public void onNaviInfoUpdated(AMapNaviInfo aMapNaviInfo) { - Log.d(TAG, "onNaviInfoUpdated"); - } - @Override public void updateCameraInfo(AMapNaviCameraInfo[] aMapNaviCameraInfos) { Log.d(TAG, "updateCameraInfo"); @@ -612,11 +660,6 @@ public class AMapCustomView } - @Override - public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) { - - } - @Override public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) { @@ -636,16 +679,10 @@ public class AMapCustomView @Override public void onCalculateRouteSuccess(AMapCalcRouteResult aMapCalcRouteResult) { Log.d(TAG, "onCalculateRouteSuccess aMapCalcRouteResult" + aMapCalcRouteResult.toString()); - //提测修改为EMULATOR - mAMapNavi.startNavi(NaviType.GPS); - UiThreadHandler.postDelayed(() -> { - mAMapNaviView.displayOverview(); - }, 2000); - //停止导航测试代码 +// mAMapNavi.startNavi(NaviType.GPS); // UiThreadHandler.postDelayed(() -> { -// mAMapNavi.stopNavi(); -// Log.d(TAG, "stop------------"); -// }, 20000); +// mAMapView.displayOverview(); +// }, 500); } @Override @@ -658,6 +695,11 @@ public class AMapCustomView Log.d(TAG, "onNaviRouteNotify"); } + @Override + public void onGpsSignalWeak(boolean b) { + + } + @Override public void onNaviSetting() { @@ -727,6 +769,10 @@ public class AMapCustomView } + /** + * 绘制新基建Markers(比如:摄像头) + * @param globalPathResp + */ private void drawInfrastructureMarkers(MessagePad.GlobalPathResp globalPathResp) { if (globalPathResp != null) { if (!pathMap.isEmpty()) { @@ -734,7 +780,11 @@ public class AMapCustomView } String geoHash; ArrayList infList; + StringBuilder sb1 = new StringBuilder(); for (MessagePad.Location location : globalPathResp.getWayPointsList()) { + LonLatPoint p = new LonLatPoint(location.getLongitude(), location.getLatitude()); + p = MapTools.INSTANCE.switchLonLatWGS84(p); + sb1.append(p.getLongitude()).append(",").append(p.getLatitude()).append("\n"); geoHash = GeoHash.withCharacterPrecision(location.getLatitude(), location.getLongitude(), 7).toBase32(); // 网格内的轨迹点只取一次 if (!pathMap.containsKey(geoHash)) { @@ -745,6 +795,7 @@ public class AMapCustomView } } } + String str1 = sb1.toString(); drawInfMarkers(pathMap); } } @@ -782,7 +833,7 @@ public class AMapCustomView }); } - private Bitmap getBitmap(int count) { + private Bitmap getBitmap(int count) { MakerWithCount marker = new MakerWithCount(getContext()); marker.setCount(count); @@ -793,4 +844,107 @@ public class AMapCustomView marker.draw(new Canvas(bitmap)); return bitmap; } + + /** + * 进入自定义全览模式 + */ + private void displayCustomOverView() { + ArrayList linePointsLatLng = MarkerDrawerManager.INSTANCE.getPlanningPoints(); + MogoLocation location = mLocation; + if (linePointsLatLng.size() > 1){ + //圈定地图显示范围 + //存放经纬度 + LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder(); + for (int i = 0; i < linePointsLatLng.size(); i++) { + boundsBuilder.include(linePointsLatLng.get(i)); + } + LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude()); + boundsBuilder.include(currentLatLng); + //第二个参数为四周留空宽度 + mAMap.moveCamera(CameraUpdateFactory.newLatLngBoundsRect(boundsBuilder.build(),50,50,50,50)); + }else { + //设置希望展示的地图缩放级别 + CameraPosition cameraPosition = new CameraPosition.Builder() + .target(mCarMarker.getPosition()).tilt(0).bearing(location.getBearing()).zoom(zoomLevel).build(); + mAMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); + } + } + + /** + * 绘制自车 + * @param location + */ + private void drawCarMarker(MogoLocation location) { + if (location == null) return; + if (mCarMarker != null) { + LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude()); + mCarMarker.setRotateAngle(360 - location.getBearing()); + mCarMarker.setPosition(currentLatLng); + mCarMarker.setToTop(); + } + } + + /** + * 绘制起始点、终点 + */ + private void drawStartAndEndMarker(List coordinates) { + if (mStartMarker != null) { + mStartMarker.setVisible(false); + } + if (mEndMarker != null) { + mEndMarker.setVisible(false); + } + if (coordinates.size() > 2) { + // 设置开始结束Marker位置 + + LatLng startLatLng = coordinates.get(0); + LatLng endLatLng = coordinates.get(coordinates.size() - 1); + + mStartMarker.setPosition(startLatLng); + mEndMarker.setPosition(endLatLng); + mStartMarker.setVisible(true); + mEndMarker.setVisible(true); + } + } + + /** + * 绘制轨迹线 + * @param coordinates + * @param locIndex + */ + private void drawPolyline(List coordinates,int locIndex) { + if (textureList.size() > 0) { + textureList.clear(); + } + if (texIndexList.size() > 0) { + texIndexList.clear(); + } + for (int i = 0; i < coordinates.size(); i++){ + if (i <= locIndex){ + // 已走过的置灰 + textureList.add(arrivedBitmap); + } else { + // 未走过的纹理 + textureList.add(unArrivedBitmap); + } + texIndexList.add(i); + } + + if (mCustomPolyline != null) { + mCustomPolyline.remove(); + } + if (mAMap != null && coordinates.size() > 2) { + //设置线段纹理 + PolylineOptions polylineOptions = new PolylineOptions(); + polylineOptions.addAll(coordinates); +// polylineOptions.useGradient(true); + polylineOptions.width(12); //线段宽度 + polylineOptions.isUseTexture(); + polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapRound); + polylineOptions.setCustomTextureList(textureList); + polylineOptions.setCustomTextureIndex(texIndexList); + // 绘制线 + mCustomPolyline = mAMap.addPolyline(polylineOptions); + } + } } diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/MarkerDrawerManager.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/MarkerDrawerManager.kt new file mode 100644 index 0000000000..9d4771f2f2 --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/MarkerDrawerManager.kt @@ -0,0 +1,169 @@ +package com.mogo.eagle.core.function.smp + +import android.content.Context +import android.util.Log +import com.amap.api.maps.CoordinateConverter +import com.amap.api.maps.model.LatLng +import com.mogo.cloud.commons.utils.CoordinateUtils +import io.reactivex.Observable +import io.reactivex.ObservableOnSubscribe +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.schedulers.Schedulers +import mogo.telematics.pad.MessagePad +import java.util.concurrent.TimeUnit + +/** + * 自定义高德地图画线管理者 + */ +object MarkerDrawerManager { + + interface Callback { + fun onLocationChanged(planningPoints: List, locIndex: Int) + } + + private val routeWipeDisposable by lazy { + CompositeDisposable() + } + + // 自主画线的所有高德坐标系的轨迹点 + val planningPoints by lazy { + ArrayList() + } + + @Volatile + var lastArrivedIndex: Int = -1 + + @Volatile + var lonLat = Pair(0.0, 0.0) + + var callback: Callback? = null + + fun startLoopCalCarLocation() { + getLoopCalCarObservable().delay(1000L, TimeUnit.MILLISECONDS, true) + .subscribeOn(Schedulers.io()) + .repeat() + .retry() + .observeOn(AndroidSchedulers.mainThread()) + .subscribe().let { + routeWipeDisposable.add(it) + } + } + + fun stopLoopCalCarLocation() { + if (!routeWipeDisposable.isDisposed) { + routeWipeDisposable.dispose() + } + } + + private fun getLoopCalCarObservable(): Observable { + return Observable.create(ObservableOnSubscribe { emitter -> + if (emitter.isDisposed) return@ObservableOnSubscribe + synchronized(this) { + loopRouteAndWipe(planningPoints, lonLat.first, lonLat.second) + } + emitter.onComplete() + }) + } + + private fun loopRouteAndWipe(routePoints: List?, lon: Double, lat: Double) { + if (routePoints != null && routePoints.isNotEmpty()) { + val arrivedIndex: Int = getArrivedPointIndex(routePoints, lon, lat) + Log.d("cff", "thread is:${Thread.currentThread().name},arrivedIndex is:$arrivedIndex") + if (arrivedIndex != -1 && lastArrivedIndex != arrivedIndex) { + callback?.onLocationChanged(routePoints, arrivedIndex) + lastArrivedIndex = arrivedIndex + } + } + } + + fun updateRoutePoints(routePoints: List?, context: Context) { + if (routePoints == null || routePoints.isEmpty()) return + val latLngModels = coordinateConverterWgsToGcjListCommon(context, routePoints) + synchronized(this) { + planningPoints.clear() + planningPoints.addAll(latLngModels) + } +// float remainingSumLength = calculateRemainingSumLength(mRoutePoints); + } + + /** + * @param routePoints + * @param realLon + * @param realLat + * @return 返回已经到达点的index + */ + private fun getArrivedPointIndex( + routePoints: List, + realLon: Double, + realLat: Double + ): Int { + var currentIndex = 0 //记录疑似点 + if (routePoints.isNotEmpty()) { + //基础点 + val baseLatLng = routePoints[0] + var baseDiffDis = CoordinateUtils.calculateLineDistance( + realLon, realLat, baseLatLng.longitude, baseLatLng.latitude + ) // lon,lat, prelon, prelat + for (i in 1 until routePoints.size) { + val latLng = routePoints[i] + val diff = CoordinateUtils.calculateLineDistance( + realLon, realLat, latLng.longitude, latLng.latitude + ) + if (baseDiffDis > diff) { + baseDiffDis = diff + currentIndex = i + } + } + return currentIndex + } + return currentIndex + } + + /** + * + * @param points + * @return 剩余的总距离 + */ + private fun calculateRemainingSumLength(points: List?): Float { + if (null == points || points.isEmpty()) return 0F + var sumLength = 0f + + //计算全路径总距离 + var i = 0 + while (i + 1 < points.size) { + val preLat = points[i].latitude + val preLon = points[i].longitude + val laLat = points[i + 1].latitude + val laLon = points[i + 1].longitude + val length = CoordinateUtils.calculateLineDistance(laLon, laLat, preLon, preLat) + sumLength += length + i++ + } + return sumLength + } + + private fun coordinateConverterWgsToGcjListCommon( + mContext: Context, + models: List + ): List { + //转成MogoLatLng集合 + val list: MutableList = java.util.ArrayList() + for (m in models) { + val mogoLatLng = coordinateConverterWgsToGcj(mContext, m) + list.add(mogoLatLng) + } + return list + } + + private fun coordinateConverterWgsToGcj( + mContext: Context, + mogoLatLng: MessagePad.Location + ): LatLng { + val mCoordinateConverter = + CoordinateConverter(mContext) + mCoordinateConverter.from(CoordinateConverter.CoordType.GPS) + mCoordinateConverter.coord(LatLng(mogoLatLng.latitude, mogoLatLng.longitude)) + return mCoordinateConverter.convert() + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/OverviewMapFragment.java b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/OverviewMapFragment.java index e8a3d3bf49..c864632956 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/OverviewMapFragment.java +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/OverviewMapFragment.java @@ -1,6 +1,7 @@ package com.mogo.eagle.core.function.smp; import android.content.Context; +import android.location.Location; import android.os.Bundle; import android.view.View; @@ -19,7 +20,11 @@ import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListen import com.mogo.eagle.core.function.map.R; import com.mogo.eagle.core.function.overview.InfStructureManager; import com.mogo.eagle.core.data.map.Infrastructure; +import com.mogo.eagle.core.function.overview.ViewModelExtKt; +import com.mogo.eagle.core.function.overview.vm.OverViewModel; import com.mogo.eagle.core.utilcode.util.UiThreadHandler; +import com.mogo.map.navi.IMogoCarLocationChangedListener2; +import com.mogo.module.common.MogoApisHandler; import org.jetbrains.annotations.NotNull; @@ -27,6 +32,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import kotlin.Pair; import mogo.telematics.pad.MessagePad; import mogo_msg.MogoReportMsg; import system_master.SystemStatusInfo; diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi-2560x1440/amap_bus_corner.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi-2560x1440/amap_bus_corner.png new file mode 100644 index 0000000000000000000000000000000000000000..840089ceab140470ebed4098344fe2711ddc436f GIT binary patch literal 42264 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 literal 0 HcmV?d00001 diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi-2560x1440/amap_bus_smooth_route.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi-2560x1440/amap_bus_smooth_route.png new file mode 100644 index 0000000000000000000000000000000000000000..99d8bd7b56e80b8e4dec18c733d42e944d62d9d7 GIT binary patch literal 879 zcmeAS@N?(olHy`uVBq!ia0vp^3PAjfgAGV-Io%!$q!^2X+?^QKos)S9@YLn{4h9CMo1QL? zAr*{oZ+m-$1j-!$c)!QE@4TZ{)r5uIonmPb7rHf;w8*(#RJ*=5Dn&rItH~)!B}^|{ z(q*mEqzh9V%=fBx1c|8JP6-TiyE{kn`NI;o4Li@-#qsyUzb;NH&X|98*-Z<$_h ztLL!p5J;=_NgAD@@(DrJ0n_Oocs&YD+S*Q+hyZf{x@^X&48 zh?uqfy0#UvCsVa5H~qY^wrZ>YS@)(}aiSjDW(HEh-piNHJ9u(SwV!wlYlPgFS8p1F zWbejktiS%)Wd5&v?xi~qU+SK?;_?5qJS#Si8EmrawF84|H+C`KG~HdUu}DmKNxg|( zu=eBka~S#ZbuRpDcATnjxLWu4L?5-QAJrCxU7l5*+}X2v3G0frA6`#-`FYu?KRx_U ziVO{>Ub(w(!@AP{*Iw{f3*6R=h<_LSeC5(l6?1;i$?dS&oF}ziY~`*y>wjtA&*{G{ zCHV)LDi-m%*86b$qg9cQukUONdTZ1kq^G=^;qd(A zti0`4tiR;1-~U%2_;GLH+lblrvP-rp?cVxW>%fmAQ`VJ5?)qx7g7QEuqV*N4jlM1L*yEH0W=ob2cpxX*pzirS*t4mVWdP8ja4 tSQYl{m`+MpWU(*Eakt5%>1$Mz6yTGVBlb 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 literal 0 HcmV?d00001 diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/amap_bus_corner.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/amap_bus_corner.png new file mode 100644 index 0000000000000000000000000000000000000000..840089ceab140470ebed4098344fe2711ddc436f GIT binary patch literal 42264 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 literal 0 HcmV?d00001 diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/amap_bus_smooth_route.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/amap_bus_smooth_route.png new file mode 100644 index 0000000000000000000000000000000000000000..99d8bd7b56e80b8e4dec18c733d42e944d62d9d7 GIT binary patch literal 879 zcmeAS@N?(olHy`uVBq!ia0vp^3PAjfgAGV-Io%!$q!^2X+?^QKos)S9@YLn{4h9CMo1QL? zAr*{oZ+m-$1j-!$c)!QE@4TZ{)r5uIonmPb7rHf;w8*(#RJ*=5Dn&rItH~)!B}^|{ z(q*mEqzh9V%=fBx1c|8JP6-TiyE{kn`NI;o4Li@-#qsyUzb;NH&X|98*-Z<$_h ztLL!p5J;=_NgAD@@(DrJ0n_Oocs&YD+S*Q+hyZf{x@^X&48 zh?uqfy0#UvCsVa5H~qY^wrZ>YS@)(}aiSjDW(HEh-piNHJ9u(SwV!wlYlPgFS8p1F zWbejktiS%)Wd5&v?xi~qU+SK?;_?5qJS#Si8EmrawF84|H+C`KG~HdUu}DmKNxg|( zu=eBka~S#ZbuRpDcATnjxLWu4L?5-QAJrCxU7l5*+}X2v3G0frA6`#-`FYu?KRx_U ziVO{>Ub(w(!@AP{*Iw{f3*6R=h<_LSeC5(l6?1;i$?dS&oF}ziY~`*y>wjtA&*{G{ zCHV)LDi-m%*86b$qg9cQukUONdTZ1kq^G=^;qd(A zti0`4tiR;1-~U%2_;GLH+lblrvP-rp?cVxW>%fmAQ`VJ5?)qx7g7QEuqV*N4jlM1L*yEH0W=ob2cpxX*pzirS*t4mVWdP8ja4 tSQYl{m`+MpWU(*Eakt5%>1$Mz6yTGVBlb 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 literal 0 HcmV?d00001 diff --git a/core/function-impl/mogo-core-function-map/src/main/res/layout/module_overview_map_view.xml b/core/function-impl/mogo-core-function-map/src/main/res/layout/module_overview_map_view.xml index cd97415ef1..dedfa69132 100644 --- a/core/function-impl/mogo-core-function-map/src/main/res/layout/module_overview_map_view.xml +++ b/core/function-impl/mogo-core-function-map/src/main/res/layout/module_overview_map_view.xml @@ -17,8 +17,8 @@ android:layout_height="match_parent" android:layout_centerInParent="true"> - From 884bee3a20019cfa43d97a32435a25ac0e398e63 Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Wed, 3 Aug 2022 18:56:00 +0800 Subject: [PATCH 20/30] =?UTF-8?q?[Update]=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E7=BB=98=E5=88=B6=E8=BD=A8=E8=BF=B9=E7=BA=BF,=E4=B8=8D?= =?UTF-8?q?=E7=94=A8=E9=AB=98=E5=BE=B7=E5=AF=BC=E8=88=AA=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eagle/core/function/map/MapFragment.java | 16 +- .../function/overview/InfStructureManager.kt | 14 + .../core/function/smp/AMapCustomView.java | 617 +++--------------- .../core/function/smp/MarkerDrawerManager.kt | 12 +- .../function/smp/OverviewMapFragment.java | 84 +-- .../amap_custom_smooth_route.png | Bin 0 -> 215 bytes 6 files changed, 111 insertions(+), 632 deletions(-) create mode 100644 core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/amap_custom_smooth_route.png diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/map/MapFragment.java b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/map/MapFragment.java index 80daca40c3..6f1e3c704a 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/map/MapFragment.java +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/map/MapFragment.java @@ -12,7 +12,6 @@ import com.alibaba.android.arouter.facade.annotation.Route; import com.mogo.commons.mvp.MvpFragment; import com.mogo.eagle.core.data.constants.MoGoFragmentPaths; import com.mogo.eagle.core.data.map.CenterLine; -import com.mogo.eagle.core.data.map.Infrastructure; import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningListener; import com.mogo.eagle.core.function.api.map.hd.IMoGoMapFragmentProvider; import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener; @@ -30,11 +29,8 @@ import com.mogo.map.uicontroller.IMogoMapUIController; import com.zhidaoauto.map.sdk.open.MapAutoApi; import com.zhidaoauto.map.sdk.open.business.PointCloudHelper; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import ch.hsr.geohash.GeoHash; import mogo.telematics.pad.MessagePad; /** @@ -96,6 +92,7 @@ public class MapFragment extends MvpFragment } // 添加换肤监听 CallerSkinModeListenerManager.INSTANCE.addListener(TAG, this); + CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, moGoAutopilotPlanningListener); } @NonNull @@ -212,6 +209,17 @@ public class MapFragment extends MvpFragment viewModel.fetchInfStructures(); } + private final IMoGoAutopilotPlanningListener moGoAutopilotPlanningListener = new IMoGoAutopilotPlanningListener() { + + @Override + public void onAutopilotRotting(@Nullable MessagePad.GlobalPathResp globalPathResp) { + InfStructureManager.INSTANCE.savePlanningData(globalPathResp.getWayPointsList()); + } + + @Override + public void onAutopilotTrajectory(@NonNull List trajectoryInfos) {} + }; + @Override public IMogoMapUIController getUIController() { return mMogoMap.getUIController(); diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/InfStructureManager.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/InfStructureManager.kt index b249f7d1df..b355165c92 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/InfStructureManager.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/overview/InfStructureManager.kt @@ -1,6 +1,7 @@ package com.mogo.eagle.core.function.overview import com.mogo.eagle.core.data.map.Infrastructure +import mogo.telematics.pad.MessagePad /** * 本地数据库查询出来的红绿灯、摄像头等数据 @@ -17,6 +18,10 @@ object InfStructureManager { HashMap>() } + private val _planningList by lazy { + ArrayList() + } + fun saveData(map: HashMap>) { if (_infMap.isNotEmpty()) { _infMap.clear() @@ -34,4 +39,13 @@ object InfStructureManager { } fun getPathData(): Map> = _pathMap + + fun savePlanningData(planningList: List) { + if (_planningList.isNotEmpty()) { + _planningList.clear() + } + _planningList.addAll(planningList) + } + + fun getPlanningData() = _planningList } \ No newline at end of file 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 41b6c130dc..96aca1cc99 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 @@ -12,7 +12,6 @@ import android.view.View; import android.widget.RelativeLayout; import android.widget.TextView; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.amap.api.maps.AMap; @@ -30,43 +29,18 @@ import com.amap.api.maps.model.Marker; import com.amap.api.maps.model.MarkerOptions; import com.amap.api.maps.model.Polyline; import com.amap.api.maps.model.PolylineOptions; -import com.amap.api.navi.AMapNaviListener; -import com.amap.api.navi.AMapNaviViewListener; -import com.amap.api.navi.model.AMapCalcRouteResult; -import com.amap.api.navi.model.AMapLaneInfo; -import com.amap.api.navi.model.AMapModelCross; -import com.amap.api.navi.model.AMapNaviCameraInfo; -import com.amap.api.navi.model.AMapNaviCross; -import com.amap.api.navi.model.AMapNaviLocation; -import com.amap.api.navi.model.AMapNaviPathGroup; -import com.amap.api.navi.model.AMapNaviRouteNotifyData; -import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo; -import com.amap.api.navi.model.AMapServiceAreaInfo; -import com.amap.api.navi.model.AimLessModeCongestionInfo; -import com.amap.api.navi.model.AimLessModeStat; -import com.amap.api.navi.model.NaviInfo; -import com.amap.api.navi.model.NaviLatLng; -import com.amap.api.navi.model.NaviPoi; -import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo; import com.mogo.eagle.core.data.config.FunctionBuildConfig; import com.mogo.eagle.core.data.map.Infrastructure; -import com.mogo.eagle.core.data.map.MogoLatLng; import com.mogo.eagle.core.data.map.MogoLocation; import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningListener; -import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener; import com.mogo.eagle.core.function.api.map.listener.IMoGoMapLocationListener; -import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager; import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager; import com.mogo.eagle.core.function.call.hmi.CallerHmiManager; import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager; import com.mogo.eagle.core.function.map.R; import com.mogo.eagle.core.function.overview.InfStructureManager; -import com.mogo.eagle.core.function.smp.view.ISmallMapDirectionView; import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils; import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils; -import com.mogo.eagle.core.utilcode.util.UiThreadHandler; -import com.zhidaoauto.map.sdk.open.query.LonLatPoint; -import com.zhidaoauto.map.sdk.open.tools.MapTools; import org.jetbrains.annotations.NotNull; @@ -78,8 +52,6 @@ import java.util.Map; import ch.hsr.geohash.GeoHash; import kotlin.Pair; import mogo.telematics.pad.MessagePad; -import mogo_msg.MogoReportMsg; -import system_master.SystemStatusInfo; /** * 小地图的方向View @@ -90,22 +62,14 @@ import system_master.SystemStatusInfo; */ public class AMapCustomView extends RelativeLayout - implements IMoGoMapLocationListener, ISmallMapDirectionView, AMapNaviListener, AMapNaviViewListener { + implements IMoGoMapLocationListener { public static final String TAG = "AMapCustomView"; private TextureMapView mAMapView; private AMap mAMap; - protected NaviLatLng mStartLatlng = new NaviLatLng(); - protected NaviLatLng mEndLatlng = new NaviLatLng(); - protected final List sList = new ArrayList(); - protected final List eList = new ArrayList(); private int zoomLevel = 15; - private final List mCoordinatesLatLng = new ArrayList<>(); - private final List mCoordinatesLatLngCurrent = new ArrayList<>(); - protected List mWayPointList = new ArrayList(); - private Polyline mPolyline; private CameraUpdate mCameraUpdate; private Context mContext; - private float tilt = 30f; + private float mTilt = 60f; private TextView overLayerView; private boolean calculate = false; @@ -113,17 +77,13 @@ public class AMapCustomView private Map> pathMap = new HashMap(); private Map> posInfMap = new HashMap(); - // 独立路径导航 - private NaviPoi mStartPoi = null; - private NaviPoi mEndPoi = null; - private AMapNaviPathGroup mIndependentPathGroup = null; - private List mIndependentPointList = new ArrayList<>(); - // =============绘制轨迹线相关============= private Marker mCarMarker; + private Marker mCompassMarker; private Marker mStartMarker; private Marker mEndMarker; - private Polyline mCustomPolyline; + private Polyline mBottomPolyline; + private Polyline mCoveredPolyline; // 计算索引并设置对应的Bitmap BitmapDescriptor arrivedBitmap; BitmapDescriptor unArrivedBitmap; @@ -160,21 +120,18 @@ public class AMapCustomView overLayerView.setBackground(getResources().getDrawable(R.drawable.amap_reset)); arrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.arrow_arrived_img); unArrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.amap_bus_smooth_route); -// unArrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.amap_custom_smooth_route); } else { overLayerView.setBackground(getResources().getDrawable(R.drawable.amap_reset_bus)); arrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.arrow_arrived_img); unArrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.amap_bus_smooth_route); } - CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, mGoAutopilotStatusListener); CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, moGoAutopilotPlanningListener); initAMapView(context); // 注册定位监听 CallerMapLocationListenerManager.INSTANCE.addListener(TAG, this); //设置全览模式 overLayerView.setOnClickListener(v -> { -// mAMapView.displayOverview(); - CallerHmiManager.INSTANCE.hideSmallFragment(); + displayCustomOverView(); }); } @@ -229,120 +186,28 @@ public class AMapCustomView * 自定义导航View和路况状态 */ private void customOptions() { -// AMapNaviViewOptions options = mAMapView.getViewOptions(); - //关闭自动绘制路线,自行绘制路线 -// options.setAutoDrawRoute(false); - //不显示导航界面 -// options.setLayoutVisible(false); -// options.setTilt(60); -// //黑夜模式 -// options.setNaviNight(true); -// //导航全程光柱 -// options.setTrafficBarEnabled(false); -// //隐藏摄像头 -// options.setCameraBubbleShow(false); -// //转向箭头 -// options.setNaviArrowVisible(false); -// // 算路成功后自动进入全览模式 -// options.setAutoDisplayOverview(true); - //指南针 -// options.setCompassEnabled(false); -// options.setTilt((int) tilt); - //路线纹理自定义 -// RouteOverlayOptions routeOverlayOptions = new RouteOverlayOptions(); if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) { - // TODO:("导航的配置需要删除") mCarMarker = mAMap.addMarker(new MarkerOptions() .icon(BitmapDescriptorFactory.fromResource(R.drawable.map_car_icon)) .anchor(0.5f, 0.5f)); - -// //自车车标 -// options.setCarBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.map_car_icon)); -// options.setFourCornersBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.amap_custom_corner)); - // 未知路段和导航路段颜色一样 -// routeOverlayOptions.setUnknownTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.amap_custom_smooth_route));//未知路段 -// routeOverlayOptions.setSmoothTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.amap_custom_smooth_route)); + mCompassMarker = mAMap.addMarker(new MarkerOptions() + .icon(BitmapDescriptorFactory.fromResource(R.drawable.amap_custom_corner)) + .anchor(0.5f, 0.5f)); } else { - // TODO:("导航的配置需要删除") mCarMarker = mAMap.addMarker(new MarkerOptions() .icon(BitmapDescriptorFactory.fromResource(R.drawable.map_bus_icon)) .anchor(0.5f, 0.5f)); - -// options.setCarBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.map_bus_icon)); -// options.setFourCornersBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.amap_bus_corner)); -// routeOverlayOptions.setUnknownTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.amap_bus_smooth_route));//未知路段 -// routeOverlayOptions.setSmoothTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.amap_bus_smooth_route)); + mCompassMarker = mAMap.addMarker(new MarkerOptions() + .icon(BitmapDescriptorFactory.fromResource(R.drawable.amap_bus_corner)) + .anchor(0.5f, 0.5f)); } mStartMarker = mAMap.addMarker(new MarkerOptions() .icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_start))); mEndMarker = mAMap.addMarker(new MarkerOptions() .icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_end))); - -// options.setStartPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.module_small_map_view_dir_start)); -// options.setWayPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.icon_module_small_map_four_corners)); -// options.setEndPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.module_small_map_view_dir_end)); -// //与走过的路线 -// options.setAfterRouteAutoGray(true); -// routeOverlayOptions.setTurnArrowIs3D(false); -// routeOverlayOptions.setJamTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.custtexture_bad));//拥堵路段 -// routeOverlayOptions.setVeryJamTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.custtexture_grayred));//超级拥堵路段 -// routeOverlayOptions.setPassRoute(BitmapFactory.decodeResource(getResources(), R.drawable.amap_custom_pass_route));//走过的路段 -// options.setRouteOverlayOptions(routeOverlayOptions); -// mAMapView.setTrafficLightsVisible(true); -// mAMapView.setViewOptions(options); } - private final IMoGoAutopilotStatusListener mGoAutopilotStatusListener = new IMoGoAutopilotStatusListener() { - - @Override - public void onAutopilotStatusRespByQuery(@NonNull SystemStatusInfo.StatusInfo status) { - - } - - @Override - public void onAutopilotIpcConnectStatusChanged(int status, @org.jetbrains.annotations.Nullable String reason) { - - } - - @Override - public void onAutopilotGuardian(@org.jetbrains.annotations.Nullable MogoReportMsg.MogoReportMessage guardianInfo) { - - } - - @Override - public void onAutopilotSNRequest() { - - } - - @Override - public void onAutopilotArriveAtStation(@org.jetbrains.annotations.Nullable MessagePad.ArrivalNotification arrivalNotification) { - - } - - @Override - public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autoPilotStatusInfo) { -// ThreadUtils.runOnUiThread(() -> { -// if (autoPilotStatusInfo == null) return; -// int state = autoPilotStatusInfo.getState(); -// //0 不能自动驾驶 1 可以自动驾驶,但是在人工干预 2 自动驾驶中 -// if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) { -//// Log.d(TAG, "自动驾驶中 state=" + String.valueOf(state)); -// if (sList.size() == 0 && eList.size() == 0 && mWayPointList.size() == 0) { -// Log.d(TAG, "sendGlobalPathReq"); -// AdasManager.getInstance().sendGlobalPathReq(); -// } -// } else { -// int type = mAMapNavi.getNaviType(); -// Log.d(TAG, "非自动驾驶状态,导航类型==" + String.valueOf(type)); -// if (type == NaviType.GPS || type == NaviType.EMULATOR) { -// mAMapNavi.stopNavi(); -// } -// } -// }); - } - }; - private final IMoGoAutopilotPlanningListener moGoAutopilotPlanningListener = new IMoGoAutopilotPlanningListener() { @Override @@ -357,77 +222,35 @@ public class AMapCustomView */ @Override public void onAutopilotRotting(@org.jetbrains.annotations.Nullable MessagePad.GlobalPathResp globalPathResp) { - if (calculate == true && sList.size() == 0 && eList.size() == 0 && mWayPointList.size() == 0) { - return; - } - calculate = true; Log.d(TAG, "onAutopilotRotting"); - List list = globalPathResp.getWayPointsList(); -// int minCount = 2; -// if (list.size() >= minCount && sList.size() == 0 && eList.size() == 0 && mWayPointList.size() == 0) { -// calculate = true; -// MessagePad.Location sLocation = (MessagePad.Location) list.get(0); -// MessagePad.Location eLocation = (MessagePad.Location) list.get(list.size() - 1); -// mStartLatlng = new NaviLatLng(sLocation.getLatitude(), sLocation.getLongitude()); -// mEndLatlng = new NaviLatLng(eLocation.getLatitude(), eLocation.getLongitude()); -// mStartPoi = new NaviPoi("", new LatLng(sLocation.getLatitude(), sLocation.getLongitude()), ""); -// mEndPoi = new NaviPoi("", new LatLng(eLocation.getLatitude(), eLocation.getLongitude()), ""); -// sList.clear(); -// eList.clear(); -// sList.add(mStartLatlng); -// eList.add(mEndLatlng); -// -// mWayPointList.clear(); -// mIndependentPointList.clear(); -// for (int i = 1; i < list.size() - minCount; i++) { -// MessagePad.Location wayLoc = (MessagePad.Location) list.get(i); -// NaviLatLng way = new NaviLatLng(wayLoc.getLatitude(), wayLoc.getLongitude()); -// NaviPoi naviPoi = new NaviPoi("", new LatLng(wayLoc.getLatitude(), wayLoc.getLongitude()), ""); -// mWayPointList.add(way); -// mIndependentPointList.add(naviPoi); -// } -// } -// int strategy = 0; -// try { -// //再次强调,最后一个参数为true时代表多路径,否则代表单路径 -// strategy = mAMapNavi.strategyConvert(true, false, false, false, false); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// Log.d(TAG, "全局路径" + list.size() + ",起点:" + sList.toString() + ",终点:" + eList.toString() + ",经点:" + mWayPointList.toString()); -// //指定路径绘制导航路线 -// mAMapNavi.calculateDriveRoute(sList, eList, mWayPointList, strategy); - - // 转成高德坐标系并存储 - MarkerDrawerManager.INSTANCE.updateRoutePoints(list, mContext); - List planningPointList = MarkerDrawerManager.INSTANCE.getPlanningPoints(); - UiThreadHandler.post(() -> { - displayCustomOverView(); - drawStartAndEndMarker(planningPointList); - }); - MarkerDrawerManager.INSTANCE.setCallback((points, locIndex) -> { - UiThreadHandler.post(() -> { - // 每1s刷新一下轨迹线 - if (points.size() > 0) { - drawPolyline(points , locIndex); - } else { - clearCustomPolyline(); - } - }); - }); - MarkerDrawerManager.INSTANCE.startLoopCalCarLocation(); - UiThreadHandler.post(() -> { - drawInfrastructureMarkers(globalPathResp); - }); + handlePlanningData(globalPathResp.getWayPointsList()); } }; + public void handlePlanningData(List locationList) { + List list = locationList; + // 转成高德坐标系并存储 + MarkerDrawerManager.INSTANCE.updateRoutePoints(list, mContext); + List planningPointList = MarkerDrawerManager.INSTANCE.getPlanningPoints(); + displayCustomOverView(); + drawStartAndEndMarker(planningPointList); + MarkerDrawerManager.INSTANCE.setCallback((points, locIndex) -> { + // 每1s刷新一下轨迹线 + if (points.size() > 0) { + drawPolyline(points, locIndex); + } else { + clearCustomPolyline(); + } + }); + MarkerDrawerManager.INSTANCE.startLoopCalCarLocation(); + drawInfrastructureMarkers(locationList); + } + @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); // 注册定位监听 CallerMapLocationListenerManager.INSTANCE.removeListener(TAG); - CallerAutoPilotStatusListenerManager.INSTANCE.removeListener(TAG); CallerAutopilotPlanningListenerManager.INSTANCE.removeListener(TAG); } @@ -448,30 +271,6 @@ public class AMapCustomView } } - @Override - public void drawablePolyline() { - } - - @Override - public void clearPolyline() { - if (mPolyline != null) { - mPolyline.remove(); - } - } - - public void clearCustomPolyline() { - if (mCustomPolyline != null) { - mCustomPolyline.remove(); - } - } - - public void resetPolyLine() { - mCoordinatesLatLng.clear(); - if (mPolyline != null) { - mPolyline.remove(); - } - } - public void onCreateView(Bundle savedInstanceState) { if (mAMapView != null) { mAMapView.onCreate(savedInstanceState); @@ -494,310 +293,45 @@ public class AMapCustomView if (mAMapView != null) { mAMapView.onDestroy(); } -// //since 1.6.0 不再在naviview destroy的时候自动执行AMapNavi.stopNavi();请自行执行 -// if (mAMapNavi != null) { -// mAMapNavi.stopNavi(); -// mAMapNavi.destroy(); -// } + if (mAMapView != null) { mAMapView.onDestroy(); } } - public void convert(List coordinates) { - - } - - //多路径算路成功回调 - @Override - public void onCalculateRouteSuccess(int[] ints) { - Log.d(TAG, "onCalculateRouteSuccess int"); - } - - - @Override - public void onInitNaviFailure() { - calculate = false; - Log.d(TAG, "onInitNaviFailure"); - } - - @Override - public void onInitNaviSuccess() { - Log.d(TAG, "onInitNaviSuccess"); - - } - - @Override - public void onStartNavi(int i) { - Log.d(TAG, "onStartNavi"); - - } - - @Override - public void onTrafficStatusUpdate() { - - } - - @Override - public void onLocationChange(AMapNaviLocation aMapNaviLocation) { -// Log.d(TAG, "高德地图经纬度:" + aMapNaviLocation.getCoord().getLongitude() + "," + aMapNaviLocation.getCoord().getLatitude()); - - } - - @Override - public void onGetNavigationText(int i, String s) { - Log.d(TAG, "onGetNavigationText int"); - } - - @Override - public void onGetNavigationText(String s) { - Log.d(TAG, "onGetNavigationText ss"); - - } - - @Override - public void onEndEmulatorNavi() { - Log.d(TAG, "onEndEmulatorNavi"); - } - - @Override - public void onArriveDestination() { - Log.d(TAG, "onArriveDestination"); - } - - @Override - public void onCalculateRouteFailure(int i) { - Log.d(TAG, "onCalculateRouteFailure"); - } - - @Override - public void onReCalculateRouteForYaw() { - Log.d(TAG, "onReCalculateRouteForYaw"); - } - - @Override - public void onReCalculateRouteForTrafficJam() { - Log.d(TAG, "onReCalculateRouteForTrafficJam"); - } - - @Override - public void onArrivedWayPoint(int i) { - Log.d(TAG, "onArrivedWayPoint"); - } - - @Override - public void onGpsOpenStatus(boolean b) { - Log.d(TAG, "onGpsOpenStatus"); - } - - @Override - public void onNaviInfoUpdate(NaviInfo naviInfo) { - Log.d(TAG, "onNaviInfoUpdate"); - } - - @Override - public void updateCameraInfo(AMapNaviCameraInfo[] aMapNaviCameraInfos) { - Log.d(TAG, "updateCameraInfo"); - } - - @Override - public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i) { - Log.d(TAG, "updateIntervalCameraInfo"); - } - - @Override - public void onServiceAreaUpdate(AMapServiceAreaInfo[] aMapServiceAreaInfos) { - Log.d(TAG, "onServiceAreaUpdate"); - } - - @Override - public void showCross(AMapNaviCross aMapNaviCross) { - Log.d(TAG, "showCross"); - } - - @Override - public void hideCross() { - Log.d(TAG, "hideCross"); - } - - @Override - public void showModeCross(AMapModelCross aMapModelCross) { - Log.d(TAG, "showModeCross"); - } - - @Override - public void hideModeCross() { - Log.d(TAG, "hideModeCross"); - } - - @Override - public void showLaneInfo(AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1) { - Log.d(TAG, "showLaneInfo"); - } - - @Override - public void showLaneInfo(AMapLaneInfo aMapLaneInfo) { - Log.d(TAG, "showLaneInfo"); - } - - @Override - public void hideLaneInfo() { - Log.d(TAG, "hideLaneInfo"); - } - - @Override - public void notifyParallelRoad(int i) { - - } - - @Override - public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) { - - } - - @Override - public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) { - - } - - @Override - public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) { - - } - - @Override - public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) { - - } - - @Override - public void onPlayRing(int i) { - - } - - //算路详情 - @Override - public void onCalculateRouteSuccess(AMapCalcRouteResult aMapCalcRouteResult) { - Log.d(TAG, "onCalculateRouteSuccess aMapCalcRouteResult" + aMapCalcRouteResult.toString()); -// mAMapNavi.startNavi(NaviType.GPS); -// UiThreadHandler.postDelayed(() -> { -// mAMapView.displayOverview(); -// }, 500); - } - - @Override - public void onCalculateRouteFailure(AMapCalcRouteResult aMapCalcRouteResult) { - Log.d(TAG, "onCalculateRouteFailure"); - } - - @Override - public void onNaviRouteNotify(AMapNaviRouteNotifyData aMapNaviRouteNotifyData) { - Log.d(TAG, "onNaviRouteNotify"); - } - - @Override - public void onGpsSignalWeak(boolean b) { - - } - - @Override - public void onNaviSetting() { - - } - - @Override - public void onNaviCancel() { - - } - - @Override - public boolean onNaviBackClick() { - return false; - } - - @Override - public void onNaviMapMode(int i) { - - } - - @Override - public void onNaviTurnClick() { - - } - - @Override - public void onNextRoadClick() { - - } - - @Override - public void onScanViewButtonClick() { - - } - - @Override - public void onLockMap(boolean b) { - - } - - @Override - public void onNaviViewLoaded() { - Log.d(TAG, "---onNaviViewLoaded---"); - CustomMapStyleOptions customMapStyleOptions = new CustomMapStyleOptions(); - // 加载自定义样式 - customMapStyleOptions.setEnable(true); - if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) { - customMapStyleOptions.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "over_view_style.data")); - customMapStyleOptions.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "over_view_style_extra.data")); - } else { - customMapStyleOptions.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "over_view_style_bus.data")); - customMapStyleOptions.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "over_view_style_extra_bus.data")); + public void clearCustomPolyline() { + if (mBottomPolyline != null) { + mBottomPolyline.remove(); + } + if (mCoveredPolyline != null) { + mCoveredPolyline.remove(); } - // 设置自定义样式 - mAMap.setCustomMapStyle(customMapStyleOptions); - // 实时路况图层关闭,必须添加在loaded结束之后,其他位置不生效 - mAMap.setTrafficEnabled(false); - } - - @Override - public void onMapTypeChanged(int i) { - - } - - @Override - public void onNaviViewShowMode(int i) { - } /** * 绘制新基建Markers(比如:摄像头) - * @param globalPathResp + * + * @param locationList */ - private void drawInfrastructureMarkers(MessagePad.GlobalPathResp globalPathResp) { - if (globalPathResp != null) { - if (!pathMap.isEmpty()) { - pathMap.clear(); - } - String geoHash; - ArrayList infList; - StringBuilder sb1 = new StringBuilder(); - for (MessagePad.Location location : globalPathResp.getWayPointsList()) { - LonLatPoint p = new LonLatPoint(location.getLongitude(), location.getLatitude()); - p = MapTools.INSTANCE.switchLonLatWGS84(p); - sb1.append(p.getLongitude()).append(",").append(p.getLatitude()).append("\n"); - geoHash = GeoHash.withCharacterPrecision(location.getLatitude(), location.getLongitude(), 7).toBase32(); - // 网格内的轨迹点只取一次 - if (!pathMap.containsKey(geoHash)) { - // 从缓存的新基建数据中去取对应geoHash的新基建数据集合 - infList = InfStructureManager.INSTANCE.getData().get(geoHash); - if (infList != null) { - pathMap.put(geoHash, infList); - } + private void drawInfrastructureMarkers(List locationList) { + if (!pathMap.isEmpty()) { + pathMap.clear(); + } + String geoHash; + ArrayList infList; + for (MessagePad.Location location : locationList) { + LatLng latLng = MarkerDrawerManager.INSTANCE.coordinateConverterWgsToGcj(mContext, location); + geoHash = GeoHash.withCharacterPrecision(latLng.latitude, latLng.longitude, 7).toBase32(); + // 网格内的轨迹点只取一次s + if (!pathMap.containsKey(geoHash)) { + // 从缓存的新基建数据中去取对应geoHash的新基建数据集合 + infList = InfStructureManager.INSTANCE.getData().get(geoHash); + if (infList != null) { + pathMap.put(geoHash, infList); } } - String str1 = sb1.toString(); - drawInfMarkers(pathMap); } + drawInfMarkers(pathMap); } public void drawInfMarkers(Map> infStruMap) { @@ -851,7 +385,7 @@ public class AMapCustomView private void displayCustomOverView() { ArrayList linePointsLatLng = MarkerDrawerManager.INSTANCE.getPlanningPoints(); MogoLocation location = mLocation; - if (linePointsLatLng.size() > 1){ + if (linePointsLatLng.size() > 1) { //圈定地图显示范围 //存放经纬度 LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder(); @@ -860,18 +394,22 @@ public class AMapCustomView } LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude()); boundsBuilder.include(currentLatLng); + + CameraPosition cameraPosition = new CameraPosition.Builder().tilt(mTilt).build(); //第二个参数为四周留空宽度 - mAMap.moveCamera(CameraUpdateFactory.newLatLngBoundsRect(boundsBuilder.build(),50,50,50,50)); - }else { + mAMap.moveCamera(CameraUpdateFactory.newLatLngBoundsRect(boundsBuilder.build(), 100, 100, 100, 100)); + mAMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); + } else { //设置希望展示的地图缩放级别 CameraPosition cameraPosition = new CameraPosition.Builder() - .target(mCarMarker.getPosition()).tilt(0).bearing(location.getBearing()).zoom(zoomLevel).build(); + .target(mCarMarker.getPosition()).tilt(0).zoom(zoomLevel).build(); mAMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); } } /** * 绘制自车 + * * @param location */ private void drawCarMarker(MogoLocation location) { @@ -881,6 +419,10 @@ public class AMapCustomView mCarMarker.setRotateAngle(360 - location.getBearing()); mCarMarker.setPosition(currentLatLng); mCarMarker.setToTop(); + if (mCompassMarker != null) { + mCompassMarker.setRotateAngle(360 - location.getBearing()); + mCompassMarker.setPosition(currentLatLng); + } } } @@ -909,18 +451,19 @@ public class AMapCustomView /** * 绘制轨迹线 + * * @param coordinates * @param locIndex */ - private void drawPolyline(List coordinates,int locIndex) { + private void drawPolyline(List coordinates, int locIndex) { if (textureList.size() > 0) { textureList.clear(); } if (texIndexList.size() > 0) { texIndexList.clear(); } - for (int i = 0; i < coordinates.size(); i++){ - if (i <= locIndex){ + for (int i = 0; i < coordinates.size(); i++) { + if (i <= locIndex) { // 已走过的置灰 textureList.add(arrivedBitmap); } else { @@ -929,22 +472,20 @@ public class AMapCustomView } texIndexList.add(i); } - - if (mCustomPolyline != null) { - mCustomPolyline.remove(); - } if (mAMap != null && coordinates.size() > 2) { //设置线段纹理 PolylineOptions polylineOptions = new PolylineOptions(); polylineOptions.addAll(coordinates); -// polylineOptions.useGradient(true); - polylineOptions.width(12); //线段宽度 - polylineOptions.isUseTexture(); + polylineOptions.width(14); //线段宽度 polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapRound); polylineOptions.setCustomTextureList(textureList); polylineOptions.setCustomTextureIndex(texIndexList); // 绘制线 - mCustomPolyline = mAMap.addPolyline(polylineOptions); + mBottomPolyline = mCoveredPolyline; + mCoveredPolyline = mAMap.addPolyline(polylineOptions); + if (mBottomPolyline != null) { + mBottomPolyline.remove(); + } } } } diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/MarkerDrawerManager.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/MarkerDrawerManager.kt index 9d4771f2f2..08f04fdb0e 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/MarkerDrawerManager.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/MarkerDrawerManager.kt @@ -59,9 +59,7 @@ object MarkerDrawerManager { private fun getLoopCalCarObservable(): Observable { return Observable.create(ObservableOnSubscribe { emitter -> if (emitter.isDisposed) return@ObservableOnSubscribe - synchronized(this) { - loopRouteAndWipe(planningPoints, lonLat.first, lonLat.second) - } + loopRouteAndWipe(planningPoints, lonLat.first, lonLat.second) emitter.onComplete() }) } @@ -80,10 +78,8 @@ object MarkerDrawerManager { fun updateRoutePoints(routePoints: List?, context: Context) { if (routePoints == null || routePoints.isEmpty()) return val latLngModels = coordinateConverterWgsToGcjListCommon(context, routePoints) - synchronized(this) { - planningPoints.clear() - planningPoints.addAll(latLngModels) - } + planningPoints.clear() + planningPoints.addAll(latLngModels) // float remainingSumLength = calculateRemainingSumLength(mRoutePoints); } @@ -156,7 +152,7 @@ object MarkerDrawerManager { return list } - private fun coordinateConverterWgsToGcj( + fun coordinateConverterWgsToGcj( mContext: Context, mogoLatLng: MessagePad.Location ): LatLng { diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/OverviewMapFragment.java b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/OverviewMapFragment.java index c864632956..c1862a7485 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/OverviewMapFragment.java +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/OverviewMapFragment.java @@ -1,41 +1,21 @@ package com.mogo.eagle.core.function.smp; import android.content.Context; -import android.location.Location; import android.os.Bundle; import android.view.View; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.alibaba.android.arouter.facade.annotation.Route; import com.mogo.commons.mvp.BaseFragment; -import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo; import com.mogo.eagle.core.data.constants.MoGoFragmentPaths; import com.mogo.eagle.core.data.map.MogoLatLng; -import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningListener; -import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener; import com.mogo.eagle.core.function.api.map.smp.IMogoSmallMapProvider; import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager; import com.mogo.eagle.core.function.map.R; import com.mogo.eagle.core.function.overview.InfStructureManager; -import com.mogo.eagle.core.data.map.Infrastructure; -import com.mogo.eagle.core.function.overview.ViewModelExtKt; -import com.mogo.eagle.core.function.overview.vm.OverViewModel; -import com.mogo.eagle.core.utilcode.util.UiThreadHandler; -import com.mogo.map.navi.IMogoCarLocationChangedListener2; -import com.mogo.module.common.MogoApisHandler; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; import java.util.List; -import java.util.Map; - -import kotlin.Pair; -import mogo.telematics.pad.MessagePad; -import mogo_msg.MogoReportMsg; -import system_master.SystemStatusInfo; /** * @author donghongyu @@ -44,8 +24,7 @@ import system_master.SystemStatusInfo; */ @Route(path = MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW) public class OverviewMapFragment extends BaseFragment - implements IMogoSmallMapProvider, IMoGoAutopilotPlanningListener, - IMoGoAutopilotStatusListener { + implements IMogoSmallMapProvider { private final String TAG = "SmallMapFragment"; protected AMapCustomView mAMapCustomView; @@ -74,7 +53,6 @@ public class OverviewMapFragment extends BaseFragment super.initViews(savedInstanceState); mAMapCustomView = mRootView.findViewById(R.id.smallMapDirectionView); mAMapCustomView.onCreateView(savedInstanceState); - CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, this); } @Override @@ -93,17 +71,10 @@ public class OverviewMapFragment extends BaseFragment @Override public void drawablePolyline(List coordinates) { - if (mAMapCustomView != null) { - mAMapCustomView.convert(coordinates); - UiThreadHandler.post(() -> mAMapCustomView.drawablePolyline()); - } } @Override public void clearPolyline() { - if (mAMapCustomView != null) { - UiThreadHandler.post(() -> mAMapCustomView.clearPolyline()); - } } @Override @@ -112,6 +83,7 @@ public class OverviewMapFragment extends BaseFragment if (mAMapCustomView != null) { mAMapCustomView.onResume(); } + mAMapCustomView.handlePlanningData(InfStructureManager.INSTANCE.getPlanningData()); } @Override @@ -146,56 +118,4 @@ public class OverviewMapFragment extends BaseFragment } CallerAutopilotPlanningListenerManager.INSTANCE.removeListener(TAG); } - - @Override - public void onAutopilotTrajectory(List trajectoryInfos) { - - } - - @Override - public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autoPilotStatusInfo) { - if (autoPilotStatusInfo.getPilotmode() != 1) { - clearPolyline(); - } - } - - @Override - public void onAutopilotArriveAtStation(MessagePad.ArrivalNotification arrivalNotification) { - - } - - @Override - public void onAutopilotSNRequest() { - - } - - @Override - public void onAutopilotGuardian(MogoReportMsg.MogoReportMessage guardianInfo) { - - } - - @Override - public void onAutopilotIpcConnectStatusChanged(int status, @Nullable String reason) { - } - - @Override - public void onAutopilotRotting(MessagePad.GlobalPathResp globalPathResp) { - if (globalPathResp == null || globalPathResp.getWayPointsList().size() == 0) { - return; - } - List latLngList = new ArrayList<>(); - for (MessagePad.Location routeModel : globalPathResp.getWayPointsList()) { - latLngList.add(new MogoLatLng(routeModel.getLatitude(), routeModel.getLongitude())); - } - if (latLngList.size() > 0) { - drawablePolyline(latLngList); - } else { - clearPolyline(); - } - } - - @Override - public void onAutopilotStatusRespByQuery(@NonNull SystemStatusInfo.StatusInfo status) { - - } } diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/amap_custom_smooth_route.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/amap_custom_smooth_route.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcfe1d5a30aeeb9c5dcc23192dddd544168cf52 GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}E~ycoX}-P; zT0k}j17mw80}DtA5K93u0|WB{Mh0de%?J`(zyz07Sip>6gA}f5OZp6?96eneLn1ie zUNGckP!Mr;w9}fkw literal 0 HcmV?d00001 From 5d72121aca1b43d9c6c8ce3c3602e9edc4f896a3 Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Thu, 4 Aug 2022 14:30:53 +0800 Subject: [PATCH 21/30] =?UTF-8?q?[Update]=E5=85=B3=E9=97=AD=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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 e4e5faa093..901e32a7bb 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 @@ -172,11 +172,10 @@ import java.util.* } } - ivCameraIcon?.setOnLongClickListener { - showSmallFragment() -// activity?.let { it1 -> CarcorderPreviewView.show(it1) } + /*ivCameraIcon?.setOnLongClickListener { + activity?.let { it1 -> CarcorderPreviewView.show(it1) } true - } + }*/ ivToolsIcon?.setOnClickListener { if (toolsViewFloat == null) { From 6ce2b501f8f0b3d96072bc084452a2b39e3a8eb5 Mon Sep 17 00:00:00 2001 From: wangmingjun Date: Thu, 4 Aug 2022 14:38:38 +0800 Subject: [PATCH 22/30] =?UTF-8?q?[290=20bus/taxi]bus=E5=8F=B8=E6=9C=BA?= =?UTF-8?q?=E7=AB=AF=E4=BC=98=E5=8C=96=E8=BD=A8=E8=BF=B9=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../passenger/model/BusPassengerModel.java | 35 +++++++++++++------ .../ui/BusPassengerBaseFragment.java | 10 ++++-- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java index 7ddfb2df9f..f28068397c 100644 --- a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java @@ -157,6 +157,7 @@ public class BusPassengerModel { BusPassengerStation station = stations.get(i); if (station.getDrivingStatus() == STATION_STATUS_STOPPED && station.isLeaving() && i+1 < stations.size()){ mRouteLineInfoCallback.updateStationsInfo(stations,i+1,false); + mTwoStationsRouts.clear(); if(mNextStationIndex != i+1){ startRemainRouteInfo(); } @@ -299,6 +300,8 @@ public class BusPassengerModel { } }; + private volatile int mPreAutoStatus = -1; + private final IMoGoAutopilotStatusListener mGoAutopilotStatusListener = new IMoGoAutopilotStatusListener(){ @Override @@ -314,17 +317,27 @@ public class BusPassengerModel { @Override public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autopilotStatusInfo) { -// if (autopilotStatusInfo == null) return; -// int state = autopilotStatusInfo.getState(); -// CallerLogger.INSTANCE.d( M_BUS_P + TAG, "state = %s", state ); -// if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) { -// //2022.7.20 自动驾驶更换成带档位的 -//// if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotRunning(); -// } else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE) { -//// if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotEnable(); -// } else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE) { -//// if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotDisable(); -// } + if (autopilotStatusInfo == null) return; + int state = autopilotStatusInfo.getState(); + if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) { + //2022.7.20 自动驾驶更换成带档位的 +// if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotRunning(); + } else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE) { + if(state != mPreAutoStatus){ + mTwoStationsRouts.clear(); + } +// if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotEnable(); + } else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE) { + if(state != mPreAutoStatus){ + mTwoStationsRouts.clear(); + } +// if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotDisable(); + }else if (state == IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING){ + if(state != mPreAutoStatus){ + mTwoStationsRouts.clear(); + } + } + mPreAutoStatus = state; } @Override diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerBaseFragment.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerBaseFragment.java index 6e69bcc01e..e2b0ac575c 100644 --- a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerBaseFragment.java +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/ui/BusPassengerBaseFragment.java @@ -107,13 +107,13 @@ public abstract class BusPassengerBaseFragment Date: Thu, 4 Aug 2022 14:41:35 +0800 Subject: [PATCH 23/30] =?UTF-8?q?[290=20bus/taxi]bus=E4=B9=98=E5=AE=A2?= =?UTF-8?q?=E5=B1=8F=E5=8E=BB=E9=99=A4=E5=85=A8=E8=A7=88=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../och/bus/passenger/presenter/BaseBusPassengerPresenter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/presenter/BaseBusPassengerPresenter.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/presenter/BaseBusPassengerPresenter.java index e139ae3dff..b855057746 100644 --- a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/presenter/BaseBusPassengerPresenter.java +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/presenter/BaseBusPassengerPresenter.java @@ -82,7 +82,7 @@ public class BaseBusPassengerPresenter extends Presenter Date: Thu, 4 Aug 2022 15:53:44 +0800 Subject: [PATCH 24/30] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E4=B8=8A=E6=8A=A5=E7=9A=84tag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apm/ApmCrashReportProvider.java | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java b/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java index bd6da83424..a1a63fe05c 100644 --- a/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java +++ b/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java @@ -38,6 +38,10 @@ public class ApmCrashReportProvider implements ITestCrashReportProvider { private static final String TAG = "ApmCrashReportProvider"; private static final String MAP_SDK_VERSION = "MAP_SDK_VERSION"; + private CarInfo mInfo = null; + private String mCityCode; + private String mLat; + private String mLogt; @Override public void init(Context context) { @@ -54,27 +58,28 @@ public class ApmCrashReportProvider implements ITestCrashReportProvider { HashMap map = new HashMap<>(); //车辆信息 String carInfoString = SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.CAR_INFO); - CarInfo info = null; + if (carInfoString != null && !carInfoString.isEmpty()) { - info = GsonUtils.fromJson(carInfoString, CarInfo.class); + mInfo = GsonUtils.fromJson(carInfoString, CarInfo.class); } //车辆所在位置 - String cityCode = SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.LOCATION_CITY_CODE); - String lat = SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.LOCATION_LATITUDE); - String logt = SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.LOCATION_LONGITUDE); -// Log.d("liyz", "cityCode = " + cityCode + " --lat = " +lat + " --logt = " + logt); + mCityCode = SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.LOCATION_CITY_CODE); + mLat = SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.LOCATION_LATITUDE); + mLogt = SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.LOCATION_LONGITUDE); + Log.d("liyz", "cityCode = " + mCityCode + " --lat = " +mLat + " --logt = " + mLogt); //地图版本 String mapSDKVersion = AppUtils.getCustomMapSDKVersion(context); map.put("MAP_SDK_VERSION", mapSDKVersion); - if (info != null) { - CallerLogger.INSTANCE.d(TAG, "nuber = " + info.getNumber_plate() + "--brand = " + info.getBrand() + "--modle = " + info.getModel()); - map.put("PLATE_NUMBER", info.getNumber_plate()); - map.put("BRAND", info.getBrand()); - map.put("MODEL", info.getModel()); - map.put("CITYCODE", cityCode); - map.put("LATITUDE", lat); - map.put("LONGITUTE", logt); + map.put("CITYCODE", mCityCode); + map.put("LATITUDE", mLat); + map.put("LONGITUTE", mLogt); + + if (mInfo != null) { + CallerLogger.INSTANCE.d(TAG, "nuber = " + mInfo.getNumber_plate() + "--brand = " + mInfo.getBrand() + "--modle = " + mInfo.getModel()); + map.put("PLATE_NUMBER", mInfo.getNumber_plate()); + map.put("BRAND", mInfo.getBrand()); + map.put("MODEL", mInfo.getModel()); } return map; } @@ -89,6 +94,10 @@ public class ApmCrashReportProvider implements ITestCrashReportProvider { crash.config().setDeviceId(DeviceIdUtils.getDeviceId(context)); } crash.addTags(MAP_SDK_VERSION, mapSDKVersion); + crash.addTags("CITYCODE", mCityCode); + crash.addTags("LATITUDE", mLat); + crash.addTags("LONGITUTE", mLogt); + // crash.setReportUrl("www.xxx.com"); // 私有化部署:私有化部署才配置上报地址 // crash.addTags("key", "value"); // 自定义筛选tag, 按需添加、可多次覆盖 @@ -98,6 +107,15 @@ public class ApmCrashReportProvider implements ITestCrashReportProvider { dimension.put("Devices_SN_WidevineID_MD5", sn + "__" + DeviceIdUtils.getWidevineIDWithMd5(context)); dimension.put("Devices_SN_WidevineID", sn + "__" + DeviceIdUtils.getWidevineID(context)); dimension.put(MAP_SDK_VERSION, mapSDKVersion); + dimension.put("CITYCODE", mCityCode); + dimension.put("LATITUDE", mLat); + dimension.put("LONGITUTE", mLogt); + if (mInfo != null) { + dimension.put("PLATE_NUMBER", mInfo.getNumber_plate()); + dimension.put("BRAND", mInfo.getBrand()); + dimension.put("MODEL", mInfo.getModel()); + } + HashMap metric = new HashMap<>(); //指标值 //metric.put("Devices_ID_metric", (double) 100); From 3c90d7ae6a83b652e5624ee18713eddaec29e3d3 Mon Sep 17 00:00:00 2001 From: lixiaopeng Date: Thu, 4 Aug 2022 16:43:19 +0800 Subject: [PATCH 25/30] =?UTF-8?q?=E6=B3=A8=E9=87=8A=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mogo/test/crashreport/apm/ApmCrashReportProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java b/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java index a1a63fe05c..c905cf456b 100644 --- a/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java +++ b/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java @@ -67,7 +67,7 @@ public class ApmCrashReportProvider implements ITestCrashReportProvider { mCityCode = SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.LOCATION_CITY_CODE); mLat = SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.LOCATION_LATITUDE); mLogt = SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.LOCATION_LONGITUDE); - Log.d("liyz", "cityCode = " + mCityCode + " --lat = " +mLat + " --logt = " + mLogt); +// Log.d("liyz", "cityCode = " + mCityCode + " --lat = " +mLat + " --logt = " + mLogt); //地图版本 String mapSDKVersion = AppUtils.getCustomMapSDKVersion(context); map.put("MAP_SDK_VERSION", mapSDKVersion); From 076a9fbccb34abbfef72d00cee46602020ed42c8 Mon Sep 17 00:00:00 2001 From: wangmingjun Date: Thu, 4 Aug 2022 16:56:40 +0800 Subject: [PATCH 26/30] =?UTF-8?q?[290=20bus/taxi]bus=E5=8F=B8=E6=9C=BA?= =?UTF-8?q?=E7=AB=AF=E5=9F=8B=E7=82=B9=EF=BC=8C=20bus=E4=B9=98=E5=AE=A2?= =?UTF-8?q?=E5=B1=8F=E8=BD=A8=E8=BF=B9=E8=B7=AF=E7=BA=BF=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mogo/och/bus/passenger/model/BusPassengerModel.java | 2 +- .../src/main/java/com/mogo/och/bus/model/BusOrderModel.java | 2 -- .../src/main/java/com/mogo/och/bus/presenter/BusPresenter.java | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java index f28068397c..64830672fe 100644 --- a/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java +++ b/OCH/mogo-och-bus-passenger/src/main/java/com/mogo/och/bus/passenger/model/BusPassengerModel.java @@ -157,8 +157,8 @@ public class BusPassengerModel { BusPassengerStation station = stations.get(i); if (station.getDrivingStatus() == STATION_STATUS_STOPPED && station.isLeaving() && i+1 < stations.size()){ mRouteLineInfoCallback.updateStationsInfo(stations,i+1,false); - mTwoStationsRouts.clear(); if(mNextStationIndex != i+1){ + mTwoStationsRouts.clear(); startRemainRouteInfo(); } mNextStationIndex = i+1; diff --git a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/model/BusOrderModel.java b/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/model/BusOrderModel.java index bd63e699c0..d505f30b43 100644 --- a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/model/BusOrderModel.java +++ b/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/model/BusOrderModel.java @@ -573,8 +573,6 @@ public class BusOrderModel { +" startLatLon="+currentStation.getName()+",endLatLon="+nextStation.getName()); CallerAutoPilotManager.INSTANCE.startAutoPilot(parameters); - triggerStartServiceEvent(isRestart, false); - if (mControllerStatusCallback != null) { mControllerStatusCallback.startOpenAutopilot(); } diff --git a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/presenter/BusPresenter.java b/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/presenter/BusPresenter.java index fadc4ad8d1..f963a3aec7 100644 --- a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/presenter/BusPresenter.java +++ b/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/presenter/BusPresenter.java @@ -247,6 +247,7 @@ public class BusPresenter extends Presenter @Override public void startOpenAutopilot() { //非美化模式下启动动画 + BusOrderModel.getInstance().triggerStartServiceEvent(isRestartAutopilot, false); runOnUIThread(() -> mView.startAutopilotAnimation()); } From 90f3fce68e1be250bd6a71afa97196c9528bd301 Mon Sep 17 00:00:00 2001 From: chenfufeng Date: Thu, 4 Aug 2022 17:55:33 +0800 Subject: [PATCH 27/30] =?UTF-8?q?[Update]=E5=90=8C=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E7=BB=98=E5=88=B6=E5=92=8C=E6=93=A6=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/function/smp/AMapCustomView.java | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) 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 96aca1cc99..e72ef33969 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 @@ -41,6 +41,7 @@ import com.mogo.eagle.core.function.map.R; import com.mogo.eagle.core.function.overview.InfStructureManager; import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils; import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils; +import com.mogo.eagle.core.utilcode.util.UiThreadHandler; import org.jetbrains.annotations.NotNull; @@ -232,18 +233,22 @@ public class AMapCustomView // 转成高德坐标系并存储 MarkerDrawerManager.INSTANCE.updateRoutePoints(list, mContext); List planningPointList = MarkerDrawerManager.INSTANCE.getPlanningPoints(); - displayCustomOverView(); - drawStartAndEndMarker(planningPointList); + UiThreadHandler.post(() -> { + displayCustomOverView(); + drawStartAndEndMarker(planningPointList); + }); MarkerDrawerManager.INSTANCE.setCallback((points, locIndex) -> { // 每1s刷新一下轨迹线 - if (points.size() > 0) { - drawPolyline(points, locIndex); - } else { - clearCustomPolyline(); - } + UiThreadHandler.post(() -> { + if (points.size() > 0) { + drawPolyline(points, locIndex); + } + }); }); MarkerDrawerManager.INSTANCE.startLoopCalCarLocation(); - drawInfrastructureMarkers(locationList); + UiThreadHandler.post(() -> { + drawInfrastructureMarkers(locationList); + }); } @Override @@ -264,11 +269,13 @@ public class AMapCustomView public void onLocationChanged(@org.jetbrains.annotations.Nullable MogoLocation location, int from) { mLocation = location; MarkerDrawerManager.INSTANCE.setLonLat(new Pair(location.getLongitude(), location.getLatitude())); - drawCarMarker(location); - if (isFirstLocation) { - displayCustomOverView(); - isFirstLocation = false; - } + UiThreadHandler.post(() -> { + drawCarMarker(location); + if (isFirstLocation) { + displayCustomOverView(); + isFirstLocation = false; + } + }); } public void onCreateView(Bundle savedInstanceState) { From 4faeedcaeafa7139565edf9c9da53c9d5f1627d4 Mon Sep 17 00:00:00 2001 From: renwj Date: Thu, 4 Aug 2022 19:40:03 +0800 Subject: [PATCH 28/30] =?UTF-8?q?[RouteOpt]=E7=A7=BB=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../routeoverlay/RouteOverlayDrawer.java | 61 ++----------------- 1 file changed, 4 insertions(+), 57 deletions(-) diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/RouteOverlayDrawer.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/RouteOverlayDrawer.java index beeee2598d..edbc9c3057 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/RouteOverlayDrawer.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/RouteOverlayDrawer.java @@ -1,14 +1,12 @@ package com.mogo.module.service.routeoverlay; import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_OLD_ROUTE; - import android.annotation.SuppressLint; import android.graphics.Color; import android.os.Handler; import android.os.HandlerThread; import android.os.SystemClock; import android.util.Log; - import androidx.core.util.Pools; import com.mogo.eagle.core.data.map.MogoLatLng; import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager; @@ -19,7 +17,6 @@ import com.mogo.map.overlay.IMogoOverlayManager; import com.mogo.map.overlay.IMogoPolyline; import com.mogo.map.overlay.MogoPolylineOptions; import com.mogo.module.common.utils.DrivingDirectionUtils; - import java.util.LinkedList; import java.util.List; import mogo.telematics.pad.MessagePad; @@ -29,33 +26,18 @@ public class RouteOverlayDrawer { private static final String TAG = "MogoRouteOverlayManager"; // 连接线参数 - private Handler mRenderHandler; IMogoOverlayManager mogoOverlayManager; private static volatile RouteOverlayDrawer sInstance; private final MogoPolylineOptions mPolylineOptions; private volatile IMogoPolyline mMoGoPolyline; - // private FileWriter writer; + private static final int COLOR_LIGHT = Color.parseColor("#BAEBF5"); + private RouteOverlayDrawer() { mPolylineOptions = new MogoPolylineOptions(); mPolylineOptions.zIndex(75000f); mPolylineOptions.setGps(true); mPolylineOptions.width(20).useGradient(true); -// try { -// File log = new File(Environment.getExternalStorageDirectory(), "log.txt"); -// if (log.exists()) { -// log.delete(); -// } -// if (log.getParentFile() != null && !log.getParentFile().exists()) { -// log.getParentFile().mkdirs(); -// } -// -// log.createNewFile(); -// writer = new FileWriter(log, false); -// } catch (Throwable t) { -// -// } - // 渐变色 mogoOverlayManager = MogoOverlayManager.getInstance(); // 线条粗细,渐变,渐变色值 @@ -191,48 +173,13 @@ public class RouteOverlayDrawer { RouteStrategy.INSTANCE.end(); Strategy strategy = RouteStrategy.INSTANCE.getStrategy(); List colors = strategy.getColors(); -// StringBuilder sb = new StringBuilder(); -// int colorIndex = 0; -// sb.append("=========================================\n"); -// for (MogoLatLng p : points) { -// sb.append(p.lat); -// sb.append(","); -// sb.append(p.lon); -// sb.append(","); -// sb.append(p.acc); -// sb.append(","); -// sb.append(p.speed); -// if (colorIndex < colors.size()) { -// int color = colors.get(colorIndex); -// sb.append(","); -// sb.append(color); -// sb.append(","); -// sb.append(Color.red(color)); -// sb.append(","); -// sb.append(Color.green(color)); -// sb.append(","); -// sb.append(Color.blue(color)); -// sb.append(","); -// sb.append(Color.alpha(color)); -// colorIndex ++; -// } -// sb.append("\n"); -// } -// try { -// if (writer != null) { -// writer.write(sb.toString()); -// writer.flush(); -// } -// } catch (Throwable t) { -// -// } boolean isLightOn = strategy instanceof ColorfulStrategy && ((ColorfulStrategy) strategy).isLightOn(); if (mMoGoPolyline == null || mMoGoPolyline.isDestroyed()) { mPolylineOptions.points(points); mPolylineOptions.colorValues(colors); if (isLightOn) { mPolylineOptions.openBright(true); - mPolylineOptions.brightColor(Color.parseColor("#D2F2F8")); + mPolylineOptions.brightColor(COLOR_LIGHT); mPolylineOptions.brightSpeed(0.5f); } else { mPolylineOptions.openBright(false); @@ -243,7 +190,7 @@ public class RouteOverlayDrawer { mPolylineOptions.colorValues(colors); if (isLightOn) { mPolylineOptions.openBright(true); - mPolylineOptions.brightColor(Color.parseColor("#D2F2F8")); + mPolylineOptions.brightColor(COLOR_LIGHT); mPolylineOptions.brightSpeed(0.5f); } else { mPolylineOptions.openBright(false); From 1ca70491a75dd860184fc54796c0b388da69372d Mon Sep 17 00:00:00 2001 From: wangmingjun Date: Thu, 4 Aug 2022 20:43:46 +0800 Subject: [PATCH 29/30] =?UTF-8?q?[290=20bus/taxi]bus=E5=8F=B8=E6=9C=BA?= =?UTF-8?q?=E7=AB=AF=E5=9F=8B=E7=82=B9=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/mogo/och/bus/model/BusOrderModel.java | 5 +++-- .../main/java/com/mogo/och/bus/presenter/BusPresenter.java | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/model/BusOrderModel.java b/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/model/BusOrderModel.java index d505f30b43..d98bdd536a 100644 --- a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/model/BusOrderModel.java +++ b/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/model/BusOrderModel.java @@ -539,8 +539,9 @@ public class BusOrderModel { */ private void startAutopilot(boolean isRestart) { - isArrivedStation = false; + triggerStartServiceEvent(isRestart, false); + isArrivedStation = false; BusStationBean currentStation = stationList.get( backgroundCurrentStationIndex); BusStationBean nextStation = stationList.get( backgroundCurrentStationIndex + 1); @@ -988,7 +989,7 @@ public class BusOrderModel { } public void triggerStartServiceEvent(boolean isRestart, boolean send) { - if (stationList == null || backgroundCurrentStationIndex >= stationList.size() || backgroundCurrentStationIndex == 0) { + if (stationList == null || backgroundCurrentStationIndex >= stationList.size()-1) { return; } BusStationBean currentStation = stationList.get( backgroundCurrentStationIndex); diff --git a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/presenter/BusPresenter.java b/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/presenter/BusPresenter.java index f963a3aec7..fadc4ad8d1 100644 --- a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/presenter/BusPresenter.java +++ b/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/presenter/BusPresenter.java @@ -247,7 +247,6 @@ public class BusPresenter extends Presenter @Override public void startOpenAutopilot() { //非美化模式下启动动画 - BusOrderModel.getInstance().triggerStartServiceEvent(isRestartAutopilot, false); runOnUIThread(() -> mView.startAutopilotAnimation()); } From 049824d0d67da29d2c00460ac7fe1aa5e5065ecb Mon Sep 17 00:00:00 2001 From: xinfengkun Date: Fri, 5 Aug 2022 14:47:21 +0800 Subject: [PATCH 30/30] =?UTF-8?q?[change]=20=E6=9B=B4=E6=96=B0260=E7=9B=91?= =?UTF-8?q?=E6=8E=A7=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/zhidao/support/adas/high/common/MogoReport.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MogoReport.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MogoReport.java index 196ababf63..dd8a4a6737 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MogoReport.java +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MogoReport.java @@ -2,8 +2,7 @@ package com.zhidao.support.adas.high.common; /** * 监控事件报告中定义的事件以及解释 - * 根据250消息定义编写 - * http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=79433139 + * 根据260消息定义编写 */ public class MogoReport { private static final String RESULT_AUTOPILOT_SYSTEM_UNSTARTED = "RESULT_AUTOPILOT_SYSTEM_UNSTARTED"; @@ -223,7 +222,7 @@ public class MogoReport { String AUTOPILOT_FAILED = "ESYS_AUTOPILOT_FAILED";//在尝试启动自动驾驶,但是超过指定时间后底盘未进入,会发送此事件 @Deprecated String IN_INIT = "ESYS_IN_INIT";//系统处于启动中,拒绝进入自动驾驶/远程驾驶 - String IN_EXIT = "ESYS_IN_EXIT";//系统处于退出中,拒绝进入自动驾驶/远程驾驶 + String IN_EXIT = "ESYS_IN_EXIT";//系统处于退出中,拒绝进入自动驾驶 String NOT_ALLOW_AUTOPILOT_FOR_REMOTE = "ESYS_NOT_ALLOW_AUTOPILOT_FOR_REMOTE";//系统处于远程驾驶中,拒绝进入自动驾驶 String NOT_ALLOW_REBOOT = "ESYS_NOT_ALLOW_REBOOT";//重启拒绝 String TOPIC_FREQ_DROPED = "ESYS_TOPIC_FREQ_DROPED";//存在topic严重掉频 @@ -232,6 +231,7 @@ public class MogoReport { String AUTOPILOT_TAKEN_OVER_BY_REMOTE = "ESYS_AUTOPILOT_TAKEN_OVER_BY_REMOTE";//自动驾驶被远程驾驶接管 String ROUTING_REQ_TIMEOUT = "ESYS_ROUTING_REQ_TIMEOUT";//自动驾驶开始前,routing请求无响应 String PLANNING_CHANGE_FAILIED = "ESYS_PLANNING_CHANGE_FAILIED";//planning版本切换启动失败 + String CHECK_TRAJECTORY_FAILURE = "ESYS_CHECK_TRAJECTORY_FAILURE";//轨迹文件检查超时或检查结果无可用轨迹 String FAULT = "ESYS_FAULT";//master启动10分钟,仍有agent未连接 } @@ -331,6 +331,7 @@ public class MogoReport { interface ILCT { String RTK_STATUS_NORMAL = "ILCT_RTK_STATUS_NORMAL";//rtk状态正常或恢复正常 + String RTK_OR_SLAM_CHANGE = "ILCT_RTK_OR_SLAM_CHANGE";//定位输出源发生RTK和SLAM变换 } } }