[RouteOpt]引导线效果优化二期
[RouteOpt]xxxx
This commit is contained in:
@@ -1034,7 +1034,7 @@ class DebugSettingView @JvmOverloads constructor(
|
||||
accelerationIsShow = isChecked
|
||||
}
|
||||
|
||||
tbRouteDynamicEffect.isChecked = AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)
|
||||
tbRouteDynamicEffect.isChecked = AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) && !AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)
|
||||
|
||||
tbRouteDynamicEffect.setOnCheckedChangeListener { _, isChecked ->
|
||||
if (isChecked) {
|
||||
|
||||
@@ -54,8 +54,12 @@ dependencies {
|
||||
|
||||
kapt rootProject.ext.dependencies.aroutercompiler
|
||||
//implementation rootProject.ext.dependencies.adasHigh
|
||||
implementation rootProject.ext.dependencies.mogocustommapoperational
|
||||
implementation (rootProject.ext.dependencies.mogocustommapoperational) {
|
||||
exclude group: 'com.zhidaoauto.machine', module: 'map'
|
||||
}
|
||||
|
||||
|
||||
implementation rootProject.ext.dependencies.mogocustommap
|
||||
implementation rootProject.ext.dependencies.amapnavi3dmap
|
||||
implementation rootProject.ext.dependencies.amaplocation
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ public class MogoLatLng implements Parcelable {
|
||||
|
||||
public double distance;
|
||||
|
||||
public double acc;
|
||||
|
||||
public MogoLatLng( double lat, double lon ) {
|
||||
this.lat = lat;
|
||||
this.lon = lon;
|
||||
|
||||
@@ -33,6 +33,12 @@ public class MogoPolylineOptions {
|
||||
private boolean mGps = false;
|
||||
private List<Integer> mColorValues;
|
||||
|
||||
private float brightSpeed = Float.MIN_VALUE;
|
||||
|
||||
private int brightColor = -1;
|
||||
|
||||
private boolean isBrightOn = false;
|
||||
|
||||
public MogoPolylineOptions() {
|
||||
this.mPoints = new ArrayList<>();
|
||||
}
|
||||
@@ -161,6 +167,21 @@ public class MogoPolylineOptions {
|
||||
return this;
|
||||
}
|
||||
|
||||
public MogoPolylineOptions brightSpeed(float speed) {
|
||||
this.brightSpeed = speed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MogoPolylineOptions openBright(boolean on) {
|
||||
this.isBrightOn = on;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MogoPolylineOptions brightColor(int color) {
|
||||
this.brightColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isAboveMaskLayer
|
||||
* @return
|
||||
@@ -231,6 +252,18 @@ public class MogoPolylineOptions {
|
||||
return mIsPointsUpdated;
|
||||
}
|
||||
|
||||
public float getBrightSpeed() {
|
||||
return brightSpeed;
|
||||
}
|
||||
|
||||
public boolean isBrightOn() {
|
||||
return isBrightOn;
|
||||
}
|
||||
|
||||
public int getBrightColor() {
|
||||
return brightColor;
|
||||
}
|
||||
|
||||
public List<Integer> getColorValues() {
|
||||
return mColorValues;
|
||||
}
|
||||
|
||||
@@ -482,6 +482,11 @@ public class ObjectUtils {
|
||||
if (options.getColorValues() != null) {
|
||||
target.colorValues(options.getColorValues());
|
||||
}
|
||||
if (options.isBrightOn()) {
|
||||
target.isBright = true;
|
||||
target.brightColor = options.getBrightColor();
|
||||
target.brightSpeed = options.getBrightSpeed();
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo;
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
|
||||
import com.mogo.eagle.core.data.map.MogoLocation;
|
||||
@@ -13,10 +15,13 @@ 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.map.CallerMapLocationListenerManager;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@@ -25,17 +30,14 @@ import mogo_msg.MogoReportMsg;
|
||||
import system_master.SystemStatusInfo;
|
||||
|
||||
public class MogoRouteOverlayManager implements
|
||||
IMoGoAutopilotPlanningListener, IMoGoAutopilotStatusListener,
|
||||
IMoGoMapLocationListener {
|
||||
IMoGoAutopilotPlanningListener, IMoGoAutopilotStatusListener, IMoGoMapLocationListener {
|
||||
private static volatile MogoRouteOverlayManager sInstance;
|
||||
private static final String TAG = "Route";
|
||||
private int STATUS_AUTOPILOT = 0;//0 非自动驾驶 ; 1 自动驾驶
|
||||
private MogoLocation mLocation;
|
||||
|
||||
private final AtomicBoolean isArriveAtStation = new AtomicBoolean(false);
|
||||
private final AtomicInteger autopilotMode = new AtomicInteger(0);
|
||||
|
||||
private List<MessagePad.TrajectoryPoint> mTrajectoryList = null;
|
||||
|
||||
private final Lock mLock = new ReentrantLock();
|
||||
private final LinkedList<List<MessagePad.TrajectoryPoint>> queue = new LinkedList<>();
|
||||
|
||||
private MogoRouteOverlayManager() {}
|
||||
|
||||
@@ -59,22 +61,28 @@ public class MogoRouteOverlayManager implements
|
||||
|
||||
@Override
|
||||
public void onAutopilotTrajectory(@NonNull List<MessagePad.TrajectoryPoint> items) {
|
||||
if (isArriveAtStation.get()) {
|
||||
synchronized (queue) {
|
||||
queue.clear();
|
||||
queue.offer(items);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(@Nullable MogoLocation location, int from) {
|
||||
if (from != 1 || location == null) {
|
||||
return;
|
||||
}
|
||||
if (items.isEmpty()) {
|
||||
if (isArriveAtStation.get() || autopilotMode.get() != 1) {
|
||||
RouteOverlayDrawer.getInstance().clearMogoRouteOverlay();
|
||||
return;
|
||||
}
|
||||
MogoLocation location = mLocation;
|
||||
if (location == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mLock.lock();
|
||||
mTrajectoryList = items;
|
||||
} finally {
|
||||
mLock.unlock();
|
||||
synchronized (queue) {
|
||||
List<MessagePad.TrajectoryPoint> items = queue.getLast();
|
||||
if (items != null && !items.isEmpty()) {
|
||||
RouteOverlayDrawer.getInstance().drawTrajectoryList(items, location.getBearing());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,13 +95,11 @@ public class MogoRouteOverlayManager implements
|
||||
isArriveAtStation.set(false);
|
||||
return;
|
||||
}
|
||||
this.STATUS_AUTOPILOT = autoPilotStatusInfo.getPilotmode();
|
||||
if (this.STATUS_AUTOPILOT == 1) {
|
||||
int mode = autoPilotStatusInfo.getPilotmode();
|
||||
if (mode == 1) {
|
||||
isArriveAtStation.set(false);
|
||||
}
|
||||
if (STATUS_AUTOPILOT != 1) {
|
||||
RouteOverlayDrawer.getInstance().clearMogoRouteOverlay();
|
||||
}
|
||||
this.autopilotMode.set(mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,7 +110,6 @@ public class MogoRouteOverlayManager implements
|
||||
Log.d(TAG, "onArriveAt data : " + arrivalNotification);
|
||||
if (!isArriveAtStation.get()) {
|
||||
isArriveAtStation.set(true);
|
||||
RouteOverlayDrawer.getInstance().clearMogoRouteOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,28 +119,6 @@ public class MogoRouteOverlayManager implements
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(@Nullable MogoLocation location, int from) {
|
||||
if (from != 1) {
|
||||
return;
|
||||
}
|
||||
boolean isExcept = false;
|
||||
try {
|
||||
if (location == null) {
|
||||
isExcept = true;
|
||||
return;
|
||||
}
|
||||
if (FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData || STATUS_AUTOPILOT == 1) {
|
||||
RouteOverlayDrawer.getInstance().drawTrajectoryList(mLock, location, mTrajectoryList);
|
||||
}
|
||||
} finally {
|
||||
mLocation = location;
|
||||
if (isExcept) {
|
||||
RouteOverlayDrawer.getInstance().hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotGuardian(MogoReportMsg.MogoReportMessage guardianInfo) {
|
||||
|
||||
@@ -146,7 +129,5 @@ public class MogoRouteOverlayManager implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotStatusRespByQuery(@NonNull SystemStatusInfo.StatusInfo status) {
|
||||
|
||||
}
|
||||
public void onAutopilotStatusRespByQuery(@NonNull SystemStatusInfo.StatusInfo status) {}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
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.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.mogo.logger.Logger;
|
||||
import com.mogo.map.MogoOverlayManager;
|
||||
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.ArrayList;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import mogo.telematics.pad.MessagePad;
|
||||
|
||||
public class RouteOverlayDrawer {
|
||||
@@ -27,13 +31,31 @@ public class RouteOverlayDrawer {
|
||||
// 连接线参数
|
||||
|
||||
private Handler mRenderHandler;
|
||||
|
||||
// private Handler mLogHandler;
|
||||
|
||||
IMogoOverlayManager mogoOverlayManager;
|
||||
private static volatile RouteOverlayDrawer sInstance;
|
||||
|
||||
private final MogoPolylineOptions mPolylineOptions;
|
||||
private volatile IMogoPolyline mMoGoPolyline;
|
||||
// private FileWriter writer;
|
||||
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();
|
||||
// 线条粗细,渐变,渐变色值
|
||||
@@ -45,15 +67,6 @@ 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() {
|
||||
@@ -68,281 +81,102 @@ public class RouteOverlayDrawer {
|
||||
}
|
||||
|
||||
public void clearMogoRouteOverlay() {
|
||||
if (mRenderTask != null && mRenderHandler != null) {
|
||||
mRenderTask.remove();
|
||||
if (mMoGoPolyline != null) {
|
||||
mMoGoPolyline.remove();
|
||||
mMoGoPolyline = null;
|
||||
}
|
||||
|
||||
if (mRenderTask != null) {
|
||||
mRenderHandler.removeCallbacks(mRenderTask);
|
||||
}
|
||||
}
|
||||
|
||||
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<Integer> colors;
|
||||
private List<MogoLatLng> points;
|
||||
|
||||
public void setData(List<Integer> colors, List<MogoLatLng> 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<Integer> colors, List<MogoLatLng> 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 List<MessagePad.TrajectoryPoint> routeList;
|
||||
private MogoLocation location;
|
||||
private volatile List<MessagePad.TrajectoryPoint> routeList;
|
||||
|
||||
private final Pools.Pool<MogoLatLng> pools;
|
||||
private final LinkedList<MogoLatLng> points;
|
||||
|
||||
private final Pools.Pool<RenderOptions> options;
|
||||
private Lock mLock;
|
||||
private double bearing;
|
||||
|
||||
public RenderTask() {
|
||||
this.pools = new Pools.SimplePool<>(500);
|
||||
this.points = new LinkedList<>();
|
||||
this.options = new Pools.SimplePool<>(5);
|
||||
}
|
||||
|
||||
public void setData(Lock lock, MogoLocation location, List<MessagePad.TrajectoryPoint> routeList) {
|
||||
this.location = location;
|
||||
public void setData(List<MessagePad.TrajectoryPoint> routeList, double bearing) {
|
||||
this.routeList = routeList;
|
||||
this.mLock = lock;
|
||||
this.bearing = bearing;
|
||||
}
|
||||
|
||||
@SuppressLint("LongLogTag")
|
||||
@Override
|
||||
public void run() {
|
||||
Lock lock = this.mLock;
|
||||
if (lock == null) {
|
||||
return;
|
||||
}
|
||||
LinkedList<MogoLatLng> pps = this.points;
|
||||
boolean isExcept = false;
|
||||
// StringBuilder sb;
|
||||
int total;
|
||||
try {
|
||||
pps.clear();
|
||||
long drawStart = SystemClock.elapsedRealtime();
|
||||
try {
|
||||
lock.lock();
|
||||
List<MessagePad.TrajectoryPoint> 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());
|
||||
}
|
||||
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());
|
||||
}
|
||||
RouteStrategy.INSTANCE.end();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
List<MessagePad.TrajectoryPoint> routes = this.routeList;
|
||||
if (routes == null || (total = routes.size()) < 2) {
|
||||
isExcept = true;
|
||||
return;
|
||||
}
|
||||
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<LinkedList<MogoLatLng>> 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()))));
|
||||
RouteStrategy.INSTANCE.start();
|
||||
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());
|
||||
}
|
||||
if (route == null) {
|
||||
//数组越界了,结束循环
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
acquire.acc = route.getAcceleration();
|
||||
acquire.speed = route.getVelocity();
|
||||
pps.add(acquire);
|
||||
RouteStrategy.INSTANCE.check(route.getVelocity(), route.getAcceleration(), routeList.size());
|
||||
}
|
||||
double lon = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lon();
|
||||
double lat = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lat();
|
||||
int removeCount = 0;
|
||||
int colorsIndex = 0;
|
||||
if (!parts.isEmpty()) {
|
||||
L:while (!parts.isEmpty()) {
|
||||
LinkedList<MogoLatLng> part = parts.peek();
|
||||
if (part == null) {
|
||||
if (points.size() > 0) {
|
||||
MogoLatLng top = null;
|
||||
while (points.size() != 0) {
|
||||
MogoLatLng first = points.peek();
|
||||
if (first == null) {
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
if (first == top) {
|
||||
break;
|
||||
}
|
||||
parts.poll();
|
||||
colorsIndex += 2;
|
||||
lon = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lon();
|
||||
lat = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lat();
|
||||
long angle = isPointOnCarFront(lon, lat, bearing, first.lon, first.lat);
|
||||
if (angle >= 90) {
|
||||
removeCount++;
|
||||
RouteStrategy.INSTANCE.remove(first.acc);
|
||||
pools.release(first);
|
||||
points.poll();
|
||||
}
|
||||
top = first;
|
||||
}
|
||||
if (parts.isEmpty()) {
|
||||
if (points.size() == 0) {
|
||||
isExcept = true;
|
||||
return;
|
||||
}
|
||||
@@ -353,75 +187,92 @@ public class RouteOverlayDrawer {
|
||||
self.lat = lat;
|
||||
self.lon = lon;
|
||||
}
|
||||
pps.addFirst(self);
|
||||
parts.get(0).addFirst(self);
|
||||
List<RenderOptions> ll = new ArrayList<>();
|
||||
for (int i = 0; i < parts.size(); i++) {
|
||||
LinkedList<MogoLatLng> ps = parts.get(i);
|
||||
RenderOptions options = this.options.acquire();
|
||||
if (options == null) {
|
||||
options = new RenderOptions(mogoOverlayManager);
|
||||
points.addFirst(self);
|
||||
RouteStrategy.INSTANCE.end();
|
||||
Strategy strategy = RouteStrategy.INSTANCE.getStrategy();
|
||||
List<Integer> 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.brightSpeed(0.5f);
|
||||
} else {
|
||||
mPolylineOptions.openBright(false);
|
||||
}
|
||||
ll.add(options);
|
||||
List<Integer> cls = new ArrayList<>();
|
||||
cls.add(colors[colorsIndex++]);
|
||||
cls.add(colors[colorsIndex++]);
|
||||
options.show(cls, ps);
|
||||
mMoGoPolyline = mogoOverlayManager.addPolyline(mPolylineOptions);
|
||||
} else {
|
||||
mPolylineOptions.points(points);
|
||||
mPolylineOptions.colorValues(colors);
|
||||
if (isLightOn) {
|
||||
mPolylineOptions.openBright(true);
|
||||
mPolylineOptions.brightColor(Color.parseColor("#D2F2F8"));
|
||||
mPolylineOptions.brightSpeed(0.5f);
|
||||
} else {
|
||||
mPolylineOptions.openBright(false);
|
||||
}
|
||||
mMoGoPolyline.setOption(mPolylineOptions);
|
||||
}
|
||||
hide();
|
||||
for (int i = ll.size() - 1; i >= 0 ; i--) {
|
||||
this.options.release(ll.get(i));
|
||||
if (mMoGoPolyline != null && !mMoGoPolyline.isDestroyed() && !mMoGoPolyline.isVisible()) {
|
||||
mMoGoPolyline.setVisible(true);
|
||||
}
|
||||
} else {
|
||||
isExcept = true;
|
||||
}
|
||||
long drawEnd = SystemClock.elapsedRealtime();
|
||||
// Log.d("Route", "draw cost:" + (drawEnd - drawStart) + "ms and isExcept:" + isExcept + "::removeCount:" + removeCount + "::total:" + total);
|
||||
Logger.d(M_OLD_ROUTE + TAG, "drawTrajectoryList cost : " + (drawEnd - drawStart) + "ms and isExcept:" + isExcept + "::removeCount:" + removeCount + "::total:" + total);
|
||||
} catch (Throwable t) {
|
||||
// Log.d("Route","error:" + Log.getStackTraceString(t));
|
||||
Logger.d(M_OLD_ROUTE + TAG, "drawTrajectoryList error (isExcept: "+isExcept+") : " + t);
|
||||
} finally {
|
||||
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));
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void hide() {
|
||||
List<RenderOptions> 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<RenderOptions> 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -431,24 +282,30 @@ public class RouteOverlayDrawer {
|
||||
// 计算车辆与点之间的夹角
|
||||
long diffAngle = DrivingDirectionUtils.getDegreeOfCar2Poi2(
|
||||
car_lon, car_lat, lon, lat, car_head);
|
||||
// Log.d("Route", "isPointOnCarFront: angle->" + diffAngle);
|
||||
CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG, "isPointOnCarFront: angle->" + diffAngle);
|
||||
return diffAngle;
|
||||
} finally {
|
||||
// Log.d("Route", "isPointOnCarFront cost:" + (SystemClock.elapsedRealtime() - start) + "ms");
|
||||
CallerLogger.INSTANCE.d(M_OLD_ROUTE + TAG, "isPointOnCarFront cost:" + (SystemClock.elapsedRealtime() - start) + "ms");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private RenderTask mRenderTask;
|
||||
private volatile RenderTask mRenderTask;
|
||||
|
||||
public void drawTrajectoryList(Lock lock, MogoLocation carLoc, List<MessagePad.TrajectoryPoint> routeList) {
|
||||
public void drawTrajectoryList(List<MessagePad.TrajectoryPoint> routeList, double bearing) {
|
||||
if (mRenderTask == null) {
|
||||
mRenderTask = new RenderTask();
|
||||
}
|
||||
mRenderTask.setData(lock, carLoc, routeList);
|
||||
mRenderTask.setData(routeList, bearing);
|
||||
if (mRenderHandler != null) {
|
||||
mRenderHandler.removeCallbacks(mRenderTask);
|
||||
mRenderHandler.post(mRenderTask);
|
||||
}
|
||||
}
|
||||
|
||||
public void setVisible(boolean isVisible) {
|
||||
if (mMoGoPolyline != null && !mMoGoPolyline.isDestroyed()) {
|
||||
mMoGoPolyline.setVisible(isVisible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,202 +1,162 @@
|
||||
package com.mogo.module.service.routeoverlay
|
||||
|
||||
import android.animation.*
|
||||
import android.graphics.*
|
||||
import android.view.animation.*
|
||||
import com.mogo.eagle.core.data.config.*
|
||||
import com.mogo.eagle.core.utilcode.mogo.*
|
||||
import java.lang.Double.NaN
|
||||
import com.mogo.module.service.routeoverlay.Colors.Companion.COLOR_BLUE
|
||||
import com.mogo.module.service.routeoverlay.Colors.Companion.COLOR_BLUE_DARK
|
||||
import com.mogo.module.service.routeoverlay.Colors.Companion.COLOR_RED_DARK
|
||||
import com.mogo.module.service.routeoverlay.Colors.Companion.COLOR_TRANSPARENT
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
|
||||
interface IStrategy {
|
||||
|
||||
fun getColors(): Array<Int>
|
||||
|
||||
fun getIndexes(): Array<Int>
|
||||
fun getColors(): List<Int>
|
||||
}
|
||||
|
||||
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_BLUE = Color.parseColor("#FF2ABAD9")
|
||||
val COLOR_BLUE_DARK = Color.parseColor("#FF074EFF")
|
||||
val COLOR_RED_DARK = Color.parseColor("#FFFF5F00")
|
||||
val COLOR_TRANSPARENT = Color.parseColor("#002ABAD9")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sealed class Strategy: IStrategy
|
||||
|
||||
class Uniform(private val count: Int, private val colors: Array<Int>? = null): Strategy() {
|
||||
class DefaultStrategy(private val colors: List<Int>? = null): Strategy() {
|
||||
|
||||
override fun getColors(): Array<Int> = colors ?: arrayOf(Colors.COLOR_BLUE_DARK, Colors.COLOR_TRANSPARENT)
|
||||
|
||||
override fun getIndexes(): Array<Int> = arrayOf(0, count)
|
||||
override fun getColors(): List<Int> = colors ?: listOf(COLOR_BLUE, COLOR_TRANSPARENT)
|
||||
}
|
||||
|
||||
|
||||
class SlowDown(private val colors: Array<Int>, private val indexes: Array<Int>): Strategy() {
|
||||
|
||||
override fun getColors(): Array<Int> = colors
|
||||
|
||||
override fun getIndexes(): Array<Int> = indexes
|
||||
|
||||
override fun toString(): String {
|
||||
return indexes.joinToString(",")
|
||||
}
|
||||
class ColorfulStrategy(private val colors: List<Int> = emptyList(), var isLightOn: Boolean): Strategy() {
|
||||
override fun getColors(): List<Int> = colors
|
||||
}
|
||||
|
||||
|
||||
class SpeedUp(private val count: Int): Strategy() {
|
||||
override fun getColors(): Array<Int> = arrayOf(Colors.COLOR_BLUE_DARK, Colors.COLOR_TRANSPARENT)
|
||||
|
||||
override fun getIndexes(): Array<Int> = arrayOf(0, count)
|
||||
}
|
||||
|
||||
|
||||
object RouteStrategy {
|
||||
|
||||
private var isEnable = AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) && !AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)
|
||||
|
||||
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<Int> = LinkedList()
|
||||
private val colors4Uniform: LinkedList<Int> = LinkedList()
|
||||
private val indexes4SlowDown: LinkedList<Int> = LinkedList()
|
||||
private var isLightBlueAll = false
|
||||
private var isRedBlue = false
|
||||
private var ignore = false
|
||||
private var firstV: Double = NaN
|
||||
private val colors: ArrayList<Int> = ArrayList()
|
||||
|
||||
private var isEnable = AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)
|
||||
private var index = 0
|
||||
|
||||
private val sorted: NavigableMap<Double, Int> by lazy { TreeMap() }
|
||||
|
||||
private var endEvaluator: ArgbEvaluator? = null
|
||||
|
||||
private var startColor = Int.MAX_VALUE
|
||||
|
||||
private var hasLessThan0 = false
|
||||
|
||||
fun enable(enable: Boolean) {
|
||||
isEnable = enable
|
||||
if (!enable) {
|
||||
strategy = null
|
||||
colors.clear()
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
startColor = Int.MAX_VALUE
|
||||
colors.clear()
|
||||
endEvaluator = null
|
||||
hasLessThan0 = false
|
||||
}
|
||||
|
||||
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 SpeedUp(index)
|
||||
}
|
||||
}
|
||||
val indexes = ArrayList<Int>()
|
||||
val i = indexes4SlowDown[2]
|
||||
if (index - i < 5) {
|
||||
return SpeedUp(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){
|
||||
if (isEnable) {
|
||||
if (colors.isEmpty()) {
|
||||
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
|
||||
val first = colors[0]
|
||||
colors.add(0, first)
|
||||
strategy = ColorfulStrategy(colors, true)
|
||||
}
|
||||
}
|
||||
|
||||
fun getStrategy(): Strategy = if (isEnable) strategy ?: Uniform(index) else SpeedUp(index)
|
||||
fun check(speed: Double, acc: Double, total: Int) {
|
||||
if (!isEnable){
|
||||
return
|
||||
}
|
||||
if (sorted.isEmpty()) {
|
||||
fill()
|
||||
}
|
||||
if (sorted.isEmpty()) {
|
||||
throw AssertionError("sorted map must not be null.")
|
||||
}
|
||||
if (acc < 0) {
|
||||
hasLessThan0 = true
|
||||
}
|
||||
val delta = (total * 0.35).toInt()
|
||||
val last = total - delta
|
||||
val entry = sorted.floorEntry(acc)
|
||||
if (entry != null) {
|
||||
if (index >= last - 1) {
|
||||
if (startColor == Int.MAX_VALUE) {
|
||||
startColor = entry.value
|
||||
if (endEvaluator == null) {
|
||||
endEvaluator = ArgbEvaluator()
|
||||
}
|
||||
colors += entry.value
|
||||
} else {
|
||||
if (endEvaluator != null) {
|
||||
val fraction = (index - last) * 1.0f / delta
|
||||
colors += endEvaluator!!.evaluate(fraction, startColor, COLOR_TRANSPARENT) as Int
|
||||
}
|
||||
}
|
||||
} else {
|
||||
colors += entry.value
|
||||
}
|
||||
}
|
||||
index++
|
||||
}
|
||||
|
||||
fun remove(acc: Double): List<Int> {
|
||||
if (sorted.isEmpty()) {
|
||||
throw AssertionError("sorted map must not be null.")
|
||||
}
|
||||
val entry = sorted.floorEntry(acc)
|
||||
if (entry != null) {
|
||||
colors.remove(entry.value)
|
||||
}
|
||||
return ArrayList(colors)
|
||||
}
|
||||
|
||||
private fun fill() {
|
||||
var startValue = -4.0
|
||||
var endValue = 0.0
|
||||
val step = 0.01
|
||||
var current = startValue
|
||||
val evaluator = ArgbEvaluator()
|
||||
val interceptor = AccelerateInterpolator()
|
||||
var total = endValue - startValue
|
||||
while (current <= endValue) {
|
||||
val fraction = interceptor.getInterpolation(((current - startValue) / total).toFloat())
|
||||
val colorValue = evaluator.evaluate(fraction, COLOR_RED_DARK, COLOR_BLUE) as Int
|
||||
sorted[current] = colorValue
|
||||
current += step
|
||||
}
|
||||
startValue = 0.01
|
||||
endValue = 3.0
|
||||
current = startValue
|
||||
total = endValue - startValue
|
||||
while (current <= endValue) {
|
||||
val fraction = (current - startValue) / total
|
||||
val colorValue = evaluator.evaluate(fraction.toFloat(), COLOR_BLUE, COLOR_BLUE_DARK) as Int
|
||||
sorted[current] = colorValue
|
||||
current += step
|
||||
}
|
||||
}
|
||||
|
||||
fun getStrategy(): Strategy = if (isEnable) { (strategy ?: DefaultStrategy()) } else DefaultStrategy()
|
||||
}
|
||||
Reference in New Issue
Block a user