Fix lose profile after move point. Refactor snap to road.

This commit is contained in:
max-klaus 2020-08-22 16:18:21 +03:00
parent 7a10cf377c
commit efa6c6fb4c
7 changed files with 102 additions and 68 deletions

View file

@ -129,6 +129,13 @@ public class GPXUtilities {
return extensions;
}
public void copyExtensions(GPXExtensions e) {
Map<String, String> extensionsToRead = e.getExtensionsToRead();
if (!extensionsToRead.isEmpty()) {
getExtensionsToWrite().putAll(extensionsToRead);
}
}
public GPXExtensionsWriter getExtensionsWriter() {
return extensionsWriter;
}

View file

@ -37,9 +37,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode.NEXT_SEGMENT;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode.WHOLE_TRACK;
@ -63,11 +61,11 @@ public class MeasurementEditingContext {
private boolean inAddPointMode;
private int calculatedPairs;
private int pointsToCalculateSize;
private CalculationMode calculationMode = WHOLE_TRACK;
private SnapToRoadProgressListener progressListener;
private ApplicationMode appMode = DEFAULT_APP_MODE;
private RouteCalculationProgress calculationProgress;
private final Queue<Pair<WptPt, WptPt>> roadSegmentsToCalculate = new ConcurrentLinkedQueue<>();
private final Map<Pair<WptPt, WptPt>, RoadSegmentData> roadSegmentData = new ConcurrentHashMap<>();
public enum CalculationMode {
@ -334,11 +332,9 @@ public class MeasurementEditingContext {
if (application == null || (before.points.size() == 0 && after.points.size() == 0)) {
return;
}
roadSegmentsToCalculate.clear();
findPointsToCalculate(Arrays.asList(before.points, after.points));
RoutingHelper routingHelper = application.getRoutingHelper();
if (progressListener != null && !routingHelper.isRouteBeingCalculated()) {
RouteCalculationParams params = getParams();
RouteCalculationParams params = getParams(true);
if (params != null) {
routingHelper.startRouteCalculationThread(params, true, true);
application.runInUIThread(new Runnable() {
@ -351,18 +347,20 @@ public class MeasurementEditingContext {
}
}
private void findPointsToCalculate(List<List<WptPt>> pointsList) {
for (List<WptPt> points : pointsList) {
private List<Pair<WptPt, WptPt>> getPointsToCalculate() {
List<Pair<WptPt, WptPt>> res = new ArrayList<>();
for (List<WptPt> points : Arrays.asList(before.points, after.points)) {
for (int i = 0; i < points.size() - 1; i++) {
Pair<WptPt, WptPt> pair = new Pair<>(points.get(i), points.get(i + 1));
if (roadSegmentData.get(pair) == null) {
roadSegmentsToCalculate.add(pair);
res.add(pair);
}
}
}
return res;
}
private void recreateCacheForSnap(TrkSegment cache, TrkSegment original) {
private void recreateCacheForSnap(TrkSegment cache, TrkSegment original, boolean calculateIfNeeded) {
if (original.points.size() > 1) {
for (int i = 0; i < original.points.size() - 1; i++) {
Pair<WptPt, WptPt> pair = new Pair<>(original.points.get(i), original.points.get(i + 1));
@ -371,7 +369,9 @@ public class MeasurementEditingContext {
if (pts != null) {
cache.points.addAll(pts);
} else {
scheduleRouteCalculateIfNotEmpty();
if (calculateIfNeeded) {
scheduleRouteCalculateIfNotEmpty();
}
cache.points.addAll(Arrays.asList(pair.first, pair.second));
}
}
@ -502,26 +502,38 @@ public class MeasurementEditingContext {
}
private void updateCacheForSnap(boolean both) {
recreateCacheForSnap(beforeCacheForSnap = new TrkSegment(), before);
recreateCacheForSnap(beforeCacheForSnap = new TrkSegment(), before, true);
if (both) {
recreateCacheForSnap(afterCacheForSnap = new TrkSegment(), after);
recreateCacheForSnap(afterCacheForSnap = new TrkSegment(), after, true);
}
}
private void updateCacheForSnap(boolean both, boolean calculateIfNeeded) {
recreateCacheForSnap(beforeCacheForSnap = new TrkSegment(), before, calculateIfNeeded);
if (both) {
recreateCacheForSnap(afterCacheForSnap = new TrkSegment(), after, calculateIfNeeded);
}
}
void cancelSnapToRoad() {
progressListener.hideProgressBar();
roadSegmentsToCalculate.clear();
if (calculationProgress != null) {
calculationProgress.isCancelled = true;
}
}
@Nullable
private RouteCalculationParams getParams() {
final Pair<WptPt, WptPt> currentPair = roadSegmentsToCalculate.poll();
if (currentPair == null) {
private RouteCalculationParams getParams(boolean resetCounter) {
List<Pair<WptPt, WptPt>> pointsToCalculate = getPointsToCalculate();
if (Algorithms.isEmpty(pointsToCalculate)) {
return null;
}
if (resetCounter) {
calculatedPairs = 0;
pointsToCalculateSize = pointsToCalculate.size();
}
final Pair<WptPt, WptPt> currentPair = pointsToCalculate.get(0);
Location start = new Location("");
start.setLatitude(currentPair.first.getLatitude());
start.setLongitude(currentPair.first.getLongitude());
@ -536,11 +548,7 @@ public class MeasurementEditingContext {
params.inSnapToRoadMode = true;
params.start = start;
ApplicationMode appMode = calculationMode == NEXT_SEGMENT
? ApplicationMode.valueOfStringKey(currentPair.first.getProfileType(), null) : this.appMode;
if (appMode == null) {
appMode = DEFAULT_APP_MODE;
}
ApplicationMode appMode = ApplicationMode.valueOfStringKey(currentPair.first.getProfileType(), DEFAULT_APP_MODE);
params.end = end;
RoutingHelper.applyApplicationSettings(params, application.getSettings(), appMode);
params.mode = appMode;
@ -554,7 +562,7 @@ public class MeasurementEditingContext {
@Override
public void updateProgress(int progress) {
int pairs = calculatedPairs + roadSegmentsToCalculate.size();
int pairs = calculatedPairs + pointsToCalculateSize;
if (pairs != 0) {
int pairProgress = 100 / pairs;
progress = calculatedPairs * pairProgress + progress / pairs;
@ -569,6 +577,7 @@ public class MeasurementEditingContext {
@Override
public void finish() {
calculatedPairs = 0;
pointsToCalculateSize = 0;
}
};
params.resultListener = new RouteCalculationResultListener() {
@ -596,24 +605,19 @@ public class MeasurementEditingContext {
DEFAULT_APP_MODE.getDefaultSpeed(), new LocationsHolder(pts).getLatLonList()));
}
roadSegmentData.put(currentPair, new RoadSegmentData(route.getAppMode(), currentPair.first, currentPair.second, pts, originalRoute));
updateCacheForSnap(true);
application.runInUIThread(new Runnable() {
@Override
public void run() {
updateCacheForSnap(true, false);
progressListener.refresh();
}
});
RouteCalculationParams params = getParams();
if (params != null) {
application.getRoutingHelper().startRouteCalculationThread(params, true, true);
} else {
application.runInUIThread(new Runnable() {
@Override
public void run() {
RouteCalculationParams params = getParams(false);
if (params != null) {
application.getRoutingHelper().startRouteCalculationThread(params, true, true);
} else {
progressListener.hideProgressBar();
}
});
}
}
});
}
};
return params;

View file

@ -1090,12 +1090,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
switchMovePointMode(false);
MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (measurementLayer != null) {
WptPt newPoint = measurementLayer.getMovedPointToApply();
ApplicationMode applicationMode = editingCtx.getAppMode();
if (applicationMode != MeasurementEditingContext.DEFAULT_APP_MODE) {
newPoint.setProfileType(applicationMode.getStringKey());
}
WptPt oldPoint = editingCtx.getOriginalPointToMove();
WptPt newPoint = measurementLayer.getMovedPointToApply();
int position = editingCtx.getSelectedPointPosition();
editingCtx.getCommandManager().execute(new MovePointCommand(measurementLayer, oldPoint, newPoint, position));
editingCtx.addPoint(newPoint);
@ -1114,8 +1110,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
}
void exitMovePointMode(boolean saveOriginalPoint) {
if (saveOriginalPoint) {
void exitMovePointMode(boolean cancelled) {
if (cancelled) {
WptPt pt = editingCtx.getOriginalPointToMove();
editingCtx.addPoint(pt);
}

View file

@ -342,10 +342,12 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
WptPt getMovedPointToApply() {
RotatedTileBox tb = view.getCurrentRotatedTileBox();
LatLon latLon = tb.getCenterLatLon();
WptPt pt = new WptPt(editingCtx.getOriginalPointToMove());
pt.lat = latLon.getLatitude();
pt.lon = latLon.getLongitude();
return pt;
WptPt originalPoint = editingCtx.getOriginalPointToMove();
WptPt point = new WptPt(originalPoint);
point.lat = latLon.getLatitude();
point.lon = latLon.getLongitude();
point.copyExtensions(originalPoint);
return point;
}
private void moveMapToLatLon(double lat, double lon) {

View file

@ -2,7 +2,9 @@ package net.osmand.plus.measurementtool.command;
import net.osmand.data.LatLon;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementToolLayer;
import net.osmand.plus.settings.backend.ApplicationMode;
public class AddPointCommand extends MeasurementModeCommand {
@ -25,7 +27,10 @@ public class AddPointCommand extends MeasurementModeCommand {
point = new WptPt();
point.lat = latLon.getLatitude();
point.lon = latLon.getLongitude();
point.setProfileType(measurementLayer.getEditingCtx().getAppMode().getStringKey());
ApplicationMode appMode = measurementLayer.getEditingCtx().getAppMode();
if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE) {
point.setProfileType(appMode.getStringKey());
}
}
this.center = center;
position = measurementLayer.getEditingCtx().getPointsCount();

View file

@ -5,19 +5,20 @@ import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementToolLayer;
import net.osmand.plus.settings.backend.ApplicationMode;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.List;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.*;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.DEFAULT_APP_MODE;
public class ChangeRouteModeCommand extends MeasurementModeCommand {
private List<WptPt> points;
int pointIdx;
ApplicationMode oldMode;
ApplicationMode newMode;
CalculationMode oldCalculationMode;
CalculationMode newCalculationMode;
private List<WptPt> oldPoints;
private List<WptPt> newPoints;
private ApplicationMode oldMode;
private ApplicationMode newMode;
private CalculationMode oldCalculationMode;
private CalculationMode newCalculationMode;
public ChangeRouteModeCommand(MeasurementToolLayer measurementLayer, ApplicationMode newMode,
CalculationMode newCalculationMode) {
@ -32,8 +33,25 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand {
@Override
public boolean execute() {
MeasurementEditingContext editingCtx = getEditingCtx();
points = new LinkedList<>(editingCtx.getPoints());
pointIdx = points.size() - 1;
oldPoints = new ArrayList<>(editingCtx.getPoints());
newPoints = new ArrayList<>(oldPoints.size());
if (oldPoints.size() > 0) {
for (WptPt pt : oldPoints) {
WptPt point = new WptPt(pt);
point.copyExtensions(pt);
newPoints.add(point);
}
switch (newCalculationMode) {
case NEXT_SEGMENT:
updateProfileType(newPoints.get(newPoints.size() - 1));
break;
case WHOLE_TRACK:
for (WptPt pt : newPoints) {
updateProfileType(pt);
}
break;
}
}
executeCommand();
return true;
}
@ -42,12 +60,12 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand {
public void undo() {
MeasurementEditingContext editingCtx = getEditingCtx();
editingCtx.getPoints().clear();
editingCtx.addPoints(points);
editingCtx.addPoints(oldPoints);
editingCtx.setCalculationMode(oldCalculationMode);
editingCtx.setAppMode(oldMode);
if (newCalculationMode == CalculationMode.WHOLE_TRACK) {
editingCtx.clearSnappedToRoadPoints();
}
editingCtx.setCalculationMode(oldCalculationMode);
editingCtx.updateCacheForSnap();
}
@ -63,13 +81,8 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand {
private void executeCommand() {
MeasurementEditingContext editingCtx = getEditingCtx();
if (pointIdx > 0 && newCalculationMode != CalculationMode.WHOLE_TRACK) {
if (newMode != null) {
points.get(pointIdx).setProfileType(newMode.getStringKey());
} else {
points.get(pointIdx).removeProfileType();
}
}
editingCtx.getPoints().clear();
editingCtx.addPoints(newPoints);
editingCtx.setCalculationMode(newCalculationMode);
editingCtx.setAppMode(newMode);
if (newCalculationMode == CalculationMode.WHOLE_TRACK) {
@ -77,4 +90,12 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand {
}
editingCtx.updateCacheForSnap();
}
private void updateProfileType(WptPt pt) {
if (newMode != null && newMode != DEFAULT_APP_MODE) {
pt.setProfileType(newMode.getStringKey());
} else {
pt.removeProfileType();
}
}
}

View file

@ -9,8 +9,7 @@ import java.util.List;
public class ClearPointsCommand extends MeasurementModeCommand {
private List<WptPt> points;
private boolean needUpdateCache;
ClearCommandMode clearMode;
private ClearCommandMode clearMode;
private int pointPosition;
public enum ClearCommandMode {