Calculate route using Executer instead of Thread
This commit is contained in:
parent
cf916a5da7
commit
c860f8eea4
3 changed files with 213 additions and 179 deletions
|
@ -10,11 +10,19 @@ import net.osmand.plus.settings.backend.ApplicationMode;
|
|||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.router.RouteCalculationProgress;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static net.osmand.plus.notifications.OsmandNotification.NotificationType.NAVIGATION;
|
||||
|
||||
class RouteRecalculationThreadHelper {
|
||||
class RouteRecalculationHelper {
|
||||
|
||||
private static final int RECALCULATE_THRESHOLD_COUNT_CAUSING_FULL_RECALCULATE = 3;
|
||||
private static final int RECALCULATE_THRESHOLD_CAUSING_FULL_RECALCULATE_INTERVAL = 2 * 60 * 1000;
|
||||
|
@ -22,17 +30,19 @@ class RouteRecalculationThreadHelper {
|
|||
private final OsmandApplication app;
|
||||
private final RoutingHelper routingHelper;
|
||||
|
||||
private Thread currentRunningJob;
|
||||
private final ExecutorService executor = new RouteRecalculationExecutor();
|
||||
private final Map<Future<?>, RouteRecalculationTask> tasksMap = new LinkedHashMap<>();
|
||||
private RouteRecalculationTask lastTask;
|
||||
|
||||
private long lastTimeEvaluatedRoute = 0;
|
||||
private String lastRouteCalcError;
|
||||
private String lastRouteCalcErrorShort;
|
||||
private long recalculateCountInInterval = 0;
|
||||
private int evalWaitInterval = 0;
|
||||
private boolean waitingNextJob;
|
||||
|
||||
private RouteCalculationProgressCallback progressRoute;
|
||||
|
||||
RouteRecalculationThreadHelper(@NonNull RoutingHelper routingHelper) {
|
||||
RouteRecalculationHelper(@NonNull RoutingHelper routingHelper) {
|
||||
this.routingHelper = routingHelper;
|
||||
this.app = routingHelper.getApplication();
|
||||
}
|
||||
|
@ -50,7 +60,14 @@ class RouteRecalculationThreadHelper {
|
|||
}
|
||||
|
||||
boolean isRouteBeingCalculated() {
|
||||
return currentRunningJob instanceof RouteRecalculationThread || waitingNextJob;
|
||||
synchronized (routingHelper) {
|
||||
for (Future<?> future : tasksMap.keySet()) {
|
||||
if (!future.isDone()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void resetEvalWaitInterval() {
|
||||
|
@ -58,24 +75,31 @@ class RouteRecalculationThreadHelper {
|
|||
}
|
||||
|
||||
void stopCalculation() {
|
||||
Thread job = currentRunningJob;
|
||||
if (job instanceof RouteRecalculationThread) {
|
||||
((RouteRecalculationThread) job).stopCalculation();
|
||||
synchronized (routingHelper) {
|
||||
for (Entry<Future<?>, RouteRecalculationTask> taskFuture : tasksMap.entrySet()) {
|
||||
taskFuture.getValue().stopCalculation();
|
||||
taskFuture.getKey().cancel(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stopCalculationIfParamsChanged() {
|
||||
Thread job = currentRunningJob;
|
||||
if (job instanceof RouteRecalculationThread) {
|
||||
RouteRecalculationThread thread = (RouteRecalculationThread) job;
|
||||
if (!thread.isParamsChanged()) {
|
||||
thread.stopCalculation();
|
||||
void stopCalculationIfParamsNotChanged() {
|
||||
synchronized (routingHelper) {
|
||||
boolean hasPendingTasks = tasksMap.isEmpty();
|
||||
for (Entry<Future<?>, RouteRecalculationTask> taskFuture : tasksMap.entrySet()) {
|
||||
RouteRecalculationTask task = taskFuture.getValue();
|
||||
if (!task.isParamsChanged()) {
|
||||
taskFuture.getKey().cancel(false);
|
||||
task.stopCalculation();
|
||||
}
|
||||
}
|
||||
if (hasPendingTasks) {
|
||||
if (isFollowingMode()) {
|
||||
getVoiceRouter().announceBackOnRoute();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private OsmandSettings getSettings() {
|
||||
return routingHelper.getSettings();
|
||||
|
@ -130,8 +154,6 @@ class RouteRecalculationThreadHelper {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// trigger voice prompt only if new route is in forward direction
|
||||
// If route is in wrong direction after one more setLocation it will be recalculated
|
||||
if (!wrongMovementDirection || newRoute) {
|
||||
|
@ -144,18 +166,15 @@ class RouteRecalculationThreadHelper {
|
|||
|
||||
void startRouteCalculationThread(RouteCalculationParams params, boolean paramsChanged, boolean updateProgress) {
|
||||
synchronized (routingHelper) {
|
||||
final Thread prevRunningJob = currentRunningJob;
|
||||
getSettings().LAST_ROUTE_APPLICATION_MODE.set(getAppMode());
|
||||
RouteRecalculationThread newThread = new RouteRecalculationThread("Calculating route", params, paramsChanged);
|
||||
currentRunningJob = newThread;
|
||||
RouteRecalculationTask newTask = new RouteRecalculationTask(this, params, paramsChanged);
|
||||
lastTask = newTask;
|
||||
startProgress(params);
|
||||
if (updateProgress) {
|
||||
updateProgress(params);
|
||||
}
|
||||
if (prevRunningJob != null) {
|
||||
newThread.setWaitPrevJob(prevRunningJob);
|
||||
}
|
||||
currentRunningJob.start();
|
||||
Future<?> future = executor.submit(newTask);
|
||||
tasksMap.put(future, newTask);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,7 +184,7 @@ class RouteRecalculationThreadHelper {
|
|||
return;
|
||||
}
|
||||
// do not evaluate very often
|
||||
if ((currentRunningJob == null && System.currentTimeMillis() - lastTimeEvaluatedRoute > evalWaitInterval)
|
||||
if ((!isRouteBeingCalculated() && System.currentTimeMillis() - lastTimeEvaluatedRoute > evalWaitInterval)
|
||||
|| paramsChanged || !onlyStartPointChanged) {
|
||||
if (System.currentTimeMillis() - lastTimeEvaluatedRoute < RECALCULATE_THRESHOLD_CAUSING_FULL_RECALCULATE_INTERVAL) {
|
||||
recalculateCountInInterval++;
|
||||
|
@ -234,11 +253,7 @@ class RouteRecalculationThreadHelper {
|
|||
public void run() {
|
||||
RouteCalculationProgress calculationProgress = params.calculationProgress;
|
||||
if (isRouteBeingCalculated()) {
|
||||
Thread t = currentRunningJob;
|
||||
if (t instanceof RouteRecalculationThread && ((RouteRecalculationThread) t).params != params) {
|
||||
// different calculation started
|
||||
return;
|
||||
} else {
|
||||
if (lastTask != null && lastTask.params == params) {
|
||||
progressRoute.updateProgress((int) calculationProgress.getLinearProgress());
|
||||
if (calculationProgress.requestPrivateAccessRouting) {
|
||||
progressRoute.requestPrivateAccessRouting();
|
||||
|
@ -268,23 +283,21 @@ class RouteRecalculationThreadHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private void showMessage(final String msg) {
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
app.showToastMessage(msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class RouteRecalculationThread extends Thread {
|
||||
private static class RouteRecalculationTask implements Runnable {
|
||||
|
||||
private final RouteRecalculationHelper routingThreadHelper;
|
||||
private final RoutingHelper routingHelper;
|
||||
private final RouteCalculationParams params;
|
||||
private final boolean paramsChanged;
|
||||
private Thread prevRunningJob;
|
||||
|
||||
public RouteRecalculationThread(String name, RouteCalculationParams params, boolean paramsChanged) {
|
||||
super(name);
|
||||
String routeCalcError;
|
||||
String routeCalcErrorShort;
|
||||
int evalWaitInterval = 0;
|
||||
|
||||
public RouteRecalculationTask(@NonNull RouteRecalculationHelper routingThreadHelper,
|
||||
@NonNull RouteCalculationParams params, boolean paramsChanged) {
|
||||
this.routingThreadHelper = routingThreadHelper;
|
||||
this.routingHelper = routingThreadHelper.routingHelper;
|
||||
this.params = params;
|
||||
this.paramsChanged = paramsChanged;
|
||||
if (params.calculationProgress == null) {
|
||||
|
@ -300,39 +313,26 @@ class RouteRecalculationThreadHelper {
|
|||
params.calculationProgress.isCancelled = true;
|
||||
}
|
||||
|
||||
private OsmandSettings getSettings() {
|
||||
return routingHelper.getSettings();
|
||||
}
|
||||
|
||||
private void showMessage(final String msg) {
|
||||
final OsmandApplication app = routingHelper.getApplication();
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
app.showToastMessage(msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (routingHelper) {
|
||||
routingHelper.resetRouteWasFinished();
|
||||
currentRunningJob = this;
|
||||
waitingNextJob = prevRunningJob != null;
|
||||
}
|
||||
if (prevRunningJob != null) {
|
||||
while (prevRunningJob.isAlive()) {
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
synchronized (routingHelper) {
|
||||
if (params.calculationProgress.isCancelled) {
|
||||
return;
|
||||
}
|
||||
currentRunningJob = this;
|
||||
waitingNextJob = false;
|
||||
}
|
||||
}
|
||||
lastRouteCalcError = null;
|
||||
lastRouteCalcErrorShort = null;
|
||||
RouteProvider provider = routingHelper.getProvider();
|
||||
OsmandSettings settings = getSettings();
|
||||
RouteCalculationResult res = provider.calculateRouteImpl(params);
|
||||
if (params.calculationProgress.isCancelled) {
|
||||
synchronized (routingHelper) {
|
||||
currentRunningJob = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
final boolean onlineSourceWithoutInternet = !res.isCalculated() &&
|
||||
|
@ -353,37 +353,54 @@ class RouteRecalculationThreadHelper {
|
|||
params.resultListener.onRouteCalculated(res);
|
||||
}
|
||||
} else {
|
||||
evalWaitInterval = Math.max(3000, evalWaitInterval * 3 / 2); // for Issue #3899
|
||||
evalWaitInterval = Math.max(3000, routingThreadHelper.evalWaitInterval * 3 / 2); // for Issue #3899
|
||||
evalWaitInterval = Math.min(evalWaitInterval, 120000);
|
||||
}
|
||||
currentRunningJob = null;
|
||||
}
|
||||
OsmandApplication app = routingHelper.getApplication();
|
||||
if (res.isCalculated()) {
|
||||
if (!params.inSnapToRoadMode && !params.inPublicTransportMode) {
|
||||
setNewRoute(prev, res, params.start);
|
||||
routingThreadHelper.setNewRoute(prev, res, params.start);
|
||||
}
|
||||
} else if (onlineSourceWithoutInternet) {
|
||||
lastRouteCalcError = app.getString(R.string.error_calculating_route)
|
||||
routeCalcError = app.getString(R.string.error_calculating_route)
|
||||
+ ":\n" + app.getString(R.string.internet_connection_required_for_online_route);
|
||||
lastRouteCalcErrorShort = app.getString(R.string.error_calculating_route);
|
||||
showMessage(lastRouteCalcError); //$NON-NLS-1$
|
||||
routeCalcErrorShort = app.getString(R.string.error_calculating_route);
|
||||
showMessage(routeCalcError);
|
||||
} else {
|
||||
if (res.getErrorMessage() != null) {
|
||||
lastRouteCalcError = app.getString(R.string.error_calculating_route) + ":\n" + res.getErrorMessage();
|
||||
lastRouteCalcErrorShort = app.getString(R.string.error_calculating_route);
|
||||
showMessage(lastRouteCalcError); //$NON-NLS-1$
|
||||
routeCalcError = app.getString(R.string.error_calculating_route) + ":\n" + res.getErrorMessage();
|
||||
routeCalcErrorShort = app.getString(R.string.error_calculating_route);
|
||||
} else {
|
||||
lastRouteCalcError = app.getString(R.string.empty_route_calculated);
|
||||
lastRouteCalcErrorShort = app.getString(R.string.empty_route_calculated);
|
||||
showMessage(lastRouteCalcError);
|
||||
routeCalcError = app.getString(R.string.empty_route_calculated);
|
||||
routeCalcErrorShort = app.getString(R.string.empty_route_calculated);
|
||||
}
|
||||
showMessage(routeCalcError);
|
||||
}
|
||||
app.getNotificationHelper().refreshNotification(NAVIGATION);
|
||||
lastTimeEvaluatedRoute = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
public void setWaitPrevJob(Thread prevRunningJob) {
|
||||
this.prevRunningJob = prevRunningJob;
|
||||
private class RouteRecalculationExecutor extends ThreadPoolExecutor {
|
||||
|
||||
public RouteRecalculationExecutor() {
|
||||
super(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
|
||||
}
|
||||
|
||||
protected void afterExecute(Runnable r, Throwable t) {
|
||||
super.afterExecute(r, t);
|
||||
RouteRecalculationTask task = null;
|
||||
synchronized (routingHelper) {
|
||||
if (r instanceof Future<?>) {
|
||||
task = tasksMap.remove(r);
|
||||
}
|
||||
}
|
||||
if (t == null && task != null) {
|
||||
evalWaitInterval = task.evalWaitInterval;
|
||||
lastRouteCalcError = task.routeCalcError;
|
||||
lastRouteCalcErrorShort = task.routeCalcErrorShort;
|
||||
}
|
||||
lastTimeEvaluatedRoute = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -54,7 +54,7 @@ public class RoutingHelper {
|
|||
private OsmandSettings settings;
|
||||
private final RouteProvider provider;
|
||||
private final VoiceRouter voiceRouter;
|
||||
private final RouteRecalculationThreadHelper routeRecalculationHelper;
|
||||
private final RouteRecalculationHelper routeRecalculationHelper;
|
||||
private final TransportRoutingHelper transportRoutingHelper;
|
||||
|
||||
private boolean isFollowingMode = false;
|
||||
|
@ -94,7 +94,7 @@ public class RoutingHelper {
|
|||
settings = context.getSettings();
|
||||
voiceRouter = new VoiceRouter(this);
|
||||
provider = new RouteProvider();
|
||||
routeRecalculationHelper = new RouteRecalculationThreadHelper(this);
|
||||
routeRecalculationHelper = new RouteRecalculationHelper(this);
|
||||
transportRoutingHelper = context.getTransportRoutingHelper();
|
||||
transportRoutingHelper.setRoutingHelper(this);
|
||||
setAppMode(settings.APPLICATION_MODE.get());
|
||||
|
@ -505,7 +505,7 @@ public class RoutingHelper {
|
|||
routeRecalculationHelper.recalculateRouteInBackground(currentLocation, finalLocation, intermediatePoints, currentGPXRoute,
|
||||
previousRoute.isCalculated() ? previousRoute : null, false, !targetPointsChanged);
|
||||
} else {
|
||||
routeRecalculationHelper.stopCalculationIfParamsChanged();
|
||||
routeRecalculationHelper.stopCalculationIfParamsNotChanged();
|
||||
}
|
||||
|
||||
double projectDist = mode != null && mode.hasFastSpeed() ? posTolerance : posTolerance / 2;
|
||||
|
|
|
@ -13,37 +13,42 @@ import net.osmand.binary.BinaryMapIndexReader;
|
|||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.osm.edit.Node;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.settings.backend.CommonPreference;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.render.NativeOsmandLibrary;
|
||||
import net.osmand.plus.routing.RouteCalculationParams.RouteCalculationResultListener;
|
||||
import net.osmand.plus.routing.RouteProvider.RouteService;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.backend.CommonPreference;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.router.GeneralRouter;
|
||||
|
||||
import net.osmand.router.NativeTransportRoutingResult;
|
||||
import net.osmand.router.RouteCalculationProgress;
|
||||
import net.osmand.router.RoutingConfiguration;
|
||||
import net.osmand.router.TransportRoutePlanner;
|
||||
import net.osmand.router.TransportRouteResult;
|
||||
import net.osmand.router.TransportRoutePlanner.TransportRouteResultSegment;
|
||||
import net.osmand.router.TransportRoutingContext;
|
||||
import net.osmand.router.TransportRouteResult;
|
||||
import net.osmand.router.TransportRoutingConfiguration;
|
||||
import net.osmand.router.NativeTransportRoutingResult;
|
||||
import net.osmand.router.TransportRoutingContext;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static net.osmand.plus.notifications.OsmandNotification.NotificationType.NAVIGATION;
|
||||
|
||||
|
@ -53,10 +58,14 @@ public class TransportRoutingHelper {
|
|||
|
||||
private List<WeakReference<IRouteInformationListener>> listeners = new LinkedList<>();
|
||||
|
||||
private OsmandApplication app;
|
||||
private final OsmandApplication app;
|
||||
private ApplicationMode applicationMode = ApplicationMode.PUBLIC_TRANSPORT;
|
||||
private RoutingHelper routingHelper;
|
||||
|
||||
private final ExecutorService executor = new RouteRecalculationExecutor();
|
||||
private final Map<Future<?>, RouteRecalculationTask> tasksMap = new LinkedHashMap<>();
|
||||
private RouteRecalculationTask lastTask;
|
||||
|
||||
private List<TransportRouteResult> routes;
|
||||
private Map<Pair<TransportRouteResultSegment, TransportRouteResultSegment>, RouteCalculationResult> walkingRouteSegments;
|
||||
private int currentRoute = -1;
|
||||
|
@ -64,11 +73,9 @@ public class TransportRoutingHelper {
|
|||
private LatLon startLocation;
|
||||
private LatLon endLocation;
|
||||
|
||||
private Thread currentRunningJob;
|
||||
private String lastRouteCalcError;
|
||||
private String lastRouteCalcErrorShort;
|
||||
private long lastTimeEvaluatedRoute = 0;
|
||||
private boolean waitingNextJob;
|
||||
|
||||
private TransportRouteCalculationProgressCallback progressRoute;
|
||||
|
||||
|
@ -212,18 +219,14 @@ public class TransportRoutingHelper {
|
|||
|
||||
private void startRouteCalculationThread(TransportRouteCalculationParams params) {
|
||||
synchronized (this) {
|
||||
final Thread prevRunningJob = currentRunningJob;
|
||||
app.getSettings().LAST_ROUTE_APPLICATION_MODE.set(routingHelper.getAppMode());
|
||||
RouteRecalculationThread newThread =
|
||||
new RouteRecalculationThread("Calculating public transport route", params,
|
||||
RouteRecalculationTask newTask = new RouteRecalculationTask(this, params,
|
||||
app.getSettings().SAFE_MODE.get() ? null : NativeOsmandLibrary.getLoadedLibrary());
|
||||
currentRunningJob = newThread;
|
||||
lastTask = newTask;
|
||||
startProgress(params);
|
||||
updateProgress(params);
|
||||
if (prevRunningJob != null) {
|
||||
newThread.setWaitPrevJob(prevRunningJob);
|
||||
}
|
||||
currentRunningJob.start();
|
||||
Future<?> future = executor.submit(newTask);
|
||||
tasksMap.put(future, newTask);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,10 +253,7 @@ public class TransportRoutingHelper {
|
|||
if (isRouteBeingCalculated()) {
|
||||
float pr = calculationProgress.getLinearProgress();
|
||||
progressRoute.updateProgress((int) pr);
|
||||
Thread t = currentRunningJob;
|
||||
if (t instanceof RouteRecalculationThread && ((RouteRecalculationThread) t).params != params) {
|
||||
// different calculation started
|
||||
} else {
|
||||
if (lastTask != null && lastTask.params == params) {
|
||||
updateProgress(params);
|
||||
}
|
||||
} else {
|
||||
|
@ -268,7 +268,23 @@ public class TransportRoutingHelper {
|
|||
}
|
||||
|
||||
public boolean isRouteBeingCalculated() {
|
||||
return currentRunningJob instanceof RouteRecalculationThread || waitingNextJob;
|
||||
synchronized (this) {
|
||||
for (Future<?> future : tasksMap.keySet()) {
|
||||
if (!future.isDone()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void stopCalculation() {
|
||||
synchronized (this) {
|
||||
for (Map.Entry<Future<?>, RouteRecalculationTask> taskFuture : tasksMap.entrySet()) {
|
||||
taskFuture.getValue().stopCalculation();
|
||||
taskFuture.getKey().cancel(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setNewRoute(final List<TransportRouteResult> res) {
|
||||
|
@ -322,9 +338,7 @@ public class TransportRoutingHelper {
|
|||
}
|
||||
});
|
||||
this.endLocation = newFinalLocation;
|
||||
if (currentRunningJob instanceof RouteRecalculationThread) {
|
||||
((RouteRecalculationThread) currentRunningJob).stopCalculation();
|
||||
}
|
||||
stopCalculation();
|
||||
}
|
||||
|
||||
private void setCurrentLocation(LatLon currentLocation) {
|
||||
|
@ -335,15 +349,6 @@ public class TransportRoutingHelper {
|
|||
recalculateRouteInBackground(currentLocation, endLocation);
|
||||
}
|
||||
|
||||
private void showMessage(final String msg) {
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
app.showToastMessage(msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public QuadRect getTransportRouteRect(@NonNull TransportRouteResult result) {
|
||||
TransportRoutingHelper transportRoutingHelper = app.getTransportRoutingHelper();
|
||||
|
@ -403,7 +408,7 @@ public class TransportRoutingHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private class WalkingRouteSegment {
|
||||
private static class WalkingRouteSegment {
|
||||
TransportRouteResultSegment s1;
|
||||
TransportRouteResultSegment s2;
|
||||
LatLon start;
|
||||
|
@ -436,18 +441,24 @@ public class TransportRoutingHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private class RouteRecalculationThread extends Thread {
|
||||
private static class RouteRecalculationTask implements Runnable {
|
||||
|
||||
private final TransportRoutingHelper transportRoutingHelper;
|
||||
private final RoutingHelper routingHelper;
|
||||
private final TransportRouteCalculationParams params;
|
||||
private Thread prevRunningJob;
|
||||
|
||||
private final Queue<WalkingRouteSegment> walkingSegmentsToCalculate = new ConcurrentLinkedQueue<>();
|
||||
private Map<Pair<TransportRouteResultSegment, TransportRouteResultSegment>, RouteCalculationResult> walkingRouteSegments = new HashMap<>();
|
||||
private boolean walkingSegmentsCalculated;
|
||||
private NativeLibrary lib;
|
||||
private final NativeLibrary lib;
|
||||
|
||||
public RouteRecalculationThread(String name, TransportRouteCalculationParams params, NativeLibrary library) {
|
||||
super(name);
|
||||
String routeCalcError;
|
||||
String routeCalcErrorShort;
|
||||
|
||||
public RouteRecalculationTask(@NonNull TransportRoutingHelper transportRoutingHelper,
|
||||
@NonNull TransportRouteCalculationParams params, @Nullable NativeLibrary library) {
|
||||
this.transportRoutingHelper = transportRoutingHelper;
|
||||
this.routingHelper = transportRoutingHelper.routingHelper;
|
||||
this.params = params;
|
||||
this.lib = library;
|
||||
if (params.calculationProgress == null) {
|
||||
|
@ -459,9 +470,9 @@ public class TransportRoutingHelper {
|
|||
params.calculationProgress.isCancelled = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO Check if native lib available and calculate route there.
|
||||
*
|
||||
* @param params
|
||||
* @return
|
||||
* @throws IOException
|
||||
|
@ -509,7 +520,6 @@ public class TransportRoutingHelper {
|
|||
|
||||
@Nullable
|
||||
private RouteCalculationParams getWalkingRouteParams() {
|
||||
|
||||
ApplicationMode walkingMode = ApplicationMode.PEDESTRIAN;
|
||||
|
||||
final WalkingRouteSegment walkingRouteSegment = walkingSegmentsToCalculate.poll();
|
||||
|
@ -517,13 +527,14 @@ public class TransportRoutingHelper {
|
|||
return null;
|
||||
}
|
||||
|
||||
OsmandApplication app = routingHelper.getApplication();
|
||||
Location start = new Location("");
|
||||
start.setLatitude(walkingRouteSegment.start.getLatitude());
|
||||
start.setLongitude(walkingRouteSegment.start.getLongitude());
|
||||
LatLon end = new LatLon(walkingRouteSegment.end.getLatitude(), walkingRouteSegment.end.getLongitude());
|
||||
|
||||
final float currentDistanceFromBegin =
|
||||
RouteRecalculationThread.this.params.calculationProgress.distanceFromBegin +
|
||||
RouteRecalculationTask.this.params.calculationProgress.distanceFromBegin +
|
||||
(walkingRouteSegment.s1 != null ? (float) walkingRouteSegment.s1.getTravelDist() : 0);
|
||||
|
||||
final RouteCalculationParams params = new RouteCalculationParams();
|
||||
|
@ -547,8 +558,8 @@ public class TransportRoutingHelper {
|
|||
float p = Math.max(params.calculationProgress.distanceFromBegin,
|
||||
params.calculationProgress.distanceFromEnd);
|
||||
|
||||
RouteRecalculationThread.this.params.calculationProgress.distanceFromBegin =
|
||||
Math.max(RouteRecalculationThread.this.params.calculationProgress.distanceFromBegin, currentDistanceFromBegin + p);
|
||||
RouteRecalculationTask.this.params.calculationProgress.distanceFromBegin =
|
||||
Math.max(RouteRecalculationTask.this.params.calculationProgress.distanceFromBegin, currentDistanceFromBegin + p);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -571,7 +582,7 @@ public class TransportRoutingHelper {
|
|||
params.resultListener = new RouteCalculationResultListener() {
|
||||
@Override
|
||||
public void onRouteCalculated(RouteCalculationResult route) {
|
||||
RouteRecalculationThread.this.walkingRouteSegments.put(new Pair<>(walkingRouteSegment.s1, walkingRouteSegment.s2), route);
|
||||
RouteRecalculationTask.this.walkingRouteSegments.put(new Pair<>(walkingRouteSegment.s1, walkingRouteSegment.s2), route);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -619,26 +630,18 @@ public class TransportRoutingHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private void showMessage(final String msg) {
|
||||
final OsmandApplication app = routingHelper.getApplication();
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (TransportRoutingHelper.this) {
|
||||
currentRunningJob = this;
|
||||
waitingNextJob = prevRunningJob != null;
|
||||
}
|
||||
if (prevRunningJob != null) {
|
||||
while (prevRunningJob.isAlive()) {
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
synchronized (TransportRoutingHelper.this) {
|
||||
currentRunningJob = this;
|
||||
waitingNextJob = false;
|
||||
app.showToastMessage(msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<TransportRouteResult> res = null;
|
||||
String error = null;
|
||||
try {
|
||||
|
@ -651,38 +654,52 @@ public class TransportRoutingHelper {
|
|||
log.error(e);
|
||||
}
|
||||
if (params.calculationProgress.isCancelled) {
|
||||
synchronized (TransportRoutingHelper.this) {
|
||||
currentRunningJob = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
synchronized (TransportRoutingHelper.this) {
|
||||
routes = res;
|
||||
TransportRoutingHelper.this.walkingRouteSegments = walkingRouteSegments;
|
||||
synchronized (transportRoutingHelper) {
|
||||
transportRoutingHelper.routes = res;
|
||||
transportRoutingHelper.walkingRouteSegments = walkingRouteSegments;
|
||||
if (res != null) {
|
||||
if (params.resultListener != null) {
|
||||
params.resultListener.onRouteCalculated(res);
|
||||
}
|
||||
}
|
||||
currentRunningJob = null;
|
||||
}
|
||||
OsmandApplication app = routingHelper.getApplication();
|
||||
if (res != null) {
|
||||
setNewRoute(res);
|
||||
transportRoutingHelper.setNewRoute(res);
|
||||
} else if (error != null) {
|
||||
lastRouteCalcError = app.getString(R.string.error_calculating_route) + ":\n" + error;
|
||||
lastRouteCalcErrorShort = app.getString(R.string.error_calculating_route);
|
||||
showMessage(lastRouteCalcError);
|
||||
routeCalcError = app.getString(R.string.error_calculating_route) + ":\n" + error;
|
||||
routeCalcErrorShort = app.getString(R.string.error_calculating_route);
|
||||
showMessage(routeCalcError);
|
||||
} else {
|
||||
lastRouteCalcError = app.getString(R.string.empty_route_calculated);
|
||||
lastRouteCalcErrorShort = app.getString(R.string.empty_route_calculated);
|
||||
showMessage(lastRouteCalcError);
|
||||
routeCalcError = app.getString(R.string.empty_route_calculated);
|
||||
routeCalcErrorShort = app.getString(R.string.empty_route_calculated);
|
||||
showMessage(routeCalcError);
|
||||
}
|
||||
app.getNotificationHelper().refreshNotification(NAVIGATION);
|
||||
lastTimeEvaluatedRoute = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
public void setWaitPrevJob(Thread prevRunningJob) {
|
||||
this.prevRunningJob = prevRunningJob;
|
||||
private class RouteRecalculationExecutor extends ThreadPoolExecutor {
|
||||
|
||||
public RouteRecalculationExecutor() {
|
||||
super(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
|
||||
}
|
||||
|
||||
protected void afterExecute(Runnable r, Throwable t) {
|
||||
super.afterExecute(r, t);
|
||||
RouteRecalculationTask task = null;
|
||||
synchronized (TransportRoutingHelper.this) {
|
||||
if (r instanceof Future<?>) {
|
||||
task = tasksMap.remove(r);
|
||||
}
|
||||
}
|
||||
if (t == null && task != null) {
|
||||
lastRouteCalcError = task.routeCalcError;
|
||||
lastRouteCalcErrorShort = task.routeCalcErrorShort;
|
||||
}
|
||||
lastTimeEvaluatedRoute = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue