Finished gpx approximation

This commit is contained in:
max-klaus 2020-08-14 17:18:16 +03:00
parent 2ab38a54b5
commit ea83bc6d5d
14 changed files with 265 additions and 116 deletions

View file

@ -310,7 +310,7 @@ public class RoutePlannerFrontEnd {
System.out.println(gctx); System.out.println(gctx);
} }
if (resultMatcher != null) { if (resultMatcher != null) {
resultMatcher.publish(gctx); resultMatcher.publish(gctx.calculationCancelled ? null : gctx);
} }
gctx.calculationDone = true; gctx.calculationDone = true;
return gctx; return gctx;

View file

@ -31,8 +31,6 @@ import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import java.io.IOException;
import static net.osmand.plus.measurementtool.ProfileCard.ProfileCardListener; import static net.osmand.plus.measurementtool.ProfileCard.ProfileCardListener;
import static net.osmand.plus.measurementtool.SliderCard.SliderCardListener; import static net.osmand.plus.measurementtool.SliderCard.SliderCardListener;
@ -40,7 +38,7 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
implements SliderCardListener, ProfileCardListener { implements SliderCardListener, ProfileCardListener {
private static final Log LOG = PlatformUtil.getLog(GpxApproximationFragment.class); private static final Log LOG = PlatformUtil.getLog(GpxApproximationFragment.class);
public static final String TAG = GpxApproximationFragment.class.getSimpleName(); public static final String TAG = GpxApproximationFragment.class.getName();
public static final String DISTANCE_THRESHOLD_KEY = "distance_threshold"; public static final String DISTANCE_THRESHOLD_KEY = "distance_threshold";
public static final String SNAP_TO_ROAD_APP_MODE_STRING_KEY = "snap_to_road_app_mode"; public static final String SNAP_TO_ROAD_APP_MODE_STRING_KEY = "snap_to_road_app_mode";
@ -49,11 +47,14 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
private int menuTitleHeight; private int menuTitleHeight;
private ApplicationMode snapToRoadAppMode = ApplicationMode.CAR; private ApplicationMode snapToRoadAppMode = ApplicationMode.CAR;
private int distanceThreshold = 50; private int distanceThreshold = 50;
private boolean applyApproximation;
private LocationsHolder locationsHolder; private LocationsHolder locationsHolder;
@Nullable @Nullable
private GpxApproximator gpxApproximator; private GpxApproximator gpxApproximator;
private ProgressBar progressBar; private ProgressBar progressBar;
private View cancelButton;
private View applyButton;
@Override @Override
public int getMainLayoutId() { public int getMainLayoutId() {
@ -139,6 +140,8 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
}); });
} }
applyButton = mainView.findViewById(R.id.right_bottom_button);
cancelButton = mainView.findViewById(R.id.dismiss_button);
if (isPortrait()) { if (isPortrait()) {
updateCardsLayout(); updateCardsLayout();
} }
@ -182,12 +185,17 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
if (gpxApproximator != null) {
gpxApproximator.cancelApproximation();
}
exitGpxApproximationMode(); exitGpxApproximationMode();
if (!applyApproximation) {
Fragment fragment = getTargetFragment(); Fragment fragment = getTargetFragment();
if (fragment instanceof GpxApproximationFragmentListener) { if (fragment instanceof GpxApproximationFragmentListener) {
((GpxApproximationFragmentListener) fragment).onCancelGpxApproximation(); ((GpxApproximationFragmentListener) fragment).onCancelGpxApproximation();
} }
} }
}
private void updateCardsLayout() { private void updateCardsLayout() {
View mainView = getMainView(); View mainView = getMainView();
@ -213,7 +221,6 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
private void updateButtons(View view) { private void updateButtons(View view) {
View buttonsContainer = view.findViewById(R.id.buttons_container); View buttonsContainer = view.findViewById(R.id.buttons_container);
buttonsContainer.setBackgroundColor(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.route_info_bg)); buttonsContainer.setBackgroundColor(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.route_info_bg));
View applyButton = view.findViewById(R.id.right_bottom_button);
applyButton.setOnClickListener(new View.OnClickListener() { applyButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -221,11 +228,10 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
if (fragment instanceof GpxApproximationFragmentListener) { if (fragment instanceof GpxApproximationFragmentListener) {
((GpxApproximationFragmentListener) fragment).onApplyGpxApproximation(); ((GpxApproximationFragmentListener) fragment).onApplyGpxApproximation();
} }
applyApproximation = true;
dismiss(); dismiss();
} }
}); });
View cancelButton = view.findViewById(R.id.dismiss_button);
cancelButton.setOnClickListener(new View.OnClickListener() { cancelButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -235,14 +241,18 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
} }
} }
}); });
UiUtilities.setupDialogButton(isNightMode(), cancelButton, UiUtilities.DialogButtonType.SECONDARY, R.string.shared_string_cancel); UiUtilities.setupDialogButton(isNightMode(), cancelButton, UiUtilities.DialogButtonType.SECONDARY, R.string.shared_string_cancel);
UiUtilities.setupDialogButton(isNightMode(), applyButton, UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_apply); UiUtilities.setupDialogButton(isNightMode(), applyButton, UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_apply);
AndroidUiHelper.updateVisibility(applyButton, true); AndroidUiHelper.updateVisibility(applyButton, true);
AndroidUiHelper.updateVisibility(view.findViewById(R.id.buttons_divider), true); AndroidUiHelper.updateVisibility(view.findViewById(R.id.buttons_divider), true);
} }
private void setApplyButtonEnabled(boolean enabled) {
if (applyButton != null) {
applyButton.setEnabled(enabled);
}
}
private void updateCards() { private void updateCards() {
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (mapActivity != null) { if (mapActivity != null) {
@ -328,15 +338,19 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
@Override @Override
public void onSliderChange(int sliderValue) { public void onSliderChange(int sliderValue) {
if (distanceThreshold != sliderValue) {
distanceThreshold = sliderValue; distanceThreshold = sliderValue;
calculateGpxApproximation(); calculateGpxApproximation();
} }
}
@Override @Override
public void onProfileSelect(ApplicationMode applicationMode) { public void onProfileSelect(ApplicationMode applicationMode) {
if (snapToRoadAppMode != applicationMode) {
snapToRoadAppMode = applicationMode; snapToRoadAppMode = applicationMode;
calculateGpxApproximation(); calculateGpxApproximation();
} }
}
public LocationsHolder getLocationsHolder() { public LocationsHolder getLocationsHolder() {
return locationsHolder; return locationsHolder;
@ -370,6 +384,7 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
private void approximateGpx() { private void approximateGpx() {
if (gpxApproximator != null) { if (gpxApproximator != null) {
setApplyButtonEnabled(false);
gpxApproximator.calculateGpxApproximation(new ResultMatcher<GpxRouteApproximation>() { gpxApproximator.calculateGpxApproximation(new ResultMatcher<GpxRouteApproximation>() {
@Override @Override
public boolean publish(final GpxRouteApproximation gpxApproximation) { public boolean publish(final GpxRouteApproximation gpxApproximation) {
@ -380,8 +395,9 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
public void run() { public void run() {
Fragment fragment = getTargetFragment(); Fragment fragment = getTargetFragment();
if (fragment instanceof GpxApproximationFragmentListener) { if (fragment instanceof GpxApproximationFragmentListener) {
((GpxApproximationFragmentListener) fragment).onGpxApproximationDone(gpxApproximation); ((GpxApproximationFragmentListener) fragment).onGpxApproximationDone(gpxApproximation, gpxApproximator.getMode());
} }
setApplyButtonEnabled(gpxApproximation != null);
} }
}); });
return true; return true;
@ -399,7 +415,7 @@ public class GpxApproximationFragment extends ContextMenuScrollFragment
public interface GpxApproximationFragmentListener { public interface GpxApproximationFragmentListener {
void onGpxApproximationDone(GpxRouteApproximation gpxApproximation); void onGpxApproximationDone(GpxRouteApproximation gpxApproximation, ApplicationMode mode);
void onApplyGpxApproximation(); void onApplyGpxApproximation();

View file

@ -17,7 +17,6 @@ import net.osmand.plus.routing.RouteCalculationResult;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.router.RouteCalculationProgress; import net.osmand.router.RouteCalculationProgress;
import net.osmand.router.RoutePlannerFrontEnd;
import net.osmand.router.RoutePlannerFrontEnd.GpxPoint; import net.osmand.router.RoutePlannerFrontEnd.GpxPoint;
import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation; import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation;
import net.osmand.router.RouteSegmentResult; import net.osmand.router.RouteSegmentResult;
@ -32,7 +31,7 @@ import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationType.*; import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationType.WHOLE_TRACK;
public class MeasurementEditingContext { public class MeasurementEditingContext {
@ -111,7 +110,7 @@ public class MeasurementEditingContext {
this.inAddPointMode = inAddPointMode; this.inAddPointMode = inAddPointMode;
} }
void setInSnapToRoadMode(boolean inSnapToRoadMode) { public void setInSnapToRoadMode(boolean inSnapToRoadMode) {
this.inSnapToRoadMode = inSnapToRoadMode; this.inSnapToRoadMode = inSnapToRoadMode;
} }
@ -147,7 +146,7 @@ public class MeasurementEditingContext {
return snapToRoadAppMode; return snapToRoadAppMode;
} }
void setSnapToRoadAppMode(ApplicationMode snapToRoadAppMode) { public void setSnapToRoadAppMode(ApplicationMode snapToRoadAppMode) {
if (this.snapToRoadAppMode != null && snapToRoadAppMode != null if (this.snapToRoadAppMode != null && snapToRoadAppMode != null
&& !this.snapToRoadAppMode.getStringKey().equals(snapToRoadAppMode.getStringKey())) { && !this.snapToRoadAppMode.getStringKey().equals(snapToRoadAppMode.getStringKey())) {
if (calculationType == WHOLE_TRACK) { if (calculationType == WHOLE_TRACK) {
@ -327,27 +326,39 @@ public class MeasurementEditingContext {
} }
} }
void setPoints(GpxRouteApproximation gpxApproximation) { public void setPoints(GpxRouteApproximation gpxApproximation) {
if (gpxApproximation == null || Algorithms.isEmpty(gpxApproximation.finalPoints) || Algorithms.isEmpty(gpxApproximation.result)) { if (gpxApproximation == null || Algorithms.isEmpty(gpxApproximation.finalPoints) || Algorithms.isEmpty(gpxApproximation.result)) {
return; return;
} }
clearSegments(); snappedToRoadPoints.clear();
List<GpxPoint> routePoints = gpxApproximation.finalPoints; List<WptPt> routePoints = new ArrayList<>();
for (int i = 0; i < routePoints.size() - 1; i++) { List<GpxPoint> gpxPoints = gpxApproximation.finalPoints;
GpxPoint rp1 = routePoints.get(i); for (int i = 0; i < gpxPoints.size() - 1; i++) {
GpxPoint rp2 = routePoints.get(i + 1); GpxPoint rp1 = gpxPoints.get(i);
GpxPoint rp2 = gpxPoints.get(i + 1);
WptPt p1 = new WptPt(); WptPt p1 = new WptPt();
p1.lat = rp1.loc.getLatitude(); p1.lat = rp1.loc.getLatitude();
p1.lon = rp1.loc.getLongitude(); p1.lon = rp1.loc.getLongitude();
if (i == 0) {
routePoints.add(p1);
}
WptPt p2 = new WptPt(); WptPt p2 = new WptPt();
p2.lat = rp2.loc.getLatitude(); p2.lat = rp2.loc.getLatitude();
p2.lon = rp2.loc.getLongitude(); p2.lon = rp2.loc.getLongitude();
routePoints.add(p2);
Pair<WptPt, WptPt> pair = new Pair<>(p1, p2); Pair<WptPt, WptPt> pair = new Pair<>(p1, p2);
List<WptPt> cacheSegment = new ArrayList<>(); List<WptPt> cacheSegment = new ArrayList<>();
for (RouteSegmentResult seg : rp1.routeToTarget) { for (RouteSegmentResult seg : rp1.routeToTarget) {
int start = seg.isForwardDirection() ? seg.getStartPointIndex() : seg.getEndPointIndex(); if (seg.isForwardDirection()) {
int end = seg.isForwardDirection() ? seg.getEndPointIndex() : seg.getStartPointIndex(); for (int ik = seg.getStartPointIndex(); ik <= seg.getEndPointIndex(); ik++) {
for (int ik = start; ik <= end; ik++) { LatLon l = seg.getPoint(ik);
WptPt pt = new WptPt();
pt.lat = l.getLatitude();
pt.lon = l.getLongitude();
cacheSegment.add(pt);
}
} else {
for (int ik = seg.getEndPointIndex(); ik >= seg.getStartPointIndex(); ik--) {
LatLon l = seg.getPoint(ik); LatLon l = seg.getPoint(ik);
WptPt pt = new WptPt(); WptPt pt = new WptPt();
pt.lat = l.getLatitude(); pt.lat = l.getLatitude();
@ -355,8 +366,10 @@ public class MeasurementEditingContext {
cacheSegment.add(pt); cacheSegment.add(pt);
} }
} }
}
snappedToRoadPoints.put(pair, cacheSegment); snappedToRoadPoints.put(pair, cacheSegment);
} }
addPoints(routePoints);
} }
private int findPointIndex(WptPt point, List<WptPt> points, int firstIndex) { private int findPointIndex(WptPt point, List<WptPt> points, int firstIndex) {

View file

@ -70,6 +70,7 @@ import net.osmand.plus.measurementtool.SelectedPointBottomSheetDialogFragment.Se
import net.osmand.plus.measurementtool.adapter.MeasurementToolAdapter; import net.osmand.plus.measurementtool.adapter.MeasurementToolAdapter;
import net.osmand.plus.measurementtool.adapter.MeasurementToolAdapter.MeasurementAdapterListener; import net.osmand.plus.measurementtool.adapter.MeasurementToolAdapter.MeasurementAdapterListener;
import net.osmand.plus.measurementtool.command.AddPointCommand; import net.osmand.plus.measurementtool.command.AddPointCommand;
import net.osmand.plus.measurementtool.command.ApplyGpxApproximationCommand;
import net.osmand.plus.measurementtool.command.ClearPointsCommand; import net.osmand.plus.measurementtool.command.ClearPointsCommand;
import net.osmand.plus.measurementtool.command.MovePointCommand; import net.osmand.plus.measurementtool.command.MovePointCommand;
import net.osmand.plus.measurementtool.command.RemovePointCommand; import net.osmand.plus.measurementtool.command.RemovePointCommand;
@ -477,7 +478,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
} }
private void initMeasurementMode(NewGpxData newGpxData) { private void initMeasurementMode(NewGpxData newGpxData) {
editingCtx.getCommandManager().resetMeasurementLayer(getMapActivity().getMapLayers().getMeasurementToolLayer()); MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
editingCtx.getCommandManager().setMeasurementLayer(mapActivity.getMapLayers().getMeasurementToolLayer());
enterMeasurementMode(); enterMeasurementMode();
showSnapToRoadControls(); showSnapToRoadControls();
if (newGpxData != null && !gpxPointsAdded) { if (newGpxData != null && !gpxPointsAdded) {
@ -504,6 +507,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|| newGpxData.getActionType() == ActionType.EDIT_SEGMENT); || newGpxData.getActionType() == ActionType.EDIT_SEGMENT);
} }
} }
}
@Override @Override
public void onResume() { public void onResume() {
@ -547,7 +551,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Nullable @Nullable
private MapActivity getMapActivity() { private MapActivity getMapActivity() {
Activity activity = getActivity(); Activity activity = getActivity();
if (activity instanceof MapActivity && !activity.isFinishing()) { if (AndroidUtils.isActivityNotDestroyed(activity)) {
return (MapActivity) activity; return (MapActivity) activity;
} }
return null; return null;
@ -601,7 +605,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
toolBarController.setTitle(getString(R.string.route_between_points)); toolBarController.setTitle(getString(R.string.route_between_points));
mapActivity.refreshMap(); mapActivity.refreshMap();
if (editingCtx.isNewData() || editingCtx.hasRoutePoints()) { if (editingCtx.isNewData() || editingCtx.hasRoutePoints() || editingCtx.isInSnapToRoadMode()) {
RouteBetweenPointsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(), RouteBetweenPointsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
this, editingCtx.getCalculationType(), this, editingCtx.getCalculationType(),
editingCtx.getSnapToRoadAppMode()); editingCtx.getSnapToRoadAppMode());
@ -1057,15 +1061,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
} }
} }
public void displayApproximatedPoints(GpxRouteApproximation gpxApproximation) {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (measurementLayer != null) {
editingCtx.setPoints(gpxApproximation);
adapter.notifyDataSetChanged();
updateDistancePointsText();
}
}
private void openSelectedPointMenu(MapActivity mapActivity) { private void openSelectedPointMenu(MapActivity mapActivity) {
SelectedPointBottomSheetDialogFragment fragment = new SelectedPointBottomSheetDialogFragment(); SelectedPointBottomSheetDialogFragment fragment = new SelectedPointBottomSheetDialogFragment();
fragment.setUsedOnMap(true); fragment.setUsedOnMap(true);
@ -1929,17 +1924,28 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
} }
@Override @Override
public void onGpxApproximationDone(GpxRouteApproximation gpxApproximation) { public void onGpxApproximationDone(GpxRouteApproximation gpxApproximation, ApplicationMode mode) {
displayApproximatedPoints(gpxApproximation); MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (measurementLayer != null) {
ApplyGpxApproximationCommand command = new ApplyGpxApproximationCommand(measurementLayer, gpxApproximation, mode);
if (!editingCtx.getCommandManager().update(command)) {
editingCtx.getCommandManager().execute(command);
}
if (pointsListOpened) {
hidePointsList();
}
showSnapToRoadControls();
}
} }
@Override @Override
public void onApplyGpxApproximation() { public void onApplyGpxApproximation() {
doAddOrMovePointCommonStuff();
} }
@Override @Override
public void onCancelGpxApproximation() { public void onCancelGpxApproximation() {
editingCtx.getCommandManager().undo();
showSnapToRoadControls();
} }
} }

View file

@ -11,15 +11,16 @@ public class AddPointCommand extends MeasurementModeCommand {
private boolean center; private boolean center;
public AddPointCommand(MeasurementToolLayer measurementLayer, boolean center) { public AddPointCommand(MeasurementToolLayer measurementLayer, boolean center) {
super(measurementLayer);
init(measurementLayer, null, center); init(measurementLayer, null, center);
} }
public AddPointCommand(MeasurementToolLayer measurementLayer, LatLon latLon) { public AddPointCommand(MeasurementToolLayer measurementLayer, LatLon latLon) {
super(measurementLayer);
init(measurementLayer, latLon, false); init(measurementLayer, latLon, false);
} }
private void init(MeasurementToolLayer measurementLayer, LatLon latLon, boolean center) { private void init(MeasurementToolLayer measurementLayer, LatLon latLon, boolean center) {
this.measurementLayer = measurementLayer;
if (latLon != null) { if (latLon != null) {
point = new WptPt(); point = new WptPt();
point.lat = latLon.getLatitude(); point.lat = latLon.getLatitude();
@ -32,27 +33,27 @@ public class AddPointCommand extends MeasurementModeCommand {
@Override @Override
public boolean execute() { public boolean execute() {
if (point != null) { if (point != null) {
measurementLayer.getEditingCtx().addPoint(point); getEditingCtx().addPoint(point);
measurementLayer.moveMapToPoint(position); measurementLayer.moveMapToPoint(position);
} else if (center) { } else if (center) {
point = measurementLayer.addCenterPoint(); point = measurementLayer.addCenterPoint();
} else { } else {
point = measurementLayer.addPoint(); point = measurementLayer.addPoint();
} }
measurementLayer.refreshMap(); refreshMap();
return point != null; return point != null;
} }
@Override @Override
public void undo() { public void undo() {
measurementLayer.getEditingCtx().removePoint(position, true); getEditingCtx().removePoint(position, true);
measurementLayer.refreshMap(); refreshMap();
} }
@Override @Override
public void redo() { public void redo() {
measurementLayer.getEditingCtx().addPoint(position, point); getEditingCtx().addPoint(position, point);
measurementLayer.refreshMap(); refreshMap();
measurementLayer.moveMapToPoint(position); measurementLayer.moveMapToPoint(position);
} }

View file

@ -0,0 +1,77 @@
package net.osmand.plus.measurementtool.command;
import androidx.annotation.NonNull;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementToolLayer;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation;
import java.util.ArrayList;
import java.util.List;
public class ApplyGpxApproximationCommand extends MeasurementModeCommand {
private ApplicationMode mode;
private GpxRouteApproximation approximation;
private List<WptPt> points;
private boolean needUpdateCache;
public ApplyGpxApproximationCommand(MeasurementToolLayer measurementLayer, GpxRouteApproximation approximation, ApplicationMode mode) {
super(measurementLayer);
this.approximation = approximation;
this.mode = mode;
}
@Override
MeasurementCommandType getType() {
return MeasurementCommandType.APPROXIMATE_POINTS;
}
@Override
public boolean execute() {
List<WptPt> pts = getEditingCtx().getPoints();
needUpdateCache = getEditingCtx().isNeedUpdateCacheForSnap();
points = new ArrayList<>(pts);
applyApproximation();
refreshMap();
return true;
}
@Override
public boolean update(@NonNull Command command) {
if (command instanceof ApplyGpxApproximationCommand) {
ApplyGpxApproximationCommand approxCommand = (ApplyGpxApproximationCommand) command;
approximation = approxCommand.approximation;
applyApproximation();
refreshMap();
return true;
}
return false;
}
@Override
public void undo() {
getEditingCtx().setInSnapToRoadMode(false);
getEditingCtx().clearSegments();
getEditingCtx().setSnapToRoadAppMode(null);
getEditingCtx().addPoints(points);
if (needUpdateCache) {
getEditingCtx().setNeedUpdateCacheForSnap(true);
}
refreshMap();
}
@Override
public void redo() {
applyApproximation();
refreshMap();
}
public void applyApproximation() {
getEditingCtx().setInSnapToRoadMode(true);
getEditingCtx().clearSegments();
getEditingCtx().setSnapToRoadAppMode(mode);
getEditingCtx().setPoints(approximation);
}
}

View file

@ -3,6 +3,7 @@ package net.osmand.plus.measurementtool.command;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementToolLayer; import net.osmand.plus.measurementtool.MeasurementToolLayer;
import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -12,33 +13,33 @@ public class ClearPointsCommand extends MeasurementModeCommand {
private boolean needUpdateCache; private boolean needUpdateCache;
public ClearPointsCommand(MeasurementToolLayer measurementLayer) { public ClearPointsCommand(MeasurementToolLayer measurementLayer) {
this.measurementLayer = measurementLayer; super(measurementLayer);
} }
@Override @Override
public boolean execute() { public boolean execute() {
List<WptPt> pts = measurementLayer.getEditingCtx().getPoints(); List<WptPt> pts = getEditingCtx().getPoints();
needUpdateCache = measurementLayer.getEditingCtx().isNeedUpdateCacheForSnap(); needUpdateCache = getEditingCtx().isNeedUpdateCacheForSnap();
points = new LinkedList<>(pts); points = new ArrayList<>(pts);
pts.clear(); pts.clear();
measurementLayer.getEditingCtx().clearSegments(); getEditingCtx().clearSegments();
measurementLayer.refreshMap(); refreshMap();
return true; return true;
} }
@Override @Override
public void undo() { public void undo() {
measurementLayer.getEditingCtx().addPoints(points); getEditingCtx().addPoints(points);
if (needUpdateCache) { if (needUpdateCache) {
measurementLayer.getEditingCtx().setNeedUpdateCacheForSnap(true); getEditingCtx().setNeedUpdateCacheForSnap(true);
} }
measurementLayer.refreshMap(); refreshMap();
} }
@Override @Override
public void redo() { public void redo() {
measurementLayer.getEditingCtx().clearSegments(); getEditingCtx().clearSegments();
measurementLayer.refreshMap(); refreshMap();
} }
@Override @Override

View file

@ -1,9 +1,13 @@
package net.osmand.plus.measurementtool.command; package net.osmand.plus.measurementtool.command;
import androidx.annotation.NonNull;
interface Command { interface Command {
boolean execute(); boolean execute();
boolean update(@NonNull Command command);
void undo(); void undo();
void redo(); void redo();

View file

@ -30,6 +30,11 @@ public class MeasurementCommandManager {
return false; return false;
} }
public boolean update(MeasurementModeCommand command) {
MeasurementModeCommand prevCommand = undoCommands.peek();
return prevCommand != null && prevCommand.update(command);
}
@Nullable @Nullable
public MeasurementCommandType undo() { public MeasurementCommandType undo() {
if (canUndo()) { if (canUndo()) {
@ -52,7 +57,7 @@ public class MeasurementCommandManager {
return null; return null;
} }
public void resetMeasurementLayer(MeasurementToolLayer layer) { public void setMeasurementLayer(MeasurementToolLayer layer) {
for (MeasurementModeCommand command : undoCommands) { for (MeasurementModeCommand command : undoCommands) {
command.setMeasurementLayer(layer); command.setMeasurementLayer(layer);
} }

View file

@ -1,23 +1,44 @@
package net.osmand.plus.measurementtool.command; package net.osmand.plus.measurementtool.command;
import androidx.annotation.NonNull;
import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementToolLayer; import net.osmand.plus.measurementtool.MeasurementToolLayer;
public abstract class MeasurementModeCommand implements Command { public abstract class MeasurementModeCommand implements Command {
MeasurementToolLayer measurementLayer; MeasurementToolLayer measurementLayer;
public MeasurementModeCommand(MeasurementToolLayer measurementLayer) {
this.measurementLayer = measurementLayer;
}
void setMeasurementLayer(MeasurementToolLayer layer) { void setMeasurementLayer(MeasurementToolLayer layer) {
this.measurementLayer = layer; this.measurementLayer = layer;
} }
@Override
public boolean update(@NonNull Command command) {
return false;
}
abstract MeasurementCommandType getType(); abstract MeasurementCommandType getType();
MeasurementEditingContext getEditingCtx() {
return measurementLayer.getEditingCtx();
}
void refreshMap() {
measurementLayer.refreshMap();
}
public enum MeasurementCommandType { public enum MeasurementCommandType {
ADD_POINT, ADD_POINT,
CLEAR_POINTS, CLEAR_POINTS,
MOVE_POINT, MOVE_POINT,
REMOVE_POINT, REMOVE_POINT,
REORDER_POINT, REORDER_POINT,
SNAP_TO_ROAD SNAP_TO_ROAD,
APPROXIMATE_POINTS
} }
} }

View file

@ -10,7 +10,7 @@ public class MovePointCommand extends MeasurementModeCommand {
private final int position; private final int position;
public MovePointCommand(MeasurementToolLayer measurementLayer, WptPt oldPoint, WptPt newPoint, int position) { public MovePointCommand(MeasurementToolLayer measurementLayer, WptPt oldPoint, WptPt newPoint, int position) {
this.measurementLayer = measurementLayer; super(measurementLayer);
this.oldPoint = oldPoint; this.oldPoint = oldPoint;
this.newPoint = newPoint; this.newPoint = newPoint;
this.position = position; this.position = position;
@ -23,16 +23,16 @@ public class MovePointCommand extends MeasurementModeCommand {
@Override @Override
public void undo() { public void undo() {
measurementLayer.getEditingCtx().removePoint(position, false); getEditingCtx().removePoint(position, false);
measurementLayer.getEditingCtx().addPoint(position, oldPoint); getEditingCtx().addPoint(position, oldPoint);
measurementLayer.refreshMap(); refreshMap();
} }
@Override @Override
public void redo() { public void redo() {
measurementLayer.getEditingCtx().removePoint(position, false); getEditingCtx().removePoint(position, false);
measurementLayer.getEditingCtx().addPoint(position, newPoint); getEditingCtx().addPoint(position, newPoint);
measurementLayer.refreshMap(); refreshMap();
} }
@Override @Override

View file

@ -9,28 +9,28 @@ public class RemovePointCommand extends MeasurementModeCommand {
private WptPt point; private WptPt point;
public RemovePointCommand(MeasurementToolLayer measurementLayer, int position) { public RemovePointCommand(MeasurementToolLayer measurementLayer, int position) {
this.measurementLayer = measurementLayer; super(measurementLayer);
this.position = position; this.position = position;
} }
@Override @Override
public boolean execute() { public boolean execute() {
point = measurementLayer.getEditingCtx().removePoint(position, true); point = getEditingCtx().removePoint(position, true);
measurementLayer.refreshMap(); refreshMap();
return true; return true;
} }
@Override @Override
public void undo() { public void undo() {
measurementLayer.getEditingCtx().addPoint(position, point); getEditingCtx().addPoint(position, point);
measurementLayer.refreshMap(); refreshMap();
measurementLayer.moveMapToPoint(position); measurementLayer.moveMapToPoint(position);
} }
@Override @Override
public void redo() { public void redo() {
measurementLayer.getEditingCtx().removePoint(position, true); getEditingCtx().removePoint(position, true);
measurementLayer.refreshMap(); refreshMap();
} }
@Override @Override

View file

@ -11,15 +11,15 @@ public class ReorderPointCommand extends MeasurementModeCommand {
private final int to; private final int to;
public ReorderPointCommand(MeasurementToolLayer measurementLayer, int from, int to) { public ReorderPointCommand(MeasurementToolLayer measurementLayer, int from, int to) {
this.measurementLayer = measurementLayer; super(measurementLayer);
this.from = from; this.from = from;
this.to = to; this.to = to;
} }
@Override @Override
public boolean execute() { public boolean execute() {
measurementLayer.getEditingCtx().setNeedUpdateCacheForSnap(true); getEditingCtx().setNeedUpdateCacheForSnap(true);
measurementLayer.refreshMap(); refreshMap();
return true; return true;
} }
@ -34,10 +34,10 @@ public class ReorderPointCommand extends MeasurementModeCommand {
} }
private void reorder(int addTo, int removeFrom) { private void reorder(int addTo, int removeFrom) {
List<WptPt> points = measurementLayer.getEditingCtx().getPoints(); List<WptPt> points = getEditingCtx().getPoints();
points.add(addTo, points.remove(removeFrom)); points.add(addTo, points.remove(removeFrom));
measurementLayer.getEditingCtx().setNeedUpdateCacheForSnap(true); getEditingCtx().setNeedUpdateCacheForSnap(true);
measurementLayer.refreshMap(); refreshMap();
} }
@Override @Override

View file

@ -112,9 +112,8 @@ public class GpxApproximator {
} }
public void setMode(ApplicationMode mode) throws IOException { public void setMode(ApplicationMode mode) throws IOException {
boolean changed = this.mode != mode; if (this.mode != mode) {
this.mode = mode; this.mode = mode;
if (changed) {
prepareEnvironment(ctx, mode); prepareEnvironment(ctx, mode);
} }
} }
@ -139,6 +138,12 @@ public class GpxApproximator {
this.approximationProgress = approximationProgress; this.approximationProgress = approximationProgress;
} }
public void cancelApproximation() {
if (gctx != null) {
gctx.calculationCancelled = true;
}
}
public void calculateGpxApproximation(@NonNull final ResultMatcher<GpxRouteApproximation> resultMatcher) { public void calculateGpxApproximation(@NonNull final ResultMatcher<GpxRouteApproximation> resultMatcher) {
if (gctx != null) { if (gctx != null) {
gctx.calculationCancelled = true; gctx.calculationCancelled = true;