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; return extensions;
} }
public void copyExtensions(GPXExtensions e) {
Map<String, String> extensionsToRead = e.getExtensionsToRead();
if (!extensionsToRead.isEmpty()) {
getExtensionsToWrite().putAll(extensionsToRead);
}
}
public GPXExtensionsWriter getExtensionsWriter() { public GPXExtensionsWriter getExtensionsWriter() {
return extensionsWriter; return extensionsWriter;
} }

View file

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

View file

@ -1090,12 +1090,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
switchMovePointMode(false); switchMovePointMode(false);
MeasurementToolLayer measurementLayer = getMeasurementLayer(); MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (measurementLayer != null) { 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 oldPoint = editingCtx.getOriginalPointToMove();
WptPt newPoint = measurementLayer.getMovedPointToApply();
int position = editingCtx.getSelectedPointPosition(); int position = editingCtx.getSelectedPointPosition();
editingCtx.getCommandManager().execute(new MovePointCommand(measurementLayer, oldPoint, newPoint, position)); editingCtx.getCommandManager().execute(new MovePointCommand(measurementLayer, oldPoint, newPoint, position));
editingCtx.addPoint(newPoint); editingCtx.addPoint(newPoint);
@ -1114,8 +1110,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
} }
} }
void exitMovePointMode(boolean saveOriginalPoint) { void exitMovePointMode(boolean cancelled) {
if (saveOriginalPoint) { if (cancelled) {
WptPt pt = editingCtx.getOriginalPointToMove(); WptPt pt = editingCtx.getOriginalPointToMove();
editingCtx.addPoint(pt); editingCtx.addPoint(pt);
} }

View file

@ -342,10 +342,12 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
WptPt getMovedPointToApply() { WptPt getMovedPointToApply() {
RotatedTileBox tb = view.getCurrentRotatedTileBox(); RotatedTileBox tb = view.getCurrentRotatedTileBox();
LatLon latLon = tb.getCenterLatLon(); LatLon latLon = tb.getCenterLatLon();
WptPt pt = new WptPt(editingCtx.getOriginalPointToMove()); WptPt originalPoint = editingCtx.getOriginalPointToMove();
pt.lat = latLon.getLatitude(); WptPt point = new WptPt(originalPoint);
pt.lon = latLon.getLongitude(); point.lat = latLon.getLatitude();
return pt; point.lon = latLon.getLongitude();
point.copyExtensions(originalPoint);
return point;
} }
private void moveMapToLatLon(double lat, double lon) { 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.data.LatLon;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementToolLayer; import net.osmand.plus.measurementtool.MeasurementToolLayer;
import net.osmand.plus.settings.backend.ApplicationMode;
public class AddPointCommand extends MeasurementModeCommand { public class AddPointCommand extends MeasurementModeCommand {
@ -25,7 +27,10 @@ public class AddPointCommand extends MeasurementModeCommand {
point = new WptPt(); point = new WptPt();
point.lat = latLon.getLatitude(); point.lat = latLon.getLatitude();
point.lon = latLon.getLongitude(); 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; this.center = center;
position = measurementLayer.getEditingCtx().getPointsCount(); 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.measurementtool.MeasurementToolLayer;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import java.util.LinkedList; import java.util.ArrayList;
import java.util.List; 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 { public class ChangeRouteModeCommand extends MeasurementModeCommand {
private List<WptPt> points; private List<WptPt> oldPoints;
int pointIdx; private List<WptPt> newPoints;
ApplicationMode oldMode; private ApplicationMode oldMode;
ApplicationMode newMode; private ApplicationMode newMode;
CalculationMode oldCalculationMode; private CalculationMode oldCalculationMode;
CalculationMode newCalculationMode; private CalculationMode newCalculationMode;
public ChangeRouteModeCommand(MeasurementToolLayer measurementLayer, ApplicationMode newMode, public ChangeRouteModeCommand(MeasurementToolLayer measurementLayer, ApplicationMode newMode,
CalculationMode newCalculationMode) { CalculationMode newCalculationMode) {
@ -32,8 +33,25 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand {
@Override @Override
public boolean execute() { public boolean execute() {
MeasurementEditingContext editingCtx = getEditingCtx(); MeasurementEditingContext editingCtx = getEditingCtx();
points = new LinkedList<>(editingCtx.getPoints()); oldPoints = new ArrayList<>(editingCtx.getPoints());
pointIdx = points.size() - 1; 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(); executeCommand();
return true; return true;
} }
@ -42,12 +60,12 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand {
public void undo() { public void undo() {
MeasurementEditingContext editingCtx = getEditingCtx(); MeasurementEditingContext editingCtx = getEditingCtx();
editingCtx.getPoints().clear(); editingCtx.getPoints().clear();
editingCtx.addPoints(points); editingCtx.addPoints(oldPoints);
editingCtx.setCalculationMode(oldCalculationMode);
editingCtx.setAppMode(oldMode); editingCtx.setAppMode(oldMode);
if (newCalculationMode == CalculationMode.WHOLE_TRACK) { if (newCalculationMode == CalculationMode.WHOLE_TRACK) {
editingCtx.clearSnappedToRoadPoints(); editingCtx.clearSnappedToRoadPoints();
} }
editingCtx.setCalculationMode(oldCalculationMode);
editingCtx.updateCacheForSnap(); editingCtx.updateCacheForSnap();
} }
@ -63,13 +81,8 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand {
private void executeCommand() { private void executeCommand() {
MeasurementEditingContext editingCtx = getEditingCtx(); MeasurementEditingContext editingCtx = getEditingCtx();
if (pointIdx > 0 && newCalculationMode != CalculationMode.WHOLE_TRACK) { editingCtx.getPoints().clear();
if (newMode != null) { editingCtx.addPoints(newPoints);
points.get(pointIdx).setProfileType(newMode.getStringKey());
} else {
points.get(pointIdx).removeProfileType();
}
}
editingCtx.setCalculationMode(newCalculationMode); editingCtx.setCalculationMode(newCalculationMode);
editingCtx.setAppMode(newMode); editingCtx.setAppMode(newMode);
if (newCalculationMode == CalculationMode.WHOLE_TRACK) { if (newCalculationMode == CalculationMode.WHOLE_TRACK) {
@ -77,4 +90,12 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand {
} }
editingCtx.updateCacheForSnap(); 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 { public class ClearPointsCommand extends MeasurementModeCommand {
private List<WptPt> points; private List<WptPt> points;
private boolean needUpdateCache; private ClearCommandMode clearMode;
ClearCommandMode clearMode;
private int pointPosition; private int pointPosition;
public enum ClearCommandMode { public enum ClearCommandMode {