diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt index d1e6d0c4e1..6d5d33f765 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt @@ -64,6 +64,8 @@ import com.mogo.eagle.core.utilcode.util.* import com.mogo.map.MogoMap import com.mogo.map.uicontroller.VisualAngleMode import com.mogo.map.uicontroller.VisualAngleMode.* +import com.mogo.module.service.routeoverlay.* +import com.tencent.liteav.basic.datareport.a.B import com.zhidao.easysocket.utils.L import kotlinx.android.synthetic.main.view_debug_setting.view.* import mogo.telematics.pad.MessagePad @@ -965,6 +967,16 @@ class DebugSettingView @JvmOverloads constructor( accelerationIsShow = isChecked } + tbRouteDynamicEffect.isChecked = AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode) + + tbRouteDynamicEffect.setOnCheckedChangeListener { _, isChecked -> + if (isChecked) { + RouteStrategy.enable(true) + } else { + RouteStrategy.enable(false) + } + } + btnThresholdDefine.setOnClickListener { try { accelerationThresholdNum = etThreshold.text.toString().toDouble() diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml index a92f6810e7..41e399344a 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml @@ -1257,6 +1257,17 @@ android:textOn="关闭「加速度面板」" android:textSize="@dimen/dp_24" /> + + mTrajectoryList = null; + private List mTrajectoryList = null; - private MogoRouteOverlayManager(Context context) { - mContext = context; - } + private final Lock mLock = new ReentrantLock(); + + private MogoRouteOverlayManager() {} public void init() { CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, this); CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, this); CallerMapLocationListenerManager.INSTANCE.addListener(TAG, this); -// intiDrawer(); } - public static MogoRouteOverlayManager getInstance(Context context) { + public static MogoRouteOverlayManager getInstance() { if (sInstance == null) { synchronized (MogoRouteOverlayManager.class) { if (sInstance == null) { - sInstance = new MogoRouteOverlayManager(context); + sInstance = new MogoRouteOverlayManager(); } } } return sInstance; } - private StringBuilder trajectoryMsg = null; - @Override public void onAutopilotTrajectory(@NonNull List items) { - long start = SystemClock.elapsedRealtime(); + if (isArriveAtStation.get()) { + return; + } + if (items.isEmpty()) { + return; + } + MogoLocation location = mLocation; + if (location == null) { + return; + } try { - if (isArriveAtStation.get()) { - return; - } - if (items.size() == 0) { - return; - } - MogoLocation location = mLocation; - if (location == null) { - return; - } + mLock.lock(); mTrajectoryList = items; - Map tags = CallerDevaToolsManager.INSTANCE.getModuleTAG(); - boolean isPrintLog = false; - if (tags != null && tags.containsKey(SceneConstant.M_OLD_ROUTE)) { - SceneModule scene = tags.get(M_OLD_ROUTE); - isPrintLog = scene.getLog(); - } - if (isPrintLog) { - if (trajectoryMsg == null) { - trajectoryMsg = new StringBuilder(128); - } - if (trajectoryMsg.length() > 0) { - trajectoryMsg.setLength(0); - } - trajectoryMsg.append("{"); - trajectoryMsg.append(System.currentTimeMillis()).append(";"); - trajectoryMsg.append(location.getLongitude()).append(";"); - trajectoryMsg.append(location.getLatitude()).append(";"); - trajectoryMsg.append(location.getAltitude()).append(";"); - trajectoryMsg.append(location.getBearing()).append(";"); - trajectoryMsg.append(location.getSpeed()).append(";"); - for (int i = 0; i < items.size(); i++) { - // 临时解决车尾拖线问题,丢弃距离车最近的几个经纬度,原因是惯性导航的中心靠近车尾,会导致经纬度靠近尾部,且两个数据不同频 - MessagePad.TrajectoryPoint a = items.get(i); - double lon = a.getLongitude(); - double lat = a.getLatitude(); - trajectoryMsg.append(lon).append(","); - trajectoryMsg.append(lat).append(","); - } - trajectoryMsg.append("}"); - CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG, "receive router data:" + items.size()); - CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG, trajectoryMsg.toString()); - } else { - CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG, "receive router data:" + items.size()); - } } finally { - CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG, "--- onAutopilotTrajectory -- cost:" + (SystemClock.elapsedRealtime() - start) + " ms"); + mLock.unlock(); } } @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())); -// } -// int listSize = latLngList.size(); -// mEnding = latLngList.get(listSize - 1); -// RouteOverlayDrawer.getInstance(mContext).addEndingMarker(latLngList.get(listSize - 1).lat,latLngList.get(listSize - 1).lon); - } + public void onAutopilotRotting(MessagePad.GlobalPathResp globalPathResp) {} @Override @@ -144,34 +90,20 @@ public class MogoRouteOverlayManager implements if (this.STATUS_AUTOPILOT == 1) { isArriveAtStation.set(false); } - //CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG ,"onAutopilotStatusResponse:"+STATUS_AUTOPILOT); -// if (STATUS_AUTOPILOT == 1 ){ -// if (mEnding != null){ -// RouteOverlayDrawer.getInstance(mContext).addEndingMarker(mEnding.lat,mEnding.lon); -// } -// }else { -// -// } if (STATUS_AUTOPILOT != 1) { - RouteOverlayDrawer.getInstance(mContext).clearEndingMarker(); - RouteOverlayDrawer.getInstance(mContext).clearMogoRouteOverlay(); + RouteOverlayDrawer.getInstance().clearMogoRouteOverlay(); } } @Override public void onAutopilotArriveAtStation(MessagePad.ArrivalNotification arrivalNotification) { - if (arrivalNotification == null) { return; } - CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG, "onArriveAt data : " + arrivalNotification); -// //演示模式下 到达终点将忽略 引导线绘制 选项关闭 -// FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = false; - + Log.d(TAG, "onArriveAt data : " + arrivalNotification); if (!isArriveAtStation.get()) { isArriveAtStation.set(true); - RouteOverlayDrawer.getInstance(mContext).clearEndingMarker(); - RouteOverlayDrawer.getInstance(mContext).clearMogoRouteOverlay(); + RouteOverlayDrawer.getInstance().clearMogoRouteOverlay(); } } @@ -186,7 +118,6 @@ public class MogoRouteOverlayManager implements if (from != 1) { return; } - long start = SystemClock.elapsedRealtime(); boolean isExcept = false; try { if (location == null) { @@ -194,14 +125,13 @@ public class MogoRouteOverlayManager implements return; } if (FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData || STATUS_AUTOPILOT == 1) { - RouteOverlayDrawer.getInstance(mContext).drawTrajectoryList(location, mTrajectoryList); + RouteOverlayDrawer.getInstance().drawTrajectoryList(mLock, location, mTrajectoryList); } } finally { mLocation = location; if (isExcept) { - RouteOverlayDrawer.getInstance(mContext).setVisible(false); + RouteOverlayDrawer.getInstance().hide(); } -// CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG, "--- onLocationChanged -- cost:" + (SystemClock.elapsedRealtime() - start) + " ms"); } } 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 f3d145dcd8..df77438030 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,70 +1,42 @@ 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.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -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.data.map.MogoLocation; import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager; -import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; -import com.mogo.eagle.core.utilcode.util.ColorUtils; -import com.mogo.map.MogoMarkerManager; import com.mogo.map.MogoOverlayManager; -import com.mogo.map.marker.IMogoMarker; -import com.mogo.map.marker.MogoMarkerOptions; 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 com.mogo.module.service.R; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import java.util.concurrent.locks.Lock; import mogo.telematics.pad.MessagePad; public class RouteOverlayDrawer { private static final String TAG = "MogoRouteOverlayManager"; - private volatile IMogoPolyline mMoGoPolyline; // 连接线参数 - private final MogoPolylineOptions mPolylineOptions; private Handler mRenderHandler; - private final Bitmap endingBitmap; - private final Context mContext; +// private Handler mLogHandler; + IMogoOverlayManager mogoOverlayManager; - private IMogoMarker endMarker; - private MogoMarkerOptions markerOptions; private static volatile RouteOverlayDrawer sInstance; - private static final String markerType = "route_ending"; - private RouteOverlayDrawer(Context context) { - mPolylineOptions = new MogoPolylineOptions(); - mPolylineOptions.zIndex(75000f); - mPolylineOptions.setGps(true); - // 引导线颜色, + private RouteOverlayDrawer() { // 渐变色 - mContext = context; mogoOverlayManager = MogoOverlayManager.getInstance(); - endingBitmap = BitmapFactory.decodeResource(context.getResources(), - R.drawable.icon_route_ending); - - List list = new ArrayList<>(); - int[] startColor = ColorUtils.hexToArgb("#CC64C3EA"); - int[] endColor = ColorUtils.hexToArgb("#0064C3EA"); - list.add(Color.argb(startColor[0], startColor[1], startColor[2], startColor[3])); - list.add(Color.argb(endColor[0], endColor[1], endColor[2], endColor[3])); // 线条粗细,渐变,渐变色值 - mPolylineOptions.width(20).useGradient(true).colorValues(list); HandlerThread renderTask = new HandlerThread("routing_render") { @Override protected void onLooperPrepared() { @@ -73,153 +45,307 @@ public class RouteOverlayDrawer { } }; renderTask.start(); + +// HandlerThread logHandler = new HandlerThread("log_handler") { +// @Override +// protected void onLooperPrepared() { +// super.onLooperPrepared(); +// mLogHandler = new Handler(getLooper()); +// } +// }; +// logHandler.start(); } - public static RouteOverlayDrawer getInstance(Context context) { + public static RouteOverlayDrawer getInstance() { if (sInstance == null) { synchronized (RouteOverlayDrawer.class) { if (sInstance == null) { - sInstance = new RouteOverlayDrawer(context); + sInstance = new RouteOverlayDrawer(); } } } return sInstance; } - public synchronized void release() { - sInstance = null; - } - - private Object readResolve() { - // 阻止反序列化,必须实现 Serializable 接口 - return sInstance; - } - - public void addEndingMarker(double lat, double lon) { - if (endMarker != null) { - return; - } - if (markerOptions == null) { - markerOptions = new MogoMarkerOptions() - .matchOnRoadSide(true) - .gps(true) - .icon(endingBitmap) - .owner(markerType) - .anchor(0.5f, 0.5f) - .scale(0.5f) - .zIndex(30001); -// .object(markerShowEntity) - } - markerOptions.latitude(lat).longitude(lon); - //CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG,"addEndingMarker-"+lat+":"+lon); - endMarker = MogoMarkerManager.getInstance(mContext).addMarker(markerType, markerOptions); -// if (DebugConfig.isDebug()){ -// ToastUtils.showLong("绘制终点marker,"+lat+":"+lon); -// } - } - public void clearMogoRouteOverlay() { - if (mMoGoPolyline != null) { - mMoGoPolyline.remove(); - mMoGoPolyline = null; - } - - if (mRenderTask != null) { + if (mRenderTask != null && mRenderHandler != null) { + mRenderTask.remove(); mRenderHandler.removeCallbacks(mRenderTask); } } - public void clearEndingMarker() { - //CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG,"clearEndingMarker"); - endMarker = null; - MogoMarkerManager.getInstance(mContext).removeMarkers(markerType); + public void remove() { + if (mRenderTask != null && mRenderHandler != null) { + mRenderTask.remove(); + mRenderHandler.removeCallbacks(mRenderTask); + } + } + + public void hide() { + if (mRenderTask != null && mRenderHandler != null) { + mRenderTask.hide(); + mRenderHandler.removeCallbacks(mRenderTask); + } + } + + private static class RenderOptions { + + private IMogoPolyline mPolyLine; + private final MogoPolylineOptions mOptions; + + private static int taskSequence = 0; + + //private Handler mHandler; + + private final IMogoOverlayManager mOverlayManager; + + //private ChildRenderTask mTask; + + private class ChildRenderTask implements Runnable { + + private List colors; + private List points; + + public void setData(List colors, List points) { + this.colors = colors; + this.points = points; + } + + @Override + public void run() { + if (this.colors == null || this.colors.isEmpty()) { + return; + } + + if (this.points == null || this.points.isEmpty()) { + return; + } + mOptions.colorValues(colors); + mOptions.points(points); + if (mPolyLine == null || mPolyLine.isDestroyed()) { + mPolyLine = mOverlayManager.addPolyline(mOptions); + } else { + mPolyLine.setOption(mOptions); + } + if (mPolyLine != null && !mPolyLine.isVisible()) { + mPolyLine.setVisible(true); + } + } + } + + public RenderOptions(IMogoOverlayManager overlay) { + mOverlayManager = overlay; + mOptions = new MogoPolylineOptions().width(20).useGradient(true).zIndex(75000f).setGps(true); +// new HandlerThread("child-render-" +(taskSequence++)) { +// @Override +// protected void onLooperPrepared() { +// super.onLooperPrepared(); +// mHandler = new Handler(getLooper()); +// } +// }.start(); + } + + public void show(List colors, List points) { +// if (mTask == null) { +// mTask = new ChildRenderTask(); +// } +// mTask.setData(colors, points); +// if (mHandler != null) { +// mHandler.removeCallbacks(mTask); +// mHandler.post(mTask); +// } + mOptions.colorValues(colors); + mOptions.points(points); + if (mPolyLine == null || mPolyLine.isDestroyed()) { + mPolyLine = mOverlayManager.addPolyline(mOptions); + } else { + mPolyLine.setOption(mOptions); + } + if (mPolyLine != null && !mPolyLine.isVisible()) { + mPolyLine.setVisible(true); + } + } + + public void hide() { +// if (mTask != null && mHandler != null) { +// mHandler.removeCallbacks(mTask); +// } + if (mPolyLine != null && mPolyLine.isVisible()) { + mPolyLine.setVisible(false); + } + } + + public void remove() { +// if (mTask != null && mHandler != null) { +// mHandler.removeCallbacks(mTask); +// } + if (mPolyLine != null && !mPolyLine.isDestroyed()) { + mPolyLine.remove(); + mPolyLine = null; + } + } } private class RenderTask implements Runnable { - private volatile List routeList; - private volatile MogoLocation location; + private List routeList; + private MogoLocation location; private final Pools.Pool pools; private final LinkedList points; + private final Pools.Pool options; + private Lock mLock; + public RenderTask() { this.pools = new Pools.SimplePool<>(500); this.points = new LinkedList<>(); + this.options = new Pools.SimplePool<>(5); } - public void setData(MogoLocation location, List routeList) { + public void setData(Lock lock, MogoLocation location, List routeList) { this.location = location; this.routeList = routeList; + this.mLock = lock; } @SuppressLint("LongLogTag") @Override public void run() { - LinkedList points = this.points; - points.clear(); + Lock lock = this.mLock; + if (lock == null) { + return; + } + LinkedList pps = this.points; boolean isExcept = false; +// StringBuilder sb; + int total; try { + pps.clear(); long drawStart = SystemClock.elapsedRealtime(); - List routes = this.routeList; - int total; - if (routes == null || (total = routes.size()) < 2) { - isExcept = true; - return; - } - for (int i = 0; i < total; i++) { - MessagePad.TrajectoryPoint route = null; - try { - route = routes.get(i); - if (route == null) { - continue; + try { + lock.lock(); + List routes = this.routeList; + if (routes == null || (total = routes.size()) < 2) { + isExcept = true; + return; + } + RouteStrategy.INSTANCE.start(); +// sb = new StringBuilder(); +// sb.append(System.currentTimeMillis()).append(" "); + for (int i = 0; i < total; i++) { + MessagePad.TrajectoryPoint route = null; + try { + route = routes.get(i); + if (route == null) { + continue; + } + } catch (Throwable t) { + Log.d("Route", "render-error:" + t.getMessage()); } - } catch (Throwable t) { - CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG, "render-error:" + t.getMessage()); + if (route == null) { + //数组越界了,结束循环 + break; + } + +// sb.append(route.getVelocity()).append(" "); +// sb.append(route.getAcceleration()).append(" "); +// sb.append(route.getAccumulatedDis()).append(" "); + MogoLatLng acquire = pools.acquire(); + double latitude = route.getLatitude(); + double longitude = route.getLongitude(); + if (acquire == null) { + acquire = new MogoLatLng(latitude, longitude); + } else { + acquire.lon = longitude; + acquire.lat = latitude; + } + pps.add(acquire); + RouteStrategy.INSTANCE.check(route.getVelocity(), route.getAcceleration()); } - if (route == null) { - //数组越界了,结束循环 - break; + RouteStrategy.INSTANCE.end(); + } finally { + lock.unlock(); + } + Strategy strategy = RouteStrategy.INSTANCE.getStrategy(); + /// Log.d("ROUTE_XX", "strategy:" + strategy + "->route: " +sb); + +// StringBuilder newSb = new StringBuilder("strategy:" + strategy + "->route: "); +// newSb.append(sb); +// if (mLogHandler != null) { +// mLogHandler.sendMessage(Message.obtain(mLogHandler, () -> { +// BufferedWriter bw = null; +// try { +// File file = new File(Environment.getExternalStorageDirectory(), "log.txt"); +// if (!file.exists()) { +// file.createNewFile(); +// } +// bw = new BufferedWriter(new FileWriter(file, true)); +// bw.write(newSb.toString()); +// bw.newLine(); +// bw.flush(); +// } catch (Throwable t) { +// try { +// if (bw != null) { +// bw.close(); +// } +// } catch (Throwable t2) { +// +// } +// } +// })); +// } + Integer[] indexes = strategy.getIndexes(); + Integer[] colors = strategy.getColors(); + LinkedList> parts = new LinkedList<>(); + if (indexes.length > 0) { + for (int i = 0; i < indexes.length; i += 2) { + int startIndex = indexes[i]; + int endIndex = indexes[i + 1]; + parts.add(new LinkedList<>(pps.subList(startIndex, Math.min(endIndex + 1, pps.size())))); } - MogoLatLng acquire = pools.acquire(); - double latitude = route.getLatitude(); - double longitude = route.getLongitude(); - if (acquire == null) { - acquire = new MogoLatLng(latitude, longitude); - } else { - acquire.lon = longitude; - acquire.lat = latitude; - } - points.add(acquire); } double lon = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lon(); double lat = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lat(); int removeCount = 0; - if (points.size() > 0) { - MogoLatLng top = null; - while (points.size() != 0) { - MogoLatLng first = points.peek(); - if (first == null) { + int colorsIndex = 0; + if (!parts.isEmpty()) { + L:while (!parts.isEmpty()) { + LinkedList part = parts.peek(); + if (part == null) { continue; } - if (first == top) { - break; + MogoLatLng top = null; + while (!part.isEmpty()) { + MogoLatLng first = part.peek(); + if (first == null) { + part.poll(); + continue; + } + if (first == top) { + break L; + } + lon = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lon(); + lat = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lat(); + long angle = isPointOnCarFront(lon, lat, location.getBearing(), first.lon, first.lat); + if (angle >= 90) { + removeCount++; + pps.remove(first); + try { + pools.release(first); + } catch (Throwable ignore) { + } finally { + part.poll(); + } + } + top = first; } - lon = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lon(); - lat = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lat(); - long angle = isPointOnCarFront(lon, lat, location.getBearing(), first.lon, first.lat); - if (angle >= 90) { - removeCount++; - pools.release(first); - points.poll(); - } - top = first; + parts.poll(); + colorsIndex += 2; } - - if (points.size() == 0) { + if (parts.isEmpty()) { isExcept = true; return; } - MogoLatLng self = pools.acquire(); if (self == null) { self = new MogoLatLng(lat, lon); @@ -227,70 +353,102 @@ public class RouteOverlayDrawer { self.lat = lat; self.lon = lon; } - points.addFirst(self); - if (mMoGoPolyline == null || mMoGoPolyline.isDestroyed()) { - mPolylineOptions.points(points); - mMoGoPolyline = mogoOverlayManager.addPolyline(mPolylineOptions); - } else { - mPolylineOptions.points(points); - mMoGoPolyline.setOption(mPolylineOptions); + pps.addFirst(self); + parts.get(0).addFirst(self); + List ll = new ArrayList<>(); + for (int i = 0; i < parts.size(); i++) { + LinkedList ps = parts.get(i); + RenderOptions options = this.options.acquire(); + if (options == null) { + options = new RenderOptions(mogoOverlayManager); + } + ll.add(options); + List cls = new ArrayList<>(); + cls.add(colors[colorsIndex++]); + cls.add(colors[colorsIndex++]); + options.show(cls, ps); } - if (mMoGoPolyline != null && !mMoGoPolyline.isDestroyed() && !mMoGoPolyline.isVisible()) { - mMoGoPolyline.setVisible(true); + hide(); + for (int i = ll.size() - 1; i >= 0 ; i--) { + this.options.release(ll.get(i)); } } else { isExcept = true; } long drawEnd = SystemClock.elapsedRealtime(); - CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG, "drawTrajectoryList cost : " + (drawEnd - drawStart) + "ms and isExcept:" + isExcept + "::removeCount:" + removeCount + "::total:" + total); + Log.d("Route", "draw cost:" + (drawEnd - drawStart) + "ms and isExcept:" + isExcept + "::removeCount:" + removeCount + "::total:" + total); } catch (Throwable t) { - CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG, "drawTrajectoryList error (isExcept: "+isExcept+") : " + t); + Log.d("Route","error:" + Log.getStackTraceString(t)); } finally { - if (isExcept) { - setVisible(false); - } - if (points.size() > 0) { - for (int i = 0; i < points.size(); i++) { - MogoLatLng latLng = points.get(i); - if (latLng == null) { - continue; - } - pools.release(latLng); + try { + if (isExcept) { + hide(); } + if (!pps.isEmpty()) { + for (int i = 0; i < pps.size(); i++) { + MogoLatLng latLng = pps.get(i); + if (latLng == null) { + continue; + } + pools.release(latLng); + } + } + } catch (Throwable t) { + Log.d("Route", "error2:" + Log.getStackTraceString(t)); } } } + private void hide() { + List list = new ArrayList<>(); + RenderOptions acquire = this.options.acquire(); + while (acquire != null) { + acquire.hide(); + list.add(acquire); + acquire = this.options.acquire(); + } + for (int i = 0; i < list.size(); i++) { + this.options.release(list.get(i)); + } + } + + public void remove() { + List list = new ArrayList<>(); + RenderOptions acquire = this.options.acquire(); + while (acquire != null) { + acquire.remove(); + list.add(acquire); + acquire = this.options.acquire(); + } + for (int i = 0; i < list.size(); i++) { + this.options.release(list.get(i)); + } + } + private long isPointOnCarFront(double car_lon, double car_lat, double car_head, double lon, double lat) { long start = SystemClock.elapsedRealtime(); try { // 计算车辆与点之间的夹角 long diffAngle = DrivingDirectionUtils.getDegreeOfCar2Poi2( car_lon, car_lat, lon, lat, car_head); - CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG, "isPointOnCarFront: angle->" + diffAngle); + Log.d("Route", "isPointOnCarFront: angle->" + diffAngle); return diffAngle; } finally { - CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG, "isPointOnCarFront cost:" + (SystemClock.elapsedRealtime() - start) + "ms"); + Log.d("Route", "isPointOnCarFront cost:" + (SystemClock.elapsedRealtime() - start) + "ms"); } } } - private volatile RenderTask mRenderTask; + private RenderTask mRenderTask; - public void drawTrajectoryList(MogoLocation carLoc, List routeList) { + public void drawTrajectoryList(Lock lock, MogoLocation carLoc, List routeList) { if (mRenderTask == null) { mRenderTask = new RenderTask(); } - mRenderTask.setData(carLoc, routeList); + mRenderTask.setData(lock, carLoc, routeList); if (mRenderHandler != null) { mRenderHandler.removeCallbacks(mRenderTask); mRenderHandler.post(mRenderTask); } } - - public void setVisible(boolean isVisible) { - if (mMoGoPolyline != null && !mMoGoPolyline.isDestroyed()) { - mMoGoPolyline.setVisible(isVisible); - } - } } diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/RouteStrategy.kt b/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/RouteStrategy.kt new file mode 100644 index 0000000000..9856abe474 --- /dev/null +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/RouteStrategy.kt @@ -0,0 +1,202 @@ +package com.mogo.module.service.routeoverlay + +import android.graphics.* +import com.mogo.eagle.core.data.config.* +import com.mogo.eagle.core.utilcode.mogo.* +import java.lang.Double.NaN +import java.util.* +import kotlin.collections.ArrayList + + +interface IStrategy { + + fun getColors(): Array + + fun getIndexes(): Array +} + +class Colors { + + companion object { + val COLOR_BLUE_DARK = Color.parseColor("#2ABAD9") + val COLOR_BLUE_LIGHT = Color.parseColor("#332ABAD9") + val COLOR_RED_DARK = Color.parseColor("#CA4C15") + val COLOR_TRANSPARENT = Color.parseColor("#002ABAD9") + } +} + + +sealed class Strategy: IStrategy + +class Uniform(private val count: Int, private val colors: Array? = null): Strategy() { + + override fun getColors(): Array = colors ?: arrayOf(Colors.COLOR_BLUE_DARK, Colors.COLOR_TRANSPARENT) + + override fun getIndexes(): Array = arrayOf(0, count) +} + + +class SlowDown(private val colors: Array, private val indexes: Array): Strategy() { + + override fun getColors(): Array = colors + + override fun getIndexes(): Array = indexes + + override fun toString(): String { + return indexes.joinToString(",") + } +} + + +class SpeedUp(private val count: Int): Strategy() { + override fun getColors(): Array = arrayOf(Colors.COLOR_BLUE_DARK, Colors.COLOR_TRANSPARENT) + + override fun getIndexes(): Array = arrayOf(0, count) +} + + +object RouteStrategy { + + private var strategy: Strategy? = null + private var index: Int = 0 + + private var oldV: Double = NaN + private var oldA: Double = NaN + private var mode: Int = -1 // 0: 匀速, 1:减速, 2: 加速 + private val colors4SlowDown: LinkedList = LinkedList() + private val colors4Uniform: LinkedList = LinkedList() + private val indexes4SlowDown: LinkedList = LinkedList() + private var isLightBlueAll = false + private var isRedBlue = false + private var ignore = false + private var firstV: Double = NaN + + private var isEnable = AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode) + + fun enable(enable: Boolean) { + isEnable = enable + } + + fun start() { + strategy = null + index = 0 + mode = -1 + ignore = false + colors4Uniform.clear() + colors4SlowDown.clear() + indexes4SlowDown.clear() + isLightBlueAll = false + isRedBlue = false + oldA = NaN + oldV = NaN + firstV = NaN + } + + fun end() { + strategy = acquireStrategy() + } + + private fun acquireStrategy(): Strategy? { + if (mode == 0) { + return if (colors4Uniform.isNotEmpty()) Uniform(index, colors = Array(colors4Uniform.size) { + colors4Uniform[it] + }) else null + } + if (mode == 2) { + return SpeedUp(index) + } + + if (indexes4SlowDown.isEmpty() || !isLightBlueAll) { + return null + } + val count = indexes4SlowDown.size + if (count == 3) { + val colors = when { + isRedBlue -> { + arrayOf(Colors.COLOR_RED_DARK, Colors.COLOR_BLUE_DARK, Colors.COLOR_BLUE_LIGHT, Colors.COLOR_TRANSPARENT) + } + else -> { + return Uniform(index) + } + } + val indexes = ArrayList() + val i = indexes4SlowDown[2] + if (index - i < 5) { + return Uniform(index) + } + indexes += 0 + indexes += i + indexes += i + indexes += index + return SlowDown(colors, indexes = indexes.toTypedArray()) + } + return null + } + + fun check(speed: Double, acc: Double) { + try { + if (!isEnable){ + return + } + if (ignore) { + return + } + if (oldV.isNaN()) { + return + } + if (oldA.isNaN()) { + return + } + if (index < 3) { + //丢掉前3个点 + return + } + if (firstV.isNaN()) { + firstV = speed; + return + } + if (speed == oldV) { + if (speed <= 0.01) { + colors4Uniform.clear() + colors4Uniform.add(Colors.COLOR_BLUE_LIGHT) + colors4Uniform.add(Colors.COLOR_TRANSPARENT) + } + ignore = true + mode = 0 + return + } + + if (speed > oldV) { + mode = 2 + ignore = true + return + } + + if (speed < oldV) { + if (mode != 1) { + indexes4SlowDown.add(0) + mode = 1 + } + } + if (mode == 1) { + if (!isLightBlueAll && speed <= 0.01) { + isLightBlueAll = true + indexes4SlowDown.add(index) + ignore = true + return + } + + if (!isRedBlue && firstV > 0 && speed > 0 && speed <= firstV / 2.0) { + isRedBlue = true + indexes4SlowDown.add(index) + } + } + } finally { + index++ + oldV = speed + oldA = acc + } + } + + fun getStrategy(): Strategy = if (isEnable) strategy ?: Uniform(index) else SpeedUp(index) +} \ No newline at end of file