Fixed save/open gpx file (plan route)

This commit is contained in:
max-klaus 2020-08-20 21:55:47 +03:00
parent 51786f71f0
commit 71419a41e9
11 changed files with 231 additions and 312 deletions

View file

@ -404,6 +404,41 @@ public class RoutePlannerFrontEnd {
cleanupResultAndAddTurns(gctx); cleanupResultAndAddTurns(gctx);
} }
public RouteSegmentResult generateStraightLineSegment(float averageSpeed, List<LatLon> points) {
RouteRegion reg = new RouteRegion();
reg.initRouteEncodingRule(0, "highway", RouteResultPreparation.UNMATCHED_HIGHWAY_TYPE);
RouteDataObject rdo = new RouteDataObject(reg);
int size = points.size();
TIntArrayList x = new TIntArrayList(size);
TIntArrayList y = new TIntArrayList(size);
double distance = 0;
double distOnRoadToPass = 0;
LatLon prev = null;
for (int i = 0; i < size; i++) {
LatLon l = points.get(i);
if (l != null) {
x.add(MapUtils.get31TileNumberX(l.getLongitude()));
y.add(MapUtils.get31TileNumberY(l.getLatitude()));
if (prev != null) {
double d = MapUtils.getDistance(l, prev);
distance += d;
distOnRoadToPass += d / averageSpeed;
}
}
prev = l;
}
rdo.pointsX = x.toArray();
rdo.pointsY = y.toArray();
rdo.types = new int[] { 0 } ;
rdo.id = -1;
RouteSegmentResult segment = new RouteSegmentResult(rdo, 0, rdo.getPointsLength() - 1);
segment.setSegmentTime((float) distOnRoadToPass);
segment.setSegmentSpeed(averageSpeed);
segment.setDistance((float) distance);
segment.setTurnType(TurnType.straight());
return segment;
}
public List<GpxPoint> generateGpxPoints(GpxRouteApproximation gctx, LocationsHolder locationsHolder) { public List<GpxPoint> generateGpxPoints(GpxRouteApproximation gctx, LocationsHolder locationsHolder) {
List<GpxPoint> gpxPoints = new ArrayList<>(locationsHolder.getSize()); List<GpxPoint> gpxPoints = new ArrayList<>(locationsHolder.getSize());
GpxPoint prev = null; GpxPoint prev = null;

View file

@ -9,17 +9,24 @@ import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.TrkSegment; import net.osmand.GPXUtilities.TrkSegment;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.LocationsHolder;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.measurementtool.command.MeasurementCommandManager; import net.osmand.plus.measurementtool.command.MeasurementCommandManager;
import net.osmand.plus.routing.RouteCalculationParams; import net.osmand.plus.routing.RouteCalculationParams;
import net.osmand.plus.routing.RouteCalculationParams.RouteCalculationResultListener;
import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteCalculationResult;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.routing.RoutingHelper.RouteCalculationProgressCallback;
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.RouteExporter;
import net.osmand.router.RouteImporter; import net.osmand.router.RouteImporter;
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.RouteResultPreparation;
import net.osmand.router.RouteSegmentResult; import net.osmand.router.RouteSegmentResult;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
@ -55,13 +62,12 @@ public class MeasurementEditingContext {
private WptPt originalPointToMove; private WptPt originalPointToMove;
private boolean inAddPointMode; private boolean inAddPointMode;
private boolean needUpdateCacheForSnap;
private int calculatedPairs; private int calculatedPairs;
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>> snapToRoadPairsToCalculate = new ConcurrentLinkedQueue<>(); 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 {
@ -73,15 +79,31 @@ public class MeasurementEditingContext {
private ApplicationMode appMode; private ApplicationMode appMode;
private WptPt start; private WptPt start;
private WptPt end; private WptPt end;
private List<WptPt> snappedToRoadPoints = new ArrayList<>(); private List<WptPt> points;
private List<RouteSegmentResult> snappedToRoadSegments = new ArrayList<>(); private List<RouteSegmentResult> segments;
private double distance;
public RoadSegmentData(ApplicationMode appMode, WptPt start, WptPt end, List<WptPt> snappedToRoadPoints, List<RouteSegmentResult> snappedToRoadSegments) { public RoadSegmentData(@NonNull ApplicationMode appMode, @NonNull WptPt start, @NonNull WptPt end,
@Nullable List<WptPt> points, @Nullable List<RouteSegmentResult> segments) {
this.appMode = appMode; this.appMode = appMode;
this.start = start; this.start = start;
this.end = end; this.end = end;
this.snappedToRoadPoints = snappedToRoadPoints; this.points = points;
this.snappedToRoadSegments = snappedToRoadSegments; this.segments = segments;
if (segments != null) {
double distance = 0;
for (RouteSegmentResult segment : segments) {
distance += segment.getDistance();
}
this.distance = distance;
} else if (points != null && points.size() > 1) {
double distance = 0;
for (int i = 1; i < points.size(); i++) {
distance += MapUtils.getDistance(points.get(i - 1).lat, points.get(i - 1).lon,
points.get(i).lat, points.get(i).lon);
}
this.distance = distance;
}
} }
public ApplicationMode getAppMode() { public ApplicationMode getAppMode() {
@ -96,12 +118,18 @@ public class MeasurementEditingContext {
return end; return end;
} }
public List<WptPt> getSnappedToRoadPoints() { @Nullable
return Collections.unmodifiableList(snappedToRoadPoints); public List<WptPt> getPoints() {
return points != null ? Collections.unmodifiableList(points) : null;
} }
public List<RouteSegmentResult> getSnappedToRoadSegments() { @Nullable
return Collections.unmodifiableList(snappedToRoadSegments); public List<RouteSegmentResult> getSegments() {
return segments != null ? Collections.unmodifiableList(segments) : null;
}
public double getDistance() {
return distance;
} }
} }
@ -117,13 +145,8 @@ public class MeasurementEditingContext {
return inAddPointMode; return inAddPointMode;
} }
public boolean isNeedUpdateCacheForSnap() { public void updateCacheForSnap() {
return needUpdateCacheForSnap; updateCacheForSnap(true);
}
public void setNeedUpdateCacheForSnap(boolean needUpdateCacheForSnap) {
this.needUpdateCacheForSnap = needUpdateCacheForSnap;
updateCacheForSnapIfNeeded(true);
} }
public int getSelectedPointPosition() { public int getSelectedPointPosition() {
@ -146,10 +169,6 @@ public class MeasurementEditingContext {
this.inAddPointMode = inAddPointMode; this.inAddPointMode = inAddPointMode;
} }
boolean isInSnapToRoadMode() {
return appMode != DEFAULT_APP_MODE;
}
NewGpxData getNewGpxData() { NewGpxData getNewGpxData() {
return newGpxData; return newGpxData;
} }
@ -191,6 +210,18 @@ public class MeasurementEditingContext {
this.appMode = DEFAULT_APP_MODE; this.appMode = DEFAULT_APP_MODE;
} }
public double getRouteDistance() {
double distance = 0;
for (RoadSegmentData data : roadSegmentData.values()) {
distance += data.getDistance();
}
return distance;
}
public boolean hasRoute() {
return !roadSegmentData.isEmpty();
}
public void clearSnappedToRoadPoints() { public void clearSnappedToRoadPoints() {
roadSegmentData.clear(); roadSegmentData.clear();
} }
@ -233,22 +264,22 @@ public class MeasurementEditingContext {
after.points.clear(); after.points.clear();
before.points.addAll(points.subList(0, position)); before.points.addAll(points.subList(0, position));
after.points.addAll(points.subList(position, points.size())); after.points.addAll(points.subList(position, points.size()));
updateCacheForSnapIfNeeded(true); updateCacheForSnap(true);
} }
public void addPoint(WptPt pt) { public void addPoint(WptPt pt) {
before.points.add(pt); before.points.add(pt);
updateCacheForSnapIfNeeded(false); updateCacheForSnap(false);
} }
public void addPoint(int position, WptPt pt) { public void addPoint(int position, WptPt pt) {
before.points.add(position, pt); before.points.add(position, pt);
updateCacheForSnapIfNeeded(false); updateCacheForSnap(false);
} }
public void addPoints(List<WptPt> points) { public void addPoints(List<WptPt> points) {
before.points.addAll(points); before.points.addAll(points);
updateCacheForSnapIfNeeded(false); updateCacheForSnap(false);
} }
public WptPt removePoint(int position, boolean updateSnapToRoad) { public WptPt removePoint(int position, boolean updateSnapToRoad) {
@ -257,7 +288,7 @@ public class MeasurementEditingContext {
} }
WptPt pt = before.points.remove(position); WptPt pt = before.points.remove(position);
if (updateSnapToRoad) { if (updateSnapToRoad) {
updateCacheForSnapIfNeeded(false); updateCacheForSnap(false);
} }
return pt; return pt;
} }
@ -265,25 +296,17 @@ public class MeasurementEditingContext {
public void clearSegments() { public void clearSegments() {
before.points.clear(); before.points.clear();
after.points.clear(); after.points.clear();
if (isInSnapToRoadMode()) {
if (beforeCacheForSnap != null && afterCacheForSnap != null) { if (beforeCacheForSnap != null && afterCacheForSnap != null) {
beforeCacheForSnap.points.clear(); beforeCacheForSnap.points.clear();
afterCacheForSnap.points.clear(); afterCacheForSnap.points.clear();
} }
needUpdateCacheForSnap = true;
} else {
beforeCacheForSnap = null;
afterCacheForSnap = null;
needUpdateCacheForSnap = false;
}
} }
public void scheduleRouteCalculateIfNotEmpty() { public void scheduleRouteCalculateIfNotEmpty() {
needUpdateCacheForSnap = true;
if (application == null || (before.points.size() == 0 && after.points.size() == 0)) { if (application == null || (before.points.size() == 0 && after.points.size() == 0)) {
return; return;
} }
snapToRoadPairsToCalculate.clear(); roadSegmentsToCalculate.clear();
findPointsToCalculate(Arrays.asList(before.points, after.points)); 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()) {
@ -305,7 +328,7 @@ public class MeasurementEditingContext {
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) {
snapToRoadPairsToCalculate.add(pair); roadSegmentsToCalculate.add(pair);
} }
} }
} }
@ -316,13 +339,11 @@ public class MeasurementEditingContext {
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));
RoadSegmentData data = this.roadSegmentData.get(pair); RoadSegmentData data = this.roadSegmentData.get(pair);
List<WptPt> pts = data != null ? data.getSnappedToRoadPoints() : null; List<WptPt> pts = data != null ? data.getPoints() : null;
if (pts != null) { if (pts != null) {
cache.points.addAll(pts); cache.points.addAll(pts);
} else { } else {
if (isInSnapToRoadMode()) {
scheduleRouteCalculateIfNotEmpty(); scheduleRouteCalculateIfNotEmpty();
}
cache.points.addAll(Arrays.asList(pair.first, pair.second)); cache.points.addAll(Arrays.asList(pair.first, pair.second));
} }
} }
@ -348,25 +369,34 @@ public class MeasurementEditingContext {
if (startIndex < 0 || startIndex < prevPointIndex || startIndex >= points.size()) { if (startIndex < 0 || startIndex < prevPointIndex || startIndex >= points.size()) {
startIndex = findPointIndex(pair.first, points, prevPointIndex); startIndex = findPointIndex(pair.first, points, prevPointIndex);
} }
int endIndex = pair.second.getTrkPtIndex() + 1; int endIndex = pair.second.getTrkPtIndex();
if (endIndex < 0 || endIndex < startIndex || endIndex >= points.size()) { if (endIndex < 0 || endIndex < startIndex || endIndex >= points.size()) {
endIndex = findPointIndex(pair.second, points, startIndex); endIndex = findPointIndex(pair.second, points, startIndex);
} }
if (startIndex >= 0 && endIndex >= 0) { if (startIndex >= 0 && endIndex >= 0) {
List<WptPt> segmentPoints = new ArrayList<>(); List<WptPt> pairPoints = new ArrayList<>();
for (int j = startIndex; j < endIndex && j < points.size(); j++) { for (int j = startIndex; j < endIndex && j < points.size(); j++) {
segmentPoints.add(points.get(j)); pairPoints.add(points.get(j));
prevPointIndex = j; prevPointIndex = j;
} }
if (points.size() > prevPointIndex + 1) {
pairPoints.add(points.get(prevPointIndex + 1));
}
Iterator<RouteSegmentResult> it = segments.iterator(); Iterator<RouteSegmentResult> it = segments.iterator();
int k = endIndex - startIndex; int k = endIndex - startIndex - 1;
while (it.hasNext() && k >= 0) { List<RouteSegmentResult> pairSegments = new ArrayList<>();
if (k == 0 && !segments.isEmpty()) {
pairSegments.add(segments.remove(0));
} else {
while (it.hasNext() && k > 0) {
RouteSegmentResult s = it.next(); RouteSegmentResult s = it.next();
pairSegments.add(s);
it.remove(); it.remove();
k -= Math.abs(s.getEndPointIndex() - s.getStartPointIndex()); k -= Math.abs(s.getEndPointIndex() - s.getStartPointIndex());
} }
}
ApplicationMode appMode = ApplicationMode.valueOfStringKey(pair.first.getProfileType(), DEFAULT_APP_MODE); ApplicationMode appMode = ApplicationMode.valueOfStringKey(pair.first.getProfileType(), DEFAULT_APP_MODE);
roadSegmentData.put(pair, new RoadSegmentData(appMode, pair.first, pair.second, segmentPoints, segments)); roadSegmentData.put(pair, new RoadSegmentData(appMode, pair.first, pair.second, pairPoints, pairSegments));
} }
} }
addPoints(routePoints); addPoints(routePoints);
@ -443,18 +473,16 @@ public class MeasurementEditingContext {
&& newGpxData.getGpxFile().hasRoute(); && newGpxData.getGpxFile().hasRoute();
} }
private void updateCacheForSnapIfNeeded(boolean both) { private void updateCacheForSnap(boolean both) {
if (needUpdateCacheForSnap) {
recreateCacheForSnap(beforeCacheForSnap = new TrkSegment(), before); recreateCacheForSnap(beforeCacheForSnap = new TrkSegment(), before);
if (both) { if (both) {
recreateCacheForSnap(afterCacheForSnap = new TrkSegment(), after); recreateCacheForSnap(afterCacheForSnap = new TrkSegment(), after);
} }
} }
}
void cancelSnapToRoad() { void cancelSnapToRoad() {
progressListener.hideProgressBar(); progressListener.hideProgressBar();
snapToRoadPairsToCalculate.clear(); roadSegmentsToCalculate.clear();
if (calculationProgress != null) { if (calculationProgress != null) {
calculationProgress.isCancelled = true; calculationProgress.isCancelled = true;
} }
@ -462,7 +490,7 @@ public class MeasurementEditingContext {
@Nullable @Nullable
private RouteCalculationParams getParams() { private RouteCalculationParams getParams() {
final Pair<WptPt, WptPt> currentPair = snapToRoadPairsToCalculate.poll(); final Pair<WptPt, WptPt> currentPair = roadSegmentsToCalculate.poll();
if (currentPair == null) { if (currentPair == null) {
return null; return null;
} }
@ -472,29 +500,25 @@ public class MeasurementEditingContext {
LatLon end = new LatLon(currentPair.second.getLatitude(), currentPair.second.getLongitude()); LatLon end = new LatLon(currentPair.second.getLatitude(), currentPair.second.getLongitude());
RouteRegion reg = new RouteRegion();
reg.initRouteEncodingRule(0, "highway", RouteResultPreparation.UNMATCHED_HIGHWAY_TYPE);
final RoutePlannerFrontEnd routePlannerFrontEnd = new RoutePlannerFrontEnd();
final RouteCalculationParams params = new RouteCalculationParams(); final RouteCalculationParams params = new RouteCalculationParams();
params.inSnapToRoadMode = true; params.inSnapToRoadMode = true;
params.start = start; params.start = start;
ApplicationMode currentPointSnapToRoadMode; ApplicationMode appMode = calculationMode == NEXT_SEGMENT
if (calculationMode == NEXT_SEGMENT) { ? ApplicationMode.valueOfStringKey(currentPair.first.getProfileType(), null) : this.appMode;
currentPointSnapToRoadMode = ApplicationMode.valueOfStringKey(currentPair.first.getProfileType(), if (appMode == null) {
null); appMode = DEFAULT_APP_MODE;
} else {
currentPointSnapToRoadMode = appMode;
} }
params.end = end; params.end = end;
if (currentPointSnapToRoadMode == null) { RoutingHelper.applyApplicationSettings(params, application.getSettings(), appMode);
ApplicationMode straightLine = ApplicationMode.AIRCRAFT; params.mode = appMode;
RoutingHelper.applyApplicationSettings(params, application.getSettings(), straightLine);
params.mode = straightLine;
} else {
RoutingHelper.applyApplicationSettings(params, application.getSettings(), currentPointSnapToRoadMode);
params.mode = currentPointSnapToRoadMode;
}
params.ctx = application; params.ctx = application;
params.calculationProgress = calculationProgress = new RouteCalculationProgress(); params.calculationProgress = calculationProgress = new RouteCalculationProgress();
params.calculationProgressCallback = new RoutingHelper.RouteCalculationProgressCallback() { params.calculationProgressCallback = new RouteCalculationProgressCallback() {
@Override @Override
public void start() { public void start() {
@ -502,7 +526,7 @@ public class MeasurementEditingContext {
@Override @Override
public void updateProgress(int progress) { public void updateProgress(int progress) {
int pairs = calculatedPairs + snapToRoadPairsToCalculate.size(); int pairs = calculatedPairs + roadSegmentsToCalculate.size();
if (pairs != 0) { if (pairs != 0) {
int pairProgress = 100 / pairs; int pairProgress = 100 / pairs;
progress = calculatedPairs * pairProgress + progress / pairs; progress = calculatedPairs * pairProgress + progress / pairs;
@ -519,7 +543,7 @@ public class MeasurementEditingContext {
calculatedPairs = 0; calculatedPairs = 0;
} }
}; };
params.resultListener = new RouteCalculationParams.RouteCalculationResultListener() { params.resultListener = new RouteCalculationResultListener() {
@Override @Override
public void onRouteCalculated(RouteCalculationResult route) { public void onRouteCalculated(RouteCalculationResult route) {
List<Location> locations = route.getRouteLocations(); List<Location> locations = route.getRouteLocations();
@ -538,11 +562,13 @@ public class MeasurementEditingContext {
pts.add(pt); pts.add(pt);
} }
calculatedPairs++; calculatedPairs++;
roadSegmentData.put(currentPair, new RoadSegmentData(route.getAppMode(), currentPair.first, currentPair.second, pts, route.getOriginalRoute())); List<RouteSegmentResult> originalRoute = route.getOriginalRoute();
int trkptIndex = currentPair.first.getTrkPtIndex(); if (Algorithms.isEmpty(originalRoute)) {
trkptIndex += pts.size() - 1; originalRoute = Collections.singletonList(routePlannerFrontEnd.generateStraightLineSegment(
currentPair.second.setTrkPtIndex(trkptIndex); DEFAULT_APP_MODE.getDefaultSpeed(), new LocationsHolder(pts).getLatLonList()));
updateCacheForSnapIfNeeded(true); }
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() {
@ -565,97 +591,29 @@ public class MeasurementEditingContext {
return params; return params;
} }
public void exportRouteAsGpx(@NonNull String gpxName, @Nullable ExportAsGpxListener exportListener) {
if (application == null || (before.points.size() == 0 && after.points.size() == 0)) {
return;
}
RoutingHelper routingHelper = application.getRoutingHelper();
if (!routingHelper.isRouteBeingCalculated()) {
RouteCalculationParams params = getExportAsGpxParams(gpxName, exportListener);
if (params != null) {
routingHelper.startRouteCalculationThread(params, true, true);
}
}
}
@Nullable @Nullable
private RouteCalculationParams getExportAsGpxParams(@NonNull final String gpxName, @Nullable final ExportAsGpxListener exportListener) { public GPXFile exportRouteAsGpx(@NonNull String gpxName) {
List<List<WptPt>> pointList = Arrays.asList(before.points, after.points); if (application == null || before.points.isEmpty() || !hasRoute()) {
WptPt startPoint = null;
WptPt endPoint = null;
List<WptPt> intermediatePoints = new ArrayList<>();
for (List<WptPt> points : pointList) {
for (WptPt point : points) {
if (startPoint == null) {
startPoint = point;
} else {
intermediatePoints.add(point);
endPoint = point;
}
}
}
if (endPoint != null) {
intermediatePoints.remove(endPoint);
}
if (startPoint == null || endPoint == null) {
return null; return null;
} }
List<RouteSegmentResult> route = new ArrayList<>();
Location start = new Location(""); List<Location> locations = new ArrayList<>();
start.setLatitude(startPoint.getLatitude()); before.points.get(0).setTrkPtIndex(0);
start.setLongitude(startPoint.getLongitude()); int size = before.points.size();
LatLon end = new LatLon(endPoint.getLatitude(), endPoint.getLongitude()); for (int i = 0; i < size - 1; i++) {
List<LatLon> intermediates = null; Pair<WptPt, WptPt> pair = new Pair<>(before.points.get(i), before.points.get(i + 1));
if (!intermediatePoints.isEmpty()) { RoadSegmentData data = this.roadSegmentData.get(pair);
intermediates = new ArrayList<>(); if (data != null) {
for (WptPt point : intermediatePoints) { LocationsHolder locationsHolder = new LocationsHolder(data.points);
intermediates.add(new LatLon(point.getLatitude(), point.getLongitude())); locations.addAll(locationsHolder.getLocationsList());
pair.second.setTrkPtIndex(locations.size() - 1);
if (i < size - 2) {
locations.remove(locations.size() - 1);
}
route.addAll(data.segments);
} }
} }
final RouteCalculationParams params = new RouteCalculationParams(); return new RouteExporter(gpxName, route, locations, null).exportRoute();
params.inSnapToRoadMode = true;
params.start = start;
params.end = end;
params.intermediates = intermediates;
if (appMode == null) {
ApplicationMode straightLine = ApplicationMode.AIRCRAFT;
RoutingHelper.applyApplicationSettings(params, application.getSettings(), straightLine);
params.mode = straightLine;
} else {
RoutingHelper.applyApplicationSettings(params, application.getSettings(), appMode);
params.mode = appMode;
}
params.ctx = application;
params.calculationProgress = calculationProgress = new RouteCalculationProgress();
params.calculationProgressCallback = new RoutingHelper.RouteCalculationProgressCallback() {
@Override
public void start() {
}
@Override
public void updateProgress(int progress) {
}
@Override
public void requestPrivateAccessRouting() {
}
@Override
public void finish() {
calculatedPairs = 0;
}
};
params.resultListener = new RouteCalculationParams.RouteCalculationResultListener() {
@Override
public void onRouteCalculated(RouteCalculationResult route) {
GPXFile gpx = application.getRoutingHelper().generateGPXFileWithRoute(route, gpxName);
if (exportListener != null) {
exportListener.onExportAsGpxFinished(gpx);
}
}
};
return params;
} }
interface SnapToRoadProgressListener { interface SnapToRoadProgressListener {
@ -668,8 +626,4 @@ public class MeasurementEditingContext {
void refresh(); void refresh();
} }
interface ExportAsGpxListener {
void onExportAsGpxFinished(GPXFile gpx);
}
} }

View file

@ -43,7 +43,6 @@ import net.osmand.AndroidUtils;
import net.osmand.FileUtils; import net.osmand.FileUtils;
import net.osmand.GPXUtilities; import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.Route;
import net.osmand.GPXUtilities.Track; import net.osmand.GPXUtilities.Track;
import net.osmand.GPXUtilities.TrkSegment; import net.osmand.GPXUtilities.TrkSegment;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
@ -70,8 +69,8 @@ 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.ChangeRouteModeCommand;
import net.osmand.plus.measurementtool.command.ApplyGpxApproximationCommand; import net.osmand.plus.measurementtool.command.ApplyGpxApproximationCommand;
import net.osmand.plus.measurementtool.command.ChangeRouteModeCommand;
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;
@ -96,7 +95,6 @@ import java.util.Locale;
import static net.osmand.IndexConstants.GPX_FILE_EXT; import static net.osmand.IndexConstants.GPX_FILE_EXT;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode; import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.ExportAsGpxListener;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.SnapToRoadProgressListener; import static net.osmand.plus.measurementtool.MeasurementEditingContext.SnapToRoadProgressListener;
import static net.osmand.plus.measurementtool.SelectFileBottomSheet.Mode.ADD_TO_TRACK; import static net.osmand.plus.measurementtool.SelectFileBottomSheet.Mode.ADD_TO_TRACK;
import static net.osmand.plus.measurementtool.SelectFileBottomSheet.Mode.OPEN_TRACK; import static net.osmand.plus.measurementtool.SelectFileBottomSheet.Mode.OPEN_TRACK;
@ -297,7 +295,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
OptionsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(), OptionsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
MeasurementToolFragment.this, MeasurementToolFragment.this,
editingCtx.isTrackSnappedToRoad() || editingCtx.isNewData(), editingCtx.isTrackSnappedToRoad() || editingCtx.isNewData(),
editingCtx.isInSnapToRoadMode(),
editingCtx.getAppMode().getStringKey() editingCtx.getAppMode().getStringKey()
); );
} }
@ -416,8 +413,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (editingCtx.getPointsCount() > 0) { if (editingCtx.getPointsCount() > 0) {
if (newGpxData != null && newGpxData.getActionType() == ActionType.EDIT_SEGMENT if (newGpxData != null && newGpxData.getActionType() == ActionType.EDIT_SEGMENT) {
&& editingCtx.isInSnapToRoadMode()) {
openSaveAsNewTrackMenu(mapActivity); openSaveAsNewTrackMenu(mapActivity);
} else { } else {
if (newGpxData == null) { if (newGpxData == null) {
@ -488,7 +484,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (!points.isEmpty()) { if (!points.isEmpty()) {
ApplicationMode snapToRoadAppMode = ApplicationMode.valueOfStringKey(points.get(points.size() - 1).getProfileType(), null); ApplicationMode snapToRoadAppMode = ApplicationMode.valueOfStringKey(points.get(points.size() - 1).getProfileType(), null);
if (snapToRoadAppMode != null) { if (snapToRoadAppMode != null) {
setSnapToRoadMode(snapToRoadAppMode); setAppMode(snapToRoadAppMode);
} }
} }
ActionType actionType = newGpxData.getActionType(); ActionType actionType = newGpxData.getActionType();
@ -604,7 +600,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() || editingCtx.isInSnapToRoadMode()) { if (editingCtx.isNewData() || editingCtx.hasRoutePoints() || editingCtx.hasRoute()) {
RouteBetweenPointsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(), RouteBetweenPointsBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager(),
this, editingCtx.getCalculationMode(), this, editingCtx.getCalculationMode(),
editingCtx.getAppMode()); editingCtx.getAppMode());
@ -670,12 +666,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (mapActivity != null) { if (mapActivity != null) {
if (editingCtx.getPointsCount() > 0) { if (editingCtx.getPointsCount() > 0) {
if (editingCtx.isInSnapToRoadMode()) {
editingCtx.getPoints().clear(); editingCtx.getPoints().clear();
editingCtx.getPoints().addAll(editingCtx.getBeforePoints()); editingCtx.getPoints().addAll(editingCtx.getBeforePoints());
editingCtx.getBeforePoints().clear(); editingCtx.getBeforePoints().clear();
editingCtx.getBeforePoints().addAll(editingCtx.getBeforeTrkSegmentLine().points); editingCtx.getBeforePoints().addAll(editingCtx.getBeforeTrkSegmentLine().points);
}
if (editingCtx.isNewData()) { if (editingCtx.isNewData()) {
saveAsGpx(SaveType.ROUTE_POINT); saveAsGpx(SaveType.ROUTE_POINT);
} else { } else {
@ -779,15 +773,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
} }
@Override @Override
public void onCloseRouteDialog(boolean snapToRoadEnabled) { public void onCloseRouteDialog() {
if (!snapToRoadEnabled && !editingCtx.isInSnapToRoadMode()) {
toolBarController.setTitle(previousToolBarTitle); toolBarController.setTitle(previousToolBarTitle);
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (mapActivity != null) { if (mapActivity != null) {
mapActivity.refreshMap(); mapActivity.refreshMap();
} }
} }
}
@Override @Override
public void onChangeApplicationMode(ApplicationMode mode, CalculationMode calculationMode) { public void onChangeApplicationMode(ApplicationMode mode, CalculationMode calculationMode) {
@ -984,13 +976,13 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}; };
} }
private void setSnapToRoadMode(@NonNull ApplicationMode appMode) { private void setAppMode(@NonNull ApplicationMode appMode) {
editingCtx.setAppMode(appMode); editingCtx.setAppMode(appMode);
editingCtx.scheduleRouteCalculateIfNotEmpty(); editingCtx.scheduleRouteCalculateIfNotEmpty();
updateSnapToRoadControls(); updateSnapToRoadControls();
} }
private void resetSnapToRoadMode() { private void resetAppMode() {
toolBarController.setTopBarSwitchVisible(false); toolBarController.setTopBarSwitchVisible(false);
toolBarController.setTitle(previousToolBarTitle); toolBarController.setTitle(previousToolBarTitle);
mainIcon.setImageDrawable(getActiveIcon(R.drawable.ic_action_ruler)); mainIcon.setImageDrawable(getActiveIcon(R.drawable.ic_action_ruler));
@ -1462,8 +1454,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private ProgressDialog progressDialog; private ProgressDialog progressDialog;
private File toSave; private File toSave;
private boolean exportRouteAsGpx = false;
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
cancelModes(); cancelModes();
@ -1492,44 +1482,20 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (measurementLayer != null) { if (measurementLayer != null) {
if (saveType == SaveType.LINE) { if (saveType == SaveType.LINE) {
TrkSegment segment = new TrkSegment(); TrkSegment segment = new TrkSegment();
if (editingCtx.isInSnapToRoadMode()) {
segment.points.addAll(before.points); segment.points.addAll(before.points);
segment.points.addAll(after.points); segment.points.addAll(after.points);
} else {
segment.points.addAll(points);
}
Track track = new Track(); Track track = new Track();
track.name = trackName; track.name = trackName;
track.segments.add(segment); track.segments.add(segment);
gpx.tracks.add(track); gpx.tracks.add(track);
} else if (saveType == SaveType.ROUTE_POINT) { } else if (saveType == SaveType.ROUTE_POINT) {
if (editingCtx.isInSnapToRoadMode()) { if (editingCtx.hasRoute()) {
exportRouteAsGpx = true; GPXFile newGpx = editingCtx.exportRouteAsGpx(trackName);
editingCtx.exportRouteAsGpx(trackName, new ExportAsGpxListener() { if (newGpx != null) {
@Override gpx = newGpx;
public void onExportAsGpxFinished(GPXFile gpx) {
gpx.addRoutePoints(editingCtx.getPoints());
final Exception res = GPXUtilities.writeGpxFile(toSave, gpx);
gpx.path = toSave.getAbsolutePath();
OsmandApplication app = getMyApplication();
if (showOnMap && app != null) {
app.getSelectedGpxHelper().selectGpxFile(gpx, true, false);
app.runInUIThread(new Runnable() {
@Override
public void run() {
onGpxSaved(res);
}
});
} }
} }
}); gpx.addRoutePoints(points);
return null;
} else {
Route rt = new Route();
rt.name = trackName;
gpx.routes.add(rt);
rt.points.addAll(points);
}
} }
} }
Exception res = GPXUtilities.writeGpxFile(toSave, gpx); Exception res = GPXUtilities.writeGpxFile(toSave, gpx);
@ -1543,33 +1509,33 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (measurementLayer != null) { if (measurementLayer != null) {
if (actionType != null) { if (actionType != null) {
switch (actionType) { switch (actionType) {
case ADD_SEGMENT: case ADD_SEGMENT: {
if (editingCtx.isInSnapToRoadMode()) {
List<WptPt> snappedPoints = new ArrayList<>(); List<WptPt> snappedPoints = new ArrayList<>();
snappedPoints.addAll(before.points); snappedPoints.addAll(before.points);
snappedPoints.addAll(after.points); snappedPoints.addAll(after.points);
gpx.addTrkSegment(snappedPoints); gpx.addTrkSegment(snappedPoints);
} else {
gpx.addTrkSegment(points);
}
break; break;
case ADD_ROUTE_POINTS: }
case ADD_ROUTE_POINTS: {
gpx.replaceRoutePoints(points); gpx.replaceRoutePoints(points);
break; break;
case EDIT_SEGMENT: }
case EDIT_SEGMENT: {
TrkSegment segment = new TrkSegment(); TrkSegment segment = new TrkSegment();
segment.points.addAll(points); segment.points.addAll(points);
gpx.replaceSegment(editingCtx.getNewGpxData().getTrkSegment(), segment); gpx.replaceSegment(editingCtx.getNewGpxData().getTrkSegment(), segment);
break; break;
case OVERWRITE_SEGMENT: }
case OVERWRITE_SEGMENT: {
List<WptPt> snappedPoints = new ArrayList<>(); List<WptPt> snappedPoints = new ArrayList<>();
snappedPoints.addAll(before.points); snappedPoints.addAll(before.points);
snappedPoints.addAll(after.points); snappedPoints.addAll(after.points);
TrkSegment segment1 = new TrkSegment(); TrkSegment segment = new TrkSegment();
segment1.points.addAll(snappedPoints); segment.points.addAll(snappedPoints);
gpx.replaceSegment(editingCtx.getNewGpxData().getTrkSegment(), segment1); gpx.replaceSegment(editingCtx.getNewGpxData().getTrkSegment(), segment);
break; break;
} }
}
} else { } else {
gpx.addRoutePoints(points); gpx.addRoutePoints(points);
} }
@ -1589,10 +1555,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Override @Override
protected void onPostExecute(Exception warning) { protected void onPostExecute(Exception warning) {
if (!exportRouteAsGpx) {
onGpxSaved(warning); onGpxSaved(warning);
} }
}
private void onGpxSaved(Exception warning) { private void onGpxSaved(Exception warning) {
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
@ -1663,7 +1627,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private void updateDistancePointsText() { private void updateDistancePointsText() {
MeasurementToolLayer measurementLayer = getMeasurementLayer(); MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (measurementLayer != null) { if (measurementLayer != null) {
distanceTv.setText(measurementLayer.getDistanceSt() + ","); String distanceStr = OsmAndFormatter.getFormattedDistance((float) editingCtx.getRouteDistance(), requireMyApplication());
distanceTv.setText(distanceStr + ",");
pointsTv.setText((portrait ? pointsSt + ": " : "") + editingCtx.getPointsCount()); pointsTv.setText((portrait ? pointsSt + ": " : "") + editingCtx.getPointsCount());
} }
updateToolbar(); updateToolbar();
@ -1780,11 +1745,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (pointsListOpened) { if (pointsListOpened) {
hidePointsList(); hidePointsList();
} }
if (editingCtx.isInSnapToRoadMode()) { resetAppMode();
resetSnapToRoadMode();
} else {
visibleSnapToRoadIcon(false);
}
if (!editingCtx.isNewData() && !planRouteMode) { if (!editingCtx.isNewData() && !planRouteMode) {
GPXFile gpx = editingCtx.getNewGpxData().getGpxFile(); GPXFile gpx = editingCtx.getNewGpxData().getGpxFile();
Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization().getTrackActivity()); Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization().getTrackActivity());

View file

@ -13,13 +13,12 @@ import net.osmand.Location;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.data.RotatedTileBox; import net.osmand.data.RotatedTileBox;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.views.layers.ContextMenuLayer;
import net.osmand.plus.views.OsmandMapLayer; import net.osmand.plus.views.OsmandMapLayer;
import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.Renderable; import net.osmand.plus.views.Renderable;
import net.osmand.plus.views.layers.ContextMenuLayer;
import net.osmand.plus.views.layers.geometry.GeometryWay; import net.osmand.plus.views.layers.geometry.GeometryWay;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
@ -100,18 +99,6 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
this.inMeasurementMode = inMeasurementMode; this.inMeasurementMode = inMeasurementMode;
} }
String getDistanceSt() {
float dist = 0;
List<WptPt> points = editingCtx.getBeforeTrkSegmentLine().points;
if (points.size() > 0) {
for (int i = 1; i < points.size(); i++) {
dist += MapUtils.getDistance(points.get(i - 1).lat, points.get(i - 1).lon,
points.get(i).lat, points.get(i).lon);
}
}
return OsmAndFormatter.getFormattedDistance(dist, view.getApplication());
}
@Override @Override
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) { public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
if (inMeasurementMode && editingCtx.getSelectedPointPosition() == -1) { if (inMeasurementMode && editingCtx.getSelectedPointPosition() == -1) {
@ -305,13 +292,9 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
private void drawCenterIcon(Canvas canvas, RotatedTileBox tb, boolean nightMode) { private void drawCenterIcon(Canvas canvas, RotatedTileBox tb, boolean nightMode) {
canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
if (nightMode) { Bitmap centerBmp = nightMode ? centerIconNight : centerIconDay;
canvas.drawBitmap(centerIconNight, tb.getCenterPixelX() - centerIconNight.getWidth() / 2f, canvas.drawBitmap(centerBmp, tb.getCenterPixelX() - centerBmp.getWidth() / 2f,
tb.getCenterPixelY() - centerIconNight.getHeight() / 2f, bitmapPaint); tb.getCenterPixelY() - centerBmp.getHeight() / 2f, bitmapPaint);
} else {
canvas.drawBitmap(centerIconDay, tb.getCenterPixelX() - centerIconDay.getWidth() / 2f,
tb.getCenterPixelY() - centerIconDay.getHeight() / 2f, bitmapPaint);
}
canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
} }

View file

@ -27,7 +27,6 @@ public class OptionsBottomSheetDialogFragment extends MenuBottomSheetDialogFragm
public static final String TAG = OptionsBottomSheetDialogFragment.class.getSimpleName(); public static final String TAG = OptionsBottomSheetDialogFragment.class.getSimpleName();
private static final Log LOG = PlatformUtil.getLog(OptionsBottomSheetDialogFragment.class); private static final Log LOG = PlatformUtil.getLog(OptionsBottomSheetDialogFragment.class);
public static final String SNAP_TO_ROAD_ENABLED_KEY = "snap_to_road_enabled";
public static final String TRACK_SNAPPED_TO_ROAD_KEY = "track_snapped_to_road"; public static final String TRACK_SNAPPED_TO_ROAD_KEY = "track_snapped_to_road";
public static final String SNAP_TO_ROAD_APP_MODE_KEY = "snap_to_road_app_mode"; public static final String SNAP_TO_ROAD_APP_MODE_KEY = "snap_to_road_app_mode";
@ -36,10 +35,8 @@ public class OptionsBottomSheetDialogFragment extends MenuBottomSheetDialogFragm
@Override @Override
public void createMenuItems(Bundle savedInstanceState) { public void createMenuItems(Bundle savedInstanceState) {
Bundle args = getArguments(); Bundle args = getArguments();
boolean snapToRoadEnabled = false;
boolean trackSnappedToRoad = false; boolean trackSnappedToRoad = false;
if (args != null) { if (args != null) {
snapToRoadEnabled = args.getBoolean(SNAP_TO_ROAD_ENABLED_KEY);
trackSnappedToRoad = args.getBoolean(TRACK_SNAPPED_TO_ROAD_KEY); trackSnappedToRoad = args.getBoolean(TRACK_SNAPPED_TO_ROAD_KEY);
routeAppMode = ApplicationMode.valueOfStringKey(args.getString(SNAP_TO_ROAD_APP_MODE_KEY), null); routeAppMode = ApplicationMode.valueOfStringKey(args.getString(SNAP_TO_ROAD_APP_MODE_KEY), null);
} }
@ -49,7 +46,7 @@ public class OptionsBottomSheetDialogFragment extends MenuBottomSheetDialogFragm
String description; String description;
Drawable icon; Drawable icon;
if (trackSnappedToRoad) { if (trackSnappedToRoad) {
if (!snapToRoadEnabled || routeAppMode == null) { if (routeAppMode == null || routeAppMode == MeasurementEditingContext.DEFAULT_APP_MODE) {
description = getString(R.string.routing_profile_straightline); description = getString(R.string.routing_profile_straightline);
icon = getContentIcon(R.drawable.ic_action_split_interval); icon = getContentIcon(R.drawable.ic_action_split_interval);
} else { } else {
@ -165,14 +162,13 @@ public class OptionsBottomSheetDialogFragment extends MenuBottomSheetDialogFragm
params.rightMargin = view.getContext().getResources().getDimensionPixelSize(R.dimen.bottom_sheet_icon_margin_large); params.rightMargin = view.getContext().getResources().getDimensionPixelSize(R.dimen.bottom_sheet_icon_margin_large);
} }
public static void showInstance(@NonNull FragmentManager fm, Fragment targetFragment, boolean trackSnappedToRoad, public static void showInstance(@NonNull FragmentManager fm, Fragment targetFragment,
boolean snapToRoad, String routeAppModeStringKey) { boolean trackSnappedToRoad, String routeAppModeStringKey) {
try { try {
if (!fm.isStateSaved()) { if (!fm.isStateSaved()) {
OptionsBottomSheetDialogFragment fragment = new OptionsBottomSheetDialogFragment(); OptionsBottomSheetDialogFragment fragment = new OptionsBottomSheetDialogFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putBoolean(TRACK_SNAPPED_TO_ROAD_KEY, trackSnappedToRoad); args.putBoolean(TRACK_SNAPPED_TO_ROAD_KEY, trackSnappedToRoad);
args.putBoolean(SNAP_TO_ROAD_ENABLED_KEY, snapToRoad);
args.putString(SNAP_TO_ROAD_APP_MODE_KEY, routeAppModeStringKey); args.putString(SNAP_TO_ROAD_APP_MODE_KEY, routeAppModeStringKey);
fragment.setArguments(args); fragment.setArguments(args);
fragment.setTargetFragment(targetFragment,0); fragment.setTargetFragment(targetFragment,0);

View file

@ -49,10 +49,9 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial
private boolean nightMode; private boolean nightMode;
private boolean portrait; private boolean portrait;
private boolean snapToRoadEnabled = true;
private TextView btnDescription; private TextView btnDescription;
private CalculationMode calculationMode = WHOLE_TRACK; private CalculationMode calculationMode = WHOLE_TRACK;
private ApplicationMode snapToRoadAppMode; private ApplicationMode appMode;
private LinearLayout customRadioButton; private LinearLayout customRadioButton;
@ -61,7 +60,7 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle args = getArguments(); Bundle args = getArguments();
if (args != null) { if (args != null) {
snapToRoadAppMode = ApplicationMode.valueOfStringKey(args.getString(ROUTE_APP_MODE_KEY), null); appMode = ApplicationMode.valueOfStringKey(args.getString(ROUTE_APP_MODE_KEY), null);
calculationMode = (CalculationMode) args.get(CALCULATION_MODE_KEY); calculationMode = (CalculationMode) args.get(CALCULATION_MODE_KEY);
} }
if (savedInstanceState != null) { if (savedInstanceState != null) {
@ -102,11 +101,9 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial
View.OnClickListener onClickListener = new View.OnClickListener() { View.OnClickListener onClickListener = new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
snapToRoadEnabled = false;
ApplicationMode mode = DEFAULT_APP_MODE; ApplicationMode mode = DEFAULT_APP_MODE;
if ((int) view.getTag() != STRAIGHT_LINE_TAG) { if ((int) view.getTag() != STRAIGHT_LINE_TAG) {
mode = modes.get((int) view.getTag()); mode = modes.get((int) view.getTag());
snapToRoadEnabled = true;
} }
Fragment fragment = getTargetFragment(); Fragment fragment = getTargetFragment();
if (fragment instanceof RouteBetweenPointsFragmentListener) { if (fragment instanceof RouteBetweenPointsFragmentListener) {
@ -118,13 +115,13 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial
Drawable icon = app.getUIUtilities().getIcon(R.drawable.ic_action_split_interval, nightMode); Drawable icon = app.getUIUtilities().getIcon(R.drawable.ic_action_split_interval, nightMode);
addProfileView(navigationType, onClickListener, STRAIGHT_LINE_TAG, icon, addProfileView(navigationType, onClickListener, STRAIGHT_LINE_TAG, icon,
app.getText(R.string.routing_profile_straightline), snapToRoadAppMode == DEFAULT_APP_MODE); app.getText(R.string.routing_profile_straightline), appMode == DEFAULT_APP_MODE);
addDelimiterView(navigationType); addDelimiterView(navigationType);
for (int i = 0; i < modes.size(); i++) { for (int i = 0; i < modes.size(); i++) {
ApplicationMode mode = modes.get(i); ApplicationMode mode = modes.get(i);
icon = app.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode)); icon = app.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode));
addProfileView(navigationType, onClickListener, i, icon, mode.toHumanString(), mode.equals(snapToRoadAppMode)); addProfileView(navigationType, onClickListener, i, icon, mode.toHumanString(), mode.equals(appMode));
} }
segmentBtn.setOnClickListener(new View.OnClickListener() { segmentBtn.setOnClickListener(new View.OnClickListener() {
@ -202,7 +199,7 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial
public void onDestroyView() { public void onDestroyView() {
Fragment fragment = getTargetFragment(); Fragment fragment = getTargetFragment();
if (fragment instanceof RouteBetweenPointsFragmentListener) { if (fragment instanceof RouteBetweenPointsFragmentListener) {
((RouteBetweenPointsFragmentListener) fragment).onCloseRouteDialog(snapToRoadEnabled); ((RouteBetweenPointsFragmentListener) fragment).onCloseRouteDialog();
} }
super.onDestroyView(); super.onDestroyView();
} }
@ -230,7 +227,7 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetDial
public interface RouteBetweenPointsFragmentListener { public interface RouteBetweenPointsFragmentListener {
void onCloseRouteDialog(boolean snapToRoadEnabled); void onCloseRouteDialog();
void onChangeApplicationMode(ApplicationMode mode, CalculationMode calculationMode); void onChangeApplicationMode(ApplicationMode mode, CalculationMode calculationMode);

View file

@ -15,7 +15,6 @@ public class ApplyGpxApproximationCommand extends MeasurementModeCommand {
private ApplicationMode mode; private ApplicationMode mode;
private GpxRouteApproximation approximation; private GpxRouteApproximation approximation;
private List<WptPt> points; private List<WptPt> points;
private boolean needUpdateCache;
public ApplyGpxApproximationCommand(MeasurementToolLayer measurementLayer, GpxRouteApproximation approximation, ApplicationMode mode) { public ApplyGpxApproximationCommand(MeasurementToolLayer measurementLayer, GpxRouteApproximation approximation, ApplicationMode mode) {
super(measurementLayer); super(measurementLayer);
@ -31,7 +30,6 @@ public class ApplyGpxApproximationCommand extends MeasurementModeCommand {
@Override @Override
public boolean execute() { public boolean execute() {
List<WptPt> pts = getEditingCtx().getPoints(); List<WptPt> pts = getEditingCtx().getPoints();
needUpdateCache = getEditingCtx().isNeedUpdateCacheForSnap();
points = new ArrayList<>(pts); points = new ArrayList<>(pts);
applyApproximation(); applyApproximation();
refreshMap(); refreshMap();
@ -55,9 +53,7 @@ public class ApplyGpxApproximationCommand extends MeasurementModeCommand {
getEditingCtx().resetAppMode(); getEditingCtx().resetAppMode();
getEditingCtx().clearSegments(); getEditingCtx().clearSegments();
getEditingCtx().addPoints(points); getEditingCtx().addPoints(points);
if (needUpdateCache) { getEditingCtx().updateCacheForSnap();
getEditingCtx().setNeedUpdateCacheForSnap(true);
}
refreshMap(); refreshMap();
} }

View file

@ -48,7 +48,7 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand {
editingCtx.clearSnappedToRoadPoints(); editingCtx.clearSnappedToRoadPoints();
} }
editingCtx.setCalculationMode(oldCalculationMode); editingCtx.setCalculationMode(oldCalculationMode);
editingCtx.setNeedUpdateCacheForSnap(true); editingCtx.updateCacheForSnap();
} }
@Override @Override
@ -75,6 +75,6 @@ public class ChangeRouteModeCommand extends MeasurementModeCommand {
if (newCalculationMode == CalculationMode.WHOLE_TRACK) { if (newCalculationMode == CalculationMode.WHOLE_TRACK) {
editingCtx.clearSnappedToRoadPoints(); editingCtx.clearSnappedToRoadPoints();
} }
editingCtx.setNeedUpdateCacheForSnap(true); editingCtx.updateCacheForSnap();
} }
} }

View file

@ -4,13 +4,11 @@ import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementToolLayer; import net.osmand.plus.measurementtool.MeasurementToolLayer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; 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;
public ClearPointsCommand(MeasurementToolLayer measurementLayer) { public ClearPointsCommand(MeasurementToolLayer measurementLayer) {
super(measurementLayer); super(measurementLayer);
@ -19,7 +17,6 @@ public class ClearPointsCommand extends MeasurementModeCommand {
@Override @Override
public boolean execute() { public boolean execute() {
List<WptPt> pts = getEditingCtx().getPoints(); List<WptPt> pts = getEditingCtx().getPoints();
needUpdateCache = getEditingCtx().isNeedUpdateCacheForSnap();
points = new ArrayList<>(pts); points = new ArrayList<>(pts);
pts.clear(); pts.clear();
getEditingCtx().clearSegments(); getEditingCtx().clearSegments();
@ -30,9 +27,7 @@ public class ClearPointsCommand extends MeasurementModeCommand {
@Override @Override
public void undo() { public void undo() {
getEditingCtx().addPoints(points); getEditingCtx().addPoints(points);
if (needUpdateCache) { getEditingCtx().updateCacheForSnap();
getEditingCtx().setNeedUpdateCacheForSnap(true);
}
refreshMap(); refreshMap();
} }

View file

@ -18,7 +18,7 @@ public class ReorderPointCommand extends MeasurementModeCommand {
@Override @Override
public boolean execute() { public boolean execute() {
getEditingCtx().setNeedUpdateCacheForSnap(true); getEditingCtx().updateCacheForSnap();
refreshMap(); refreshMap();
return true; return true;
} }
@ -36,7 +36,7 @@ public class ReorderPointCommand extends MeasurementModeCommand {
private void reorder(int addTo, int removeFrom) { private void reorder(int addTo, int removeFrom) {
List<WptPt> points = getEditingCtx().getPoints(); List<WptPt> points = getEditingCtx().getPoints();
points.add(addTo, points.remove(removeFrom)); points.add(addTo, points.remove(removeFrom));
getEditingCtx().setNeedUpdateCacheForSnap(true); getEditingCtx().updateCacheForSnap();
refreshMap(); refreshMap();
} }

View file

@ -1,6 +1,7 @@
package net.osmand.plus.routing; package net.osmand.plus.routing;
import android.content.Context; import android.content.Context;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import net.osmand.Location; import net.osmand.Location;
@ -11,10 +12,11 @@ import net.osmand.binary.RouteDataObject;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.LocationPoint; import net.osmand.data.LocationPoint;
import net.osmand.data.QuadRect; import net.osmand.data.QuadRect;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.routing.AlarmInfo.AlarmInfoType; import net.osmand.plus.routing.AlarmInfo.AlarmInfoType;
import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.router.ExitInfo; import net.osmand.router.ExitInfo;
import net.osmand.router.RouteSegmentResult; import net.osmand.router.RouteSegmentResult;
import net.osmand.router.RoutingContext; import net.osmand.router.RoutingContext;
@ -61,7 +63,7 @@ public class RouteCalculationResult {
// params // params
protected final ApplicationMode appMode; protected final ApplicationMode appMode;
protected final RouteProvider.RouteService routeService; protected final RouteService routeService;
protected final double routeRecalcDistance; protected final double routeRecalcDistance;
protected final double routeVisibleAngle; protected final double routeVisibleAngle;
@ -128,7 +130,7 @@ public class RouteCalculationResult {
this.routeService = params.mode.getRouteService(); this.routeService = params.mode.getRouteService();
if(params.ctx != null) { if(params.ctx != null) {
this.routeRecalcDistance = params.ctx.getSettings().ROUTE_RECALCULATION_DISTANCE.getModeValue(params.mode); this.routeRecalcDistance = params.ctx.getSettings().ROUTE_RECALCULATION_DISTANCE.getModeValue(params.mode);
this.routeVisibleAngle = routeService == RouteProvider.RouteService.STRAIGHT ? this.routeVisibleAngle = routeService == RouteService.STRAIGHT ?
params.ctx.getSettings().ROUTE_STRAIGHT_ANGLE.getModeValue(params.mode) : 0; params.ctx.getSettings().ROUTE_STRAIGHT_ANGLE.getModeValue(params.mode) : 0;
} else { } else {
this.routeRecalcDistance = 0; this.routeRecalcDistance = 0;
@ -178,7 +180,7 @@ public class RouteCalculationResult {
updateDirectionsTime(this.directions, this.listDistance); updateDirectionsTime(this.directions, this.listDistance);
this.alarmInfo = Collections.unmodifiableList(alarms); this.alarmInfo = Collections.unmodifiableList(alarms);
this.routeRecalcDistance = ctx.getSettings().ROUTE_RECALCULATION_DISTANCE.getModeValue(mode); this.routeRecalcDistance = ctx.getSettings().ROUTE_RECALCULATION_DISTANCE.getModeValue(mode);
this.routeVisibleAngle = routeService == RouteProvider.RouteService.STRAIGHT ? this.routeVisibleAngle = routeService == RouteService.STRAIGHT ?
ctx.getSettings().ROUTE_STRAIGHT_ANGLE.getModeValue(mode) : 0; ctx.getSettings().ROUTE_STRAIGHT_ANGLE.getModeValue(mode) : 0;
} }
@ -276,7 +278,7 @@ public class RouteCalculationResult {
return routeRecalcDistance; return routeRecalcDistance;
} }
public RouteProvider.RouteService getRouteService() { public RouteService getRouteService() {
return routeService; return routeService;
} }