diff --git a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java index a7302f7544..18ebc9b688 100644 --- a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java +++ b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java @@ -330,6 +330,15 @@ public class GPXUtilities { return profileType != null && !GAP_PROFILE_TYPE.equals(profileType); } + public boolean isGap() { + String profileType = getProfileType(); + return GAP_PROFILE_TYPE.equals(profileType); + } + + public void setGap() { + setProfileType(GAP_PROFILE_TYPE); + } + public void removeProfileType() { getExtensionsToWrite().remove(PROFILE_TYPE_EXTENSION); } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java index 460d56f7ab..8661d42f39 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java @@ -65,6 +65,7 @@ public class MeasurementEditingContext { private WptPt originalPointToMove; private boolean inAddPointMode; + private boolean inAddPointBeforeMode; private boolean inApproximationMode; private int calculatedPairs; private int pointsToCalculateSize; @@ -74,12 +75,17 @@ public class MeasurementEditingContext { private RouteCalculationProgress calculationProgress; private Map, RoadSegmentData> roadSegmentData = new ConcurrentHashMap<>(); - public enum CalculationMode { NEXT_SEGMENT, WHOLE_TRACK } + public enum AdditionMode { + UNDEFINED, + ADD_AFTER, + ADD_BEFORE, + } + public static class RoadSegmentData { private final ApplicationMode appMode; private final WptPt start; @@ -158,6 +164,10 @@ public class MeasurementEditingContext { return inAddPointMode; } + public boolean isInAddPointBeforeMode() { + return inAddPointBeforeMode; + } + public void updateSegmentsForSnap() { updateSegmentsForSnap(true); } @@ -178,8 +188,9 @@ public class MeasurementEditingContext { this.originalPointToMove = originalPointToMove; } - void setInAddPointMode(boolean inAddPointMode) { + void setInAddPointMode(boolean inAddPointMode, boolean inAddPointAfterMode) { this.inAddPointMode = inAddPointMode; + this.inAddPointBeforeMode = inAddPointAfterMode; } public boolean isInApproximationMode() { @@ -294,6 +305,32 @@ public class MeasurementEditingContext { return !newData && hasDefaultPoints && getPoints().size() > 2; } + public boolean isSelectionNeedApproximation() { + boolean hasDefaultPoints = false; + boolean newData = isNewData(); + if (!newData && selectedPointPosition != -1) { + WptPt selectedPoint = getPoints().get(selectedPointPosition); + List segments = getBeforeSegments(); + List points = null; + for (TrkSegment segment : segments) { + if (segment.points.contains(selectedPoint)) { + points = segment.points; + } + } + WptPt prevPoint = null; + if (points != null) { + for (WptPt point : points) { + if (!point.hasProfile() && (prevPoint == null || !prevPoint.hasProfile())) { + hasDefaultPoints = true; + break; + } + prevPoint = point; + } + } + } + return !newData && hasDefaultPoints && getPoints().size() > 2; + } + public void clearSnappedToRoadPoints() { roadSegmentData.clear(); } @@ -312,6 +349,14 @@ public class MeasurementEditingContext { return afterSegments; } + public List getBeforeSegments() { + return beforeSegments; + } + + public List getAfterSegments() { + return afterSegments; + } + public List getPoints() { return getBeforePoints(); } @@ -323,7 +368,7 @@ public class MeasurementEditingContext { String prevProfileType = null; for (WptPt point : allPoints) { String profileType = point.getProfileType(); - boolean isGap = ApplicationMode.GAP.getStringKey().equals(profileType); + boolean isGap = point.isGap(); boolean plainPoint = Algorithms.isEmpty(profileType) || (isGap && Algorithms.isEmpty(prevProfileType)); boolean routePoint = !plainPoint; if (plain && plainPoint || route && routePoint) { @@ -364,12 +409,71 @@ public class MeasurementEditingContext { updateSegmentsForSnap(true); } + private void preAddPoint(int position, AdditionMode additionMode, WptPt point) { + switch (additionMode) { + case UNDEFINED: { + if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE) { + point.setProfileType(appMode.getStringKey()); + } + break; + } + case ADD_AFTER: { + List points = getBeforePoints(); + if (position > 0 && position <= points.size()) { + WptPt prevPt = points.get(position - 1); + if (prevPt.isGap()) { + point.setGap(); + if (position > 1) { + WptPt pt = points.get(position - 2); + if (pt.hasProfile()) { + prevPt.setProfileType(pt.getProfileType()); + } else { + prevPt.removeProfileType(); + } + } + } else if (prevPt.hasProfile()) { + point.setProfileType(prevPt.getProfileType()); + } + } else if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE) { + point.setProfileType(appMode.getStringKey()); + } + break; + } + case ADD_BEFORE: { + List points = getAfterPoints(); + if (position >= -1 && position + 1 < points.size()) { + WptPt nextPt = points.get(position + 1); + if (nextPt.hasProfile()) { + point.setProfileType(nextPt.getProfileType()); + } + } else if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE) { + point.setProfileType(appMode.getStringKey()); + } + break; + } + } + } + public void addPoint(WptPt pt) { + addPoint(pt, AdditionMode.UNDEFINED); + } + + public void addPoint(WptPt pt, AdditionMode additionMode) { + if (additionMode == AdditionMode.ADD_AFTER || additionMode == AdditionMode.ADD_BEFORE) { + preAddPoint(additionMode == AdditionMode.ADD_BEFORE ? -1 : getBeforePoints().size(), additionMode, pt); + } before.points.add(pt); updateSegmentsForSnap(false); } public void addPoint(int position, WptPt pt) { + addPoint(position, pt, AdditionMode.UNDEFINED); + } + + public void addPoint(int position, WptPt pt, AdditionMode additionMode) { + if (additionMode == AdditionMode.ADD_AFTER || additionMode == AdditionMode.ADD_BEFORE) { + preAddPoint(position, additionMode, pt); + } before.points.add(position, pt); updateSegmentsForSnap(false); } @@ -404,7 +508,14 @@ public class MeasurementEditingContext { if (position < 0 || position >= before.points.size()) { return new WptPt(); } - WptPt pt = before.points.remove(position); + WptPt pt = before.points.get(position); + if (position > 0 && pt.isGap()) { + WptPt prevPt = before.points.get(position - 1); + if (!prevPt.isGap()) { + prevPt.setGap(); + } + } + before.points.remove(position); if (updateSnapToRoad) { updateSegmentsForSnap(false); } @@ -442,11 +553,27 @@ public class MeasurementEditingContext { } public boolean isFirstPointSelected() { - return selectedPointPosition == 0; + return isBorderPointSelected(true); } public boolean isLastPointSelected() { - return selectedPointPosition == getPoints().size() - 1; + return isBorderPointSelected(false); + } + + private boolean isBorderPointSelected(boolean first) { + WptPt selectedPoint = getPoints().get(selectedPointPosition); + List segments = getBeforeSegments(); + int count = 0; + for (TrkSegment segment : segments) { + int i = segment.points.indexOf(selectedPoint); + if (i != -1) { + int segmentPosition = selectedPointPosition - count; + return first ? segmentPosition == 0 : segmentPosition == segment.points.size() - 1; + } else { + count += segment.points.size(); + } + } + return false; } public ApplicationMode getSelectedPointAppMode() { @@ -508,7 +635,7 @@ public class MeasurementEditingContext { String profileType = point.getProfileType(); if (profileType != null) { boolean isDefault = profileType.equals(DEFAULT_APP_MODE.getStringKey()); - boolean isGap = profileType.equals(ApplicationMode.GAP.getStringKey()); + boolean isGap = point.isGap(); if (defaultMode && !isDefault && !isGap) { roadSegmentIndexes.add(segments.size() - 1); defaultMode = false; @@ -522,6 +649,8 @@ public class MeasurementEditingContext { } } } + } else { + s.points.addAll(points); } if (s.points.isEmpty()) { segments.remove(s); @@ -542,6 +671,9 @@ public class MeasurementEditingContext { segmentForSnap.points.addAll(Arrays.asList(pair.first, pair.second)); } } + if (segmentForSnap.points.isEmpty()) { + segmentForSnap.points.addAll(segment.points); + } segmentsForSnap.add(segmentForSnap); } } else if (!points.isEmpty()) { @@ -609,13 +741,13 @@ public class MeasurementEditingContext { } } if (!routePoints.isEmpty() && si < segments.size() - 1) { - routePoints.get(routePoints.size() - 1).setProfileType(ApplicationMode.GAP.getStringKey()); + routePoints.get(routePoints.size() - 1).setGap(); } addPoints(routePoints); } else { addPoints(points); if (!points.isEmpty() && si < segments.size() - 1) { - points.get(points.size() - 1).setProfileType(ApplicationMode.GAP.getStringKey()); + points.get(points.size() - 1).setGap(); } } } @@ -668,8 +800,8 @@ public class MeasurementEditingContext { } WptPt lastOriginalPoint = originalPoints.get(originalPoints.size() - 1); WptPt lastRoutePoint = routePoints.get(routePoints.size() - 1); - if (ApplicationMode.GAP.getStringKey().equals(lastOriginalPoint.getProfileType())) { - lastRoutePoint.setProfileType(ApplicationMode.GAP.getStringKey()); + if (lastOriginalPoint.isGap()) { + lastRoutePoint.setGap(); } replacePoints(originalPoints, routePoints); return routePoints; @@ -864,7 +996,7 @@ public class MeasurementEditingContext { for (WptPt point : plainPoints) { if (point.getTrkPtIndex() != -1) { points.add(point); - if (ApplicationMode.GAP.getStringKey().equals(point.getProfileType())) { + if (point.isGap()) { res.add(points); points = new ArrayList<>(); } @@ -920,7 +1052,7 @@ public class MeasurementEditingContext { List lastPointIndexes = new ArrayList<>(); for (int i = 0; i < before.points.size(); i++) { WptPt pt = before.points.get(i); - if (ApplicationMode.GAP.getStringKey().equals(pt.getProfileType())) { + if (pt.isGap()) { lastPointIndexes.add(i); } } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 3b74a59f58..b22b276bb0 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -810,7 +810,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route } @Override - public void addToTheTrackOnClick() { + public void addToTrackOnClick() { MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { if (editingCtx.getPointsCount() > 0) { @@ -877,7 +877,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route MeasurementToolLayer measurementLayer = getMeasurementLayer(); if (measurementLayer != null) { measurementLayer.moveMapToPoint(editingCtx.getSelectedPointPosition()); - editingCtx.setInAddPointMode(true); + editingCtx.setInAddPointMode(true, false); editingCtx.splitSegments(editingCtx.getSelectedPointPosition() + 1); } ((TextView) mainView.findViewById(R.id.add_point_before_after_text)).setText(mainView.getResources().getString(R.string.add_point_after)); @@ -890,7 +890,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route MeasurementToolLayer measurementLayer = getMeasurementLayer(); if (measurementLayer != null) { measurementLayer.moveMapToPoint(editingCtx.getSelectedPointPosition()); - editingCtx.setInAddPointMode(true); + editingCtx.setInAddPointMode(true, true); editingCtx.splitSegments(editingCtx.getSelectedPointPosition()); } ((TextView) mainView.findViewById(R.id.add_point_before_after_text)).setText(mainView.getResources().getString(R.string.add_point_before)); @@ -1031,7 +1031,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route SelectedGpxFile selectedGpxFile = mapActivity.getMyApplication().getSelectedGpxHelper() .getSelectedFileByPath(gpxFile.path); boolean showOnMap = selectedGpxFile != null; - saveExistingGpx(gpxFile, showOnMap, false, FinalSaveAction.SHOW_TOAST); + saveExistingGpx(gpxFile, showOnMap, false, true, FinalSaveAction.SHOW_TOAST); } } @@ -1270,7 +1270,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route switchAddPointBeforeAfterMode(false); editingCtx.splitSegments(editingCtx.getBeforePoints().size() + editingCtx.getAfterPoints().size()); editingCtx.setSelectedPointPosition(-1); - editingCtx.setInAddPointMode(false); + editingCtx.setInAddPointMode(false, false); MeasurementToolLayer measurementLayer = getMeasurementLayer(); if (measurementLayer != null) { measurementLayer.refreshMap(); @@ -1282,7 +1282,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route switchAddPointBeforeAfterMode(false); editingCtx.splitSegments(editingCtx.getBeforePoints().size() + editingCtx.getAfterPoints().size()); editingCtx.setSelectedPointPosition(-1); - editingCtx.setInAddPointMode(false); + editingCtx.setInAddPointMode(false, false); MeasurementToolLayer measurementToolLayer = getMeasurementLayer(); if (measurementToolLayer != null) { measurementToolLayer.refreshMap(); @@ -1468,7 +1468,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route SelectedGpxFile selectedGpxFile = mapActivity.getMyApplication().getSelectedGpxHelper().getSelectedFileByPath(gpx.path); boolean showOnMap = selectedGpxFile != null; - saveExistingGpx(gpx, showOnMap, false, finalSaveAction); + saveExistingGpx(gpx, showOnMap, false, false, finalSaveAction); } } @@ -1507,16 +1507,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route private void saveNewGpx(@NonNull File dir, @NonNull String fileName, boolean showOnMap, boolean simplified, FinalSaveAction finalSaveAction) { - saveGpx(new File(dir, fileName), null, simplified, finalSaveAction, showOnMap); + saveGpx(new File(dir, fileName), null, simplified, false, finalSaveAction, showOnMap); } private void saveExistingGpx(@NonNull GPXFile gpx, boolean showOnMap, - boolean simplified, FinalSaveAction finalSaveAction) { - saveGpx(new File(gpx.path), gpx, simplified, finalSaveAction, showOnMap); + boolean simplified, boolean addToTrack, FinalSaveAction finalSaveAction) { + saveGpx(new File(gpx.path), gpx, simplified, addToTrack, finalSaveAction, showOnMap); } private void saveGpx(@NonNull final File outFile, @Nullable GPXFile gpxFile, boolean simplified, - final FinalSaveAction finalSaveAction, final boolean showOnMap) { + boolean addToTrack, final FinalSaveAction finalSaveAction, final boolean showOnMap) { SaveGpxRouteListener saveGpxRouteListener = new SaveGpxRouteListener() { @Override public void gpxSavingFinished(Exception warning, GPXFile savedGpxFile, File backupFile) { @@ -1524,7 +1524,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route } }; - SaveGpxRouteAsyncTask saveTask = new SaveGpxRouteAsyncTask(this, outFile, gpxFile, simplified, showOnMap, saveGpxRouteListener); + SaveGpxRouteAsyncTask saveTask = new SaveGpxRouteAsyncTask(this, outFile, gpxFile, simplified, + addToTrack, showOnMap, saveGpxRouteListener); saveTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java index 585ba3ec1e..cad4985d38 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java @@ -17,7 +17,7 @@ import net.osmand.data.PointDescription; import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; import net.osmand.plus.R; -import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.plus.measurementtool.MeasurementEditingContext.AdditionMode; import net.osmand.plus.views.OsmandMapLayer; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.Renderable; @@ -313,27 +313,29 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL } private void drawBeforeAfterPath(Canvas canvas, RotatedTileBox tb) { - List before = editingCtx.getBeforeTrkSegmentLine(); - List after = editingCtx.getAfterTrkSegmentLine(); + List before = editingCtx.getBeforeSegments(); + List after = editingCtx.getAfterSegments(); if (before.size() > 0 || after.size() > 0) { path.reset(); tx.clear(); ty.clear(); boolean hasPointsBefore = false; + boolean hasGapBefore = false; if (before.size() > 0) { TrkSegment segment = before.get(before.size() - 1); if (segment.points.size() > 0) { hasPointsBefore = true; WptPt pt = segment.points.get(segment.points.size() - 1); - if (!ApplicationMode.GAP.getStringKey().equals(pt.getProfileType())) { + hasGapBefore = pt.isGap(); + if (!pt.isGap() || !editingCtx.isInAddPointBeforeMode()) { float locX = tb.getPixXFromLatLon(pt.lat, pt.lon); float locY = tb.getPixYFromLatLon(pt.lat, pt.lon); tx.add(locX); ty.add(locY); - tx.add((float) tb.getCenterPixelX()); - ty.add((float) tb.getCenterPixelY()); } + tx.add((float) tb.getCenterPixelX()); + ty.add((float) tb.getCenterPixelY()); } } if (after.size() > 0) { @@ -343,11 +345,13 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL tx.add((float) tb.getCenterPixelX()); ty.add((float) tb.getCenterPixelY()); } - WptPt pt = segment.points.get(0); - float locX = tb.getPixXFromLatLon(pt.lat, pt.lon); - float locY = tb.getPixYFromLatLon(pt.lat, pt.lon); - tx.add(locX); - ty.add(locY); + if (!hasGapBefore || editingCtx.isInAddPointBeforeMode()) { + WptPt pt = segment.points.get(0); + float locX = tb.getPixXFromLatLon(pt.lat, pt.lon); + float locY = tb.getPixYFromLatLon(pt.lat, pt.lon); + tx.add(locX); + ty.add(locY); + } } } @@ -376,7 +380,7 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); } - public WptPt addCenterPoint() { + public WptPt addCenterPoint(boolean addPointBefore) { RotatedTileBox tb = view.getCurrentRotatedTileBox(); LatLon l = tb.getCenterLatLon(); WptPt pt = new WptPt(); @@ -384,17 +388,13 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL pt.lon = l.getLongitude(); boolean allowed = editingCtx.getPointsCount() == 0 || !editingCtx.getPoints().get(editingCtx.getPointsCount() - 1).equals(pt); if (allowed) { - ApplicationMode applicationMode = editingCtx.getAppMode(); - if (applicationMode != MeasurementEditingContext.DEFAULT_APP_MODE) { - pt.setProfileType(applicationMode.getStringKey()); - } - editingCtx.addPoint(pt); + editingCtx.addPoint(pt, addPointBefore ? AdditionMode.ADD_BEFORE : AdditionMode.ADD_AFTER); return pt; } return null; } - public WptPt addPoint() { + public WptPt addPoint(boolean addPointBefore) { if (pressedPointLatLon != null) { WptPt pt = new WptPt(); double lat = pressedPointLatLon.getLatitude(); @@ -404,11 +404,7 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL pressedPointLatLon = null; boolean allowed = editingCtx.getPointsCount() == 0 || !editingCtx.getPoints().get(editingCtx.getPointsCount() - 1).equals(pt); if (allowed) { - ApplicationMode applicationMode = editingCtx.getAppMode(); - if (applicationMode != MeasurementEditingContext.DEFAULT_APP_MODE) { - pt.setProfileType(applicationMode.getStringKey()); - } - editingCtx.addPoint(pt); + editingCtx.addPoint(pt, addPointBefore ? AdditionMode.ADD_BEFORE : AdditionMode.ADD_AFTER); moveMapToLatLon(lat, lon); return pt; } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/OptionsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/OptionsBottomSheetDialogFragment.java index 6cfbcf8f3f..0a9c690a1e 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/OptionsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/OptionsBottomSheetDialogFragment.java @@ -108,7 +108,7 @@ public class OptionsBottomSheetDialogFragment extends MenuBottomSheetDialogFragm public void onClick(View v) { Fragment fragment = getTargetFragment(); if (fragment instanceof OptionsFragmentListener) { - ((OptionsFragmentListener) fragment).addToTheTrackOnClick(); + ((OptionsFragmentListener) fragment).addToTrackOnClick(); } dismiss(); } @@ -229,7 +229,7 @@ public class OptionsBottomSheetDialogFragment extends MenuBottomSheetDialogFragm void saveAsNewTrackOnClick(); - void addToTheTrackOnClick(); + void addToTrackOnClick(); void directionsOnClick(); diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SaveGpxRouteAsyncTask.java b/OsmAnd/src/net/osmand/plus/measurementtool/SaveGpxRouteAsyncTask.java index c49251d72f..a73d8667cc 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SaveGpxRouteAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SaveGpxRouteAsyncTask.java @@ -4,12 +4,13 @@ import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; -import androidx.annotation.Nullable; +import androidx.annotation.NonNull; import net.osmand.AndroidUtils; import net.osmand.FileUtils; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; +import net.osmand.GPXUtilities.Route; import net.osmand.GPXUtilities.Track; import net.osmand.GPXUtilities.TrkSegment; import net.osmand.GPXUtilities.WptPt; @@ -27,25 +28,28 @@ import static net.osmand.IndexConstants.GPX_FILE_EXT; class SaveGpxRouteAsyncTask extends AsyncTask { - private WeakReference fragmentRef; + private final WeakReference fragmentRef; private ProgressDialog progressDialog; - private File outFile; + private final File outFile; private File backupFile; - private GPXFile gpxFile; + private final GPXFile gpxFile; private GPXFile savedGpxFile; - private boolean simplified; - private boolean showOnMap; + private final boolean simplified; + private final boolean addToTrack; + private final boolean showOnMap; - private SaveGpxRouteListener saveGpxRouteListener; + private final SaveGpxRouteListener saveGpxRouteListener; public SaveGpxRouteAsyncTask(MeasurementToolFragment fragment, File outFile, GPXFile gpxFile, - boolean simplified, boolean showOnMap, SaveGpxRouteListener saveGpxRouteListener) { + boolean simplified, boolean addToTrack, boolean showOnMap, + SaveGpxRouteListener saveGpxRouteListener) { fragmentRef = new WeakReference<>(fragment); this.outFile = outFile; this.showOnMap = showOnMap; this.gpxFile = gpxFile; this.simplified = simplified; + this.addToTrack = addToTrack; this.saveGpxRouteListener = saveGpxRouteListener; } @@ -99,7 +103,7 @@ class SaveGpxRouteAsyncTask extends AsyncTask { } private GPXFile generateGpxFile(MeasurementToolLayer measurementLayer, MeasurementEditingContext editingCtx, - String trackName, @Nullable GPXFile gpx) { + String trackName, @NonNull GPXFile gpx) { if (measurementLayer != null) { List before = editingCtx.getBeforeTrkSegmentLine(); List after = editingCtx.getAfterTrkSegmentLine(); @@ -120,10 +124,9 @@ class SaveGpxRouteAsyncTask extends AsyncTask { } else { GPXFile newGpx = editingCtx.exportGpx(trackName); if (newGpx != null) { - List gpxPoints = null; - if (gpx != null) { - gpxPoints = gpx.getPoints(); - } + List gpxTracks = gpx.tracks; + List gpxPoints = gpx.getPoints(); + List gpxRoutes = gpx.routes; gpx = newGpx; List> routePoints = editingCtx.getRoutePoints(); for (List points : routePoints) { @@ -132,6 +135,10 @@ class SaveGpxRouteAsyncTask extends AsyncTask { if (!Algorithms.isEmpty(gpxPoints)) { gpx.addPoints(gpxPoints); } + if (addToTrack) { + gpx.tracks.addAll(gpxTracks); + gpx.routes.addAll(gpxRoutes); + } } } } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SelectedPointBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SelectedPointBottomSheetDialogFragment.java index c55d07d4fa..39ff57b20c 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SelectedPointBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SelectedPointBottomSheetDialogFragment.java @@ -173,7 +173,7 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo dismiss(); } }) - .setDisabled(editingCtx.isFirstPointSelected()) + .setDisabled(editingCtx.isFirstPointSelected() || editingCtx.isSelectionNeedApproximation()) .create(); items.add(changeRouteTypeBefore); @@ -192,7 +192,7 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo dismiss(); } }) - .setDisabled(editingCtx.isLastPointSelected()) + .setDisabled(editingCtx.isLastPointSelected() || editingCtx.isSelectionNeedApproximation()) .create(); items.add(changeRouteTypeAfter); diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/command/AddPointCommand.java b/OsmAnd/src/net/osmand/plus/measurementtool/command/AddPointCommand.java index 2d4afe4ccd..7d40812d1f 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/command/AddPointCommand.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/command/AddPointCommand.java @@ -3,48 +3,57 @@ 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.MeasurementEditingContext.AdditionMode; import net.osmand.plus.measurementtool.MeasurementToolLayer; import net.osmand.plus.settings.backend.ApplicationMode; +import java.util.List; + public class AddPointCommand extends MeasurementModeCommand { private int position; private WptPt point; + private String prevPointProfile; private boolean center; + private boolean addPointBefore; public AddPointCommand(MeasurementToolLayer measurementLayer, boolean center) { super(measurementLayer); - init(measurementLayer, null, center); + init(null, center); } public AddPointCommand(MeasurementToolLayer measurementLayer, LatLon latLon) { super(measurementLayer); - init(measurementLayer, latLon, false); + init(latLon, false); } - private void init(MeasurementToolLayer measurementLayer, LatLon latLon, boolean center) { + private void init(LatLon latLon, boolean center) { + MeasurementEditingContext ctx = getEditingCtx(); if (latLon != null) { point = new WptPt(); point.lat = latLon.getLatitude(); point.lon = latLon.getLongitude(); - ApplicationMode appMode = measurementLayer.getEditingCtx().getAppMode(); - if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE) { - point.setProfileType(appMode.getStringKey()); - } } this.center = center; - position = measurementLayer.getEditingCtx().getPointsCount(); + position = ctx.getPointsCount(); } @Override public boolean execute() { + MeasurementEditingContext ctx = getEditingCtx(); + addPointBefore = ctx.isInAddPointBeforeMode(); + List points = ctx.getPoints(); + if (points.size() > 0) { + WptPt prevPt = points.get(points.size() - 1); + prevPointProfile = prevPt.getProfileType(); + } if (point != null) { - getEditingCtx().addPoint(point); + ctx.addPoint(point, addPointBefore ? AdditionMode.ADD_BEFORE : AdditionMode.ADD_AFTER); measurementLayer.moveMapToPoint(position); } else if (center) { - point = measurementLayer.addCenterPoint(); + point = measurementLayer.addCenterPoint(addPointBefore); } else { - point = measurementLayer.addPoint(); + point = measurementLayer.addPoint(addPointBefore); } refreshMap(); return point != null; @@ -52,13 +61,22 @@ public class AddPointCommand extends MeasurementModeCommand { @Override public void undo() { - getEditingCtx().removePoint(position, true); + MeasurementEditingContext ctx = getEditingCtx(); + if (position > 0) { + WptPt prevPt = ctx.getPoints().get(position - 1); + if (prevPointProfile != null) { + prevPt.setProfileType(prevPointProfile); + } else { + prevPt.removeProfileType(); + } + } + ctx.removePoint(position, true); refreshMap(); } @Override public void redo() { - getEditingCtx().addPoint(position, point); + getEditingCtx().addPoint(position, point, addPointBefore ? AdditionMode.ADD_BEFORE : AdditionMode.ADD_AFTER); refreshMap(); measurementLayer.moveMapToPoint(position); } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/command/ChangeRouteModeCommand.java b/OsmAnd/src/net/osmand/plus/measurementtool/command/ChangeRouteModeCommand.java index c4399e2730..a9cfa2bb1e 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/command/ChangeRouteModeCommand.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/command/ChangeRouteModeCommand.java @@ -150,10 +150,12 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand { } private void updateProfileType(WptPt pt) { - if (newMode != null && newMode != DEFAULT_APP_MODE) { - pt.setProfileType(newMode.getStringKey()); - } else { - pt.removeProfileType(); + if (!pt.isGap()) { + if (newMode != null && newMode != DEFAULT_APP_MODE) { + pt.setProfileType(newMode.getStringKey()); + } else { + pt.removeProfileType(); + } } } } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/command/RemovePointCommand.java b/OsmAnd/src/net/osmand/plus/measurementtool/command/RemovePointCommand.java index c420d1c42e..383da291a4 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/command/RemovePointCommand.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/command/RemovePointCommand.java @@ -7,6 +7,7 @@ public class RemovePointCommand extends MeasurementModeCommand { private final int position; private WptPt point; + private String prevPointProfile; public RemovePointCommand(MeasurementToolLayer measurementLayer, int position) { super(measurementLayer); @@ -15,6 +16,9 @@ public class RemovePointCommand extends MeasurementModeCommand { @Override public boolean execute() { + if (position > 0) { + prevPointProfile = getEditingCtx().getPoints().get(position - 1).getProfileType(); + } point = getEditingCtx().removePoint(position, true); refreshMap(); return true; @@ -22,6 +26,14 @@ public class RemovePointCommand extends MeasurementModeCommand { @Override public void undo() { + if (position > 0) { + WptPt prevPt = getEditingCtx().getPoints().get(position - 1); + if (prevPointProfile != null) { + prevPt.setProfileType(prevPointProfile); + } else { + prevPt.removeProfileType(); + } + } getEditingCtx().addPoint(position, point); refreshMap(); measurementLayer.moveMapToPoint(position); diff --git a/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java b/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java index 266eaf1f5e..65e683a734 100644 --- a/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java +++ b/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java @@ -78,10 +78,6 @@ public class GpxApproximator { } } - public static void cancelPendingApproximations() { - SINGLE_THREAD_EXECUTOR.getQueue().clear(); - } - private void prepareEnvironment(@NonNull OsmandApplication ctx, @NonNull ApplicationMode mode) throws IOException { this.env = routingHelper.getRoutingEnvironment(ctx, mode, start, end); } @@ -196,9 +192,7 @@ public class GpxApproximator { if (approximationTask != null && calculationProgress != null && !calculationProgress.isCancelled) { float pr = calculationProgress.getLinearProgress(); approximationProgress.updateProgress(GpxApproximator.this, (int) pr); - if (GpxApproximator.this.gctx != gctx) { - // different calculation started - } else { + if (GpxApproximator.this.gctx == gctx) { updateProgress(gctx); } }