Fix plan route recalculation after app mode settings change

This commit is contained in:
max-klaus 2020-12-23 16:13:44 +03:00
parent 75e93d6ec7
commit b2b6775105
22 changed files with 365 additions and 261 deletions

View file

@ -64,6 +64,7 @@ import net.osmand.plus.helpers.enums.MetricsConstants;
import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper; import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.monitoring.LiveMonitoringHelper; import net.osmand.plus.monitoring.LiveMonitoringHelper;
import net.osmand.plus.osmedit.oauth.OsmOAuthHelper; import net.osmand.plus.osmedit.oauth.OsmOAuthHelper;
import net.osmand.plus.poi.PoiFiltersHelper; import net.osmand.plus.poi.PoiFiltersHelper;
@ -156,6 +157,7 @@ public class OsmandApplication extends MultiDexApplication {
GpxDbHelper gpxDbHelper; GpxDbHelper gpxDbHelper;
QuickActionRegistry quickActionRegistry; QuickActionRegistry quickActionRegistry;
OsmOAuthHelper osmOAuthHelper; OsmOAuthHelper osmOAuthHelper;
MeasurementEditingContext measurementEditingContext;
private Resources localizedResources; private Resources localizedResources;
private Map<String, Builder> customRoutingConfigs = new ConcurrentHashMap<>(); private Map<String, Builder> customRoutingConfigs = new ConcurrentHashMap<>();
@ -465,6 +467,14 @@ public class OsmandApplication extends MultiDexApplication {
return routingHelper; return routingHelper;
} }
public MeasurementEditingContext getMeasurementEditingContext() {
return measurementEditingContext;
}
public void setMeasurementEditingContext(MeasurementEditingContext context) {
this.measurementEditingContext = context;
}
public TransportRoutingHelper getTransportRoutingHelper() { public TransportRoutingHelper getTransportRoutingHelper() {
return transportRoutingHelper; return transportRoutingHelper;
} }

View file

@ -553,7 +553,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
allowPrivate.setModeValue(mode, true); allowPrivate.setModeValue(mode, true);
} }
} }
getRoutingHelper().onSettingsChanged(true); getRoutingHelper().onSettingsChanged(null, true);
} }
}); });
dlg.setNegativeButton(R.string.shared_string_no, null); dlg.setNegativeButton(R.string.shared_string_no, null);

View file

@ -119,7 +119,7 @@ public class AvoidSpecificRoads {
remove(item); remove(item);
removeImpassableRoad(item); removeImpassableRoad(item);
notifyDataSetChanged(); notifyDataSetChanged();
recalculateRoute(); recalculateRoute(item != null ? item.appModeKey : null);
} }
}); });
return v; return v;
@ -163,8 +163,9 @@ public class AvoidSpecificRoads {
return app.getString(R.string.shared_string_road); return app.getString(R.string.shared_string_road);
} }
private void recalculateRoute() { private void recalculateRoute(@Nullable String appModeKey) {
app.getRoutingHelper().onSettingsChanged(); ApplicationMode mode = ApplicationMode.valueOfStringKey(appModeKey, null);
app.getRoutingHelper().onSettingsChanged(mode);
} }
public void removeImpassableRoad(LatLon latLon) { public void removeImpassableRoad(LatLon latLon) {
@ -181,7 +182,7 @@ public class AvoidSpecificRoads {
removeImpassableRoad(getLocation(obj)); removeImpassableRoad(getLocation(obj));
} }
public void showDialog(@NonNull final MapActivity mapActivity) { public void showDialog(@NonNull final MapActivity mapActivity, final @Nullable ApplicationMode mode) {
boolean nightMode = app.getDaynightHelper().isNightModeForMapControls(); boolean nightMode = app.getDaynightHelper().isNightModeForMapControls();
Context themedContext = UiUtilities.getThemedContext(mapActivity, nightMode); Context themedContext = UiUtilities.getThemedContext(mapActivity, nightMode);
@ -206,14 +207,14 @@ public class AvoidSpecificRoads {
bld.setPositiveButton(R.string.shared_string_select_on_map, new DialogInterface.OnClickListener() { bld.setPositiveButton(R.string.shared_string_select_on_map, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialogInterface, int i) { public void onClick(DialogInterface dialogInterface, int i) {
selectFromMap(mapActivity); selectFromMap(mapActivity, mode);
} }
}); });
bld.setNegativeButton(R.string.shared_string_close, null); bld.setNegativeButton(R.string.shared_string_close, null);
bld.show(); bld.show();
} }
public void selectFromMap(final MapActivity mapActivity) { public void selectFromMap(@NonNull final MapActivity mapActivity) {
ContextMenuLayer cm = mapActivity.getMapLayers().getContextMenuLayer(); ContextMenuLayer cm = mapActivity.getMapLayers().getContextMenuLayer();
cm.setSelectOnMap(new CallbackWithObject<LatLon>() { cm.setSelectOnMap(new CallbackWithObject<LatLon>() {
@Override @Override
@ -224,6 +225,17 @@ public class AvoidSpecificRoads {
}); });
} }
public void selectFromMap(@NonNull final MapActivity mapActivity, @Nullable final ApplicationMode mode) {
ContextMenuLayer cm = mapActivity.getMapLayers().getContextMenuLayer();
cm.setSelectOnMap(new CallbackWithObject<LatLon>() {
@Override
public boolean processResult(LatLon result) {
addImpassableRoad(mapActivity, result, true, false, mode != null ? mode.getStringKey() : null);
return true;
}
});
}
public void addImpassableRoad(@Nullable final MapActivity mapActivity, public void addImpassableRoad(@Nullable final MapActivity mapActivity,
@NonNull final LatLon loc, @NonNull final LatLon loc,
final boolean showDialog, final boolean showDialog,
@ -236,7 +248,9 @@ public class AvoidSpecificRoads {
ApplicationMode defaultAppMode = app.getRoutingHelper().getAppMode(); ApplicationMode defaultAppMode = app.getRoutingHelper().getAppMode();
final ApplicationMode appMode = appModeKey != null ? ApplicationMode.valueOfStringKey(appModeKey, defaultAppMode) : defaultAppMode; final ApplicationMode appMode = appModeKey != null ? ApplicationMode.valueOfStringKey(appModeKey, defaultAppMode) : defaultAppMode;
List<RouteSegmentResult> roads = app.getRoutingHelper().getRoute().getOriginalRoute(); List<RouteSegmentResult> roads = app.getMeasurementEditingContext() != null
? app.getMeasurementEditingContext().getRoadSegmentData(appMode)
: app.getRoutingHelper().getRoute().getOriginalRoute();
if (mapActivity != null && roads != null) { if (mapActivity != null && roads != null) {
RotatedTileBox tb = mapActivity.getMapView().getCurrentRotatedTileBox().copy(); RotatedTileBox tb = mapActivity.getMapView().getCurrentRotatedTileBox().copy();
float maxDistPx = MAX_AVOID_ROUTE_SEARCH_RADIUS_DP * tb.getDensity(); float maxDistPx = MAX_AVOID_ROUTE_SEARCH_RADIUS_DP * tb.getDensity();
@ -346,10 +360,10 @@ public class AvoidSpecificRoads {
app.getSettings().removeImpassableRoad(location); app.getSettings().removeImpassableRoad(location);
} }
} }
recalculateRoute(); recalculateRoute(avoidRoadInfo.appModeKey);
if (activity != null) { if (activity != null) {
if (showDialog) { if (showDialog) {
showDialog(activity); showDialog(activity, ApplicationMode.valueOfStringKey(avoidRoadInfo.appModeKey, null));
} }
MapContextMenu menu = activity.getContextMenu(); MapContextMenu menu = activity.getContextMenu();
if (menu.isActive()) { if (menu.isActive()) {

View file

@ -135,12 +135,12 @@ public class GraphsCard extends BaseCard implements OnUpdateInfoListener {
} }
private void updateMenu() { private void updateMenu() {
if (!editingCtx.isPointsEnoughToCalculateRoute()) { if (editingCtx.isPointsEnoughToCalculateRoute()) {
graphTypesMenu.setVisibility(View.GONE);
} else {
graphTypesMenu.setVisibility(View.VISIBLE); graphTypesMenu.setVisibility(View.VISIBLE);
graphTypesMenu.removeAllViews(); graphTypesMenu.removeAllViews();
fillInMenu(); fillInMenu();
} else {
graphTypesMenu.setVisibility(View.GONE);
} }
} }
@ -349,7 +349,7 @@ public class GraphsCard extends BaseCard implements OnUpdateInfoListener {
private List<RouteStatistics> calculateRouteStatistics() { private List<RouteStatistics> calculateRouteStatistics() {
OsmandApplication app = getMyApplication(); OsmandApplication app = getMyApplication();
List<RouteSegmentResult> route = editingCtx.getAllRouteSegments(); List<RouteSegmentResult> route = editingCtx.getOrderedRoadSegmentData();
if (route != null && app != null) { if (route != null && app != null) {
return RouteDetailsFragment.calculateRouteStatistics(app, route, nightMode); return RouteDetailsFragment.calculateRouteStatistics(app, route, nightMode);
} }

View file

@ -16,11 +16,12 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.measurementtool.command.ApplyGpxApproximationCommand; import net.osmand.plus.measurementtool.command.ApplyGpxApproximationCommand;
import net.osmand.plus.measurementtool.command.MeasurementCommandManager; import net.osmand.plus.measurementtool.command.MeasurementCommandManager;
import net.osmand.plus.measurementtool.command.MeasurementModeCommand; import net.osmand.plus.measurementtool.command.MeasurementModeCommand;
import net.osmand.plus.routing.IRouteSettingsListener;
import net.osmand.plus.routing.RouteCalculationParams; import net.osmand.plus.routing.RouteCalculationParams;
import net.osmand.plus.routing.RouteCalculationParams.RouteCalculationResultListener; import net.osmand.plus.routing.RouteCalculationParams.RouteCalculationResultListener;
import net.osmand.plus.routing.RouteCalculationProgressCallback;
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.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.RouteExporter;
@ -40,12 +41,13 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode.WHOLE_TRACK; import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode.WHOLE_TRACK;
import static net.osmand.plus.measurementtool.command.MeasurementModeCommand.MeasurementCommandType.APPROXIMATE_POINTS; import static net.osmand.plus.measurementtool.command.MeasurementModeCommand.MeasurementCommandType.APPROXIMATE_POINTS;
public class MeasurementEditingContext { public class MeasurementEditingContext implements IRouteSettingsListener {
public final static ApplicationMode DEFAULT_APP_MODE = ApplicationMode.DEFAULT; public final static ApplicationMode DEFAULT_APP_MODE = ApplicationMode.DEFAULT;
@ -70,9 +72,11 @@ public class MeasurementEditingContext {
private int calculatedPairs; private int calculatedPairs;
private int pointsToCalculateSize; private int pointsToCalculateSize;
private CalculationMode lastCalculationMode = WHOLE_TRACK; private CalculationMode lastCalculationMode = WHOLE_TRACK;
private SnapToRoadProgressListener progressListener;
private ApplicationMode appMode = DEFAULT_APP_MODE; private ApplicationMode appMode = DEFAULT_APP_MODE;
private SnapToRoadProgressListener progressListener;
private RouteCalculationProgress calculationProgress; private RouteCalculationProgress calculationProgress;
private Map<Pair<WptPt, WptPt>, RoadSegmentData> roadSegmentData = new ConcurrentHashMap<>(); private Map<Pair<WptPt, WptPt>, RoadSegmentData> roadSegmentData = new ConcurrentHashMap<>();
public enum CalculationMode { public enum CalculationMode {
@ -86,64 +90,20 @@ public class MeasurementEditingContext {
ADD_BEFORE, ADD_BEFORE,
} }
public static class RoadSegmentData { public void setApplication(OsmandApplication application) {
private final ApplicationMode appMode; this.application = application;
private final WptPt start; }
private final WptPt end;
private final List<WptPt> points;
private final List<RouteSegmentResult> segments;
private final double distance;
public RoadSegmentData(@NonNull ApplicationMode appMode, @NonNull WptPt start, @NonNull WptPt end, public void setupRouteSettingsListener() {
@Nullable List<WptPt> points, @Nullable List<RouteSegmentResult> segments) { if (application != null) {
this.appMode = appMode; application.getRoutingHelper().addRouteSettingsListener(this);
this.start = start;
this.end = end;
this.points = points;
this.segments = segments;
double distance = 0;
if (points != null && points.size() > 1) {
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);
}
} else if (segments != null) {
for (RouteSegmentResult segment : segments) {
distance += segment.getDistance();
}
}
this.distance = distance;
}
public ApplicationMode getAppMode() {
return appMode;
}
public WptPt getStart() {
return start;
}
public WptPt getEnd() {
return end;
}
@Nullable
public List<WptPt> getPoints() {
return points != null ? Collections.unmodifiableList(points) : null;
}
@Nullable
public List<RouteSegmentResult> getSegments() {
return segments != null ? Collections.unmodifiableList(segments) : null;
}
public double getDistance() {
return distance;
} }
} }
public void setApplication(OsmandApplication application) { public void resetRouteSettingsListener() {
this.application = application; if (application != null) {
application.getRoutingHelper().removeRouteSettingsListener(this);
}
} }
MeasurementCommandManager getCommandManager() { MeasurementCommandManager getCommandManager() {
@ -371,7 +331,7 @@ public class MeasurementEditingContext {
return getPointsCount() >= 2; return getPointsCount() >= 2;
} }
public List<RouteSegmentResult> getAllRouteSegments() { public List<RouteSegmentResult> getOrderedRoadSegmentData() {
List<RouteSegmentResult> allSegments = new ArrayList<>(); List<RouteSegmentResult> allSegments = new ArrayList<>();
for (Pair<WptPt, WptPt> key : getOrderedRoadSegmentDataKeys()) { for (Pair<WptPt, WptPt> key : getOrderedRoadSegmentDataKeys()) {
RoadSegmentData data = roadSegmentData.get(key); RoadSegmentData data = roadSegmentData.get(key);
@ -385,19 +345,48 @@ public class MeasurementEditingContext {
return allSegments.size() > 0 ? allSegments : null; return allSegments.size() > 0 ? allSegments : null;
} }
public void recalculateRouteSegmentsForAppMode() { @NonNull
clearRouteSegmentsByAppMode(); public List<RouteSegmentResult> getRoadSegmentData(@Nullable ApplicationMode mode) {
updateSegmentsForSnap(); List<RouteSegmentResult> res = new ArrayList<>();
} if (mode == null) {
for (RoadSegmentData data : roadSegmentData.values()) {
public void clearRouteSegmentsByAppMode() { List<RouteSegmentResult> segments = data.getSegments();
for (Pair<WptPt, WptPt> key : getOrderedRoadSegmentDataKeys()) { if (!Algorithms.isEmpty(segments)) {
if(key.first.getProfileType().equals(appMode.getStringKey())) { res.addAll(segments);
RoadSegmentData data = roadSegmentData.get(key);
if (data != null) {
roadSegmentData.remove(key);
} }
} }
} else {
for (Entry<Pair<WptPt, WptPt>, RoadSegmentData> dataEntry : roadSegmentData.entrySet()) {
WptPt firstPoint = dataEntry.getKey().first;
if (mode.getStringKey().equals(firstPoint.getProfileType())) {
List<RouteSegmentResult> segments = dataEntry.getValue().getSegments();
if (!Algorithms.isEmpty(segments)) {
res.addAll(segments);
}
}
}
}
return res;
}
void recalculateRouteSegments(@Nullable ApplicationMode mode) {
boolean changed = false;
if (mode == null) {
roadSegmentData.clear();
changed = true;
} else {
for (Pair<WptPt, WptPt> pair : getOrderedRoadSegmentDataKeys()) {
if (mode.getStringKey().equals(pair.first.getProfileType())) {
RoadSegmentData data = roadSegmentData.get(pair);
if (data != null) {
roadSegmentData.remove(pair);
changed = true;
}
}
}
}
if (changed) {
updateSegmentsForSnap(false);
} }
} }
@ -794,11 +783,11 @@ public class MeasurementEditingContext {
Pair<WptPt, WptPt> pair = new Pair<>(routePoints.get(i), routePoints.get(i + 1)); Pair<WptPt, WptPt> pair = new Pair<>(routePoints.get(i), routePoints.get(i + 1));
int startIndex = pair.first.getTrkPtIndex(); int startIndex = pair.first.getTrkPtIndex();
if (startIndex < 0 || startIndex < prevPointIndex || startIndex >= points.size()) { if (startIndex < 0 || startIndex < prevPointIndex || startIndex >= points.size()) {
startIndex = findPointIndex(pair.first, points, prevPointIndex); startIndex = MeasurementEditingContextUtils.findPointIndex(pair.first, points, prevPointIndex);
} }
int endIndex = pair.second.getTrkPtIndex(); 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 = MeasurementEditingContextUtils.findPointIndex(pair.second, points, startIndex);
} }
if (startIndex >= 0 && endIndex >= 0) { if (startIndex >= 0 && endIndex >= 0) {
List<WptPt> pairPoints = new ArrayList<>(); List<WptPt> pairPoints = new ArrayList<>();
@ -847,7 +836,7 @@ public class MeasurementEditingContext {
List<GpxPoint> gpxPoints = gpxApproximation.finalPoints; List<GpxPoint> gpxPoints = gpxApproximation.finalPoints;
for (int i = 0; i < gpxPoints.size(); i++) { for (int i = 0; i < gpxPoints.size(); i++) {
GpxPoint gp1 = gpxPoints.get(i); GpxPoint gp1 = gpxPoints.get(i);
boolean lastGpxPoint = isLastGpxPoint(gpxPoints, i); boolean lastGpxPoint = MeasurementEditingContextUtils.isLastGpxPoint(gpxPoints, i);
List<WptPt> points = new ArrayList<>(); List<WptPt> points = new ArrayList<>();
List<RouteSegmentResult> segments = new ArrayList<>(); List<RouteSegmentResult> segments = new ArrayList<>();
for (int k = 0; k < gp1.routeToTarget.size(); k++) { for (int k = 0; k < gp1.routeToTarget.size(); k++) {
@ -858,7 +847,7 @@ public class MeasurementEditingContext {
} }
for (int k = 0; k < segments.size(); k++) { for (int k = 0; k < segments.size(); k++) {
RouteSegmentResult seg = segments.get(k); RouteSegmentResult seg = segments.get(k);
fillPointsArray(points, seg, lastGpxPoint && k == segments.size() - 1); MeasurementEditingContextUtils.fillPointsArray(points, seg, lastGpxPoint && k == segments.size() - 1);
} }
if (!points.isEmpty()) { if (!points.isEmpty()) {
WptPt wp1 = new WptPt(); WptPt wp1 = new WptPt();
@ -893,61 +882,6 @@ public class MeasurementEditingContext {
return routePoints; return routePoints;
} }
private boolean isLastGpxPoint(List<GpxPoint> gpxPoints, int index) {
if (index == gpxPoints.size() - 1) {
return true;
} else {
for (int i = index + 1; i < gpxPoints.size(); i++) {
GpxPoint gp = gpxPoints.get(i);
for (int k = 0; k < gp.routeToTarget.size(); k++) {
RouteSegmentResult seg = gp.routeToTarget.get(k);
if (seg.getStartPointIndex() != seg.getEndPointIndex()) {
return false;
}
}
}
}
return true;
}
private void fillPointsArray(List<WptPt> points, RouteSegmentResult seg, boolean includeEndPoint) {
int ind = seg.getStartPointIndex();
boolean plus = seg.isForwardDirection();
float[] heightArray = seg.getObject().calculateHeightArray();
while (ind != seg.getEndPointIndex()) {
addPointToArray(points, seg, ind, heightArray);
ind = plus ? ind + 1 : ind - 1;
}
if (includeEndPoint) {
addPointToArray(points, seg, ind, heightArray);
}
}
private void addPointToArray(List<WptPt> points, RouteSegmentResult seg, int index, float[] heightArray) {
LatLon l = seg.getPoint(index);
WptPt pt = new WptPt();
if (heightArray != null && heightArray.length > index * 2 + 1) {
pt.ele = heightArray[index * 2 + 1];
}
pt.lat = l.getLatitude();
pt.lon = l.getLongitude();
points.add(pt);
}
private int findPointIndex(WptPt point, List<WptPt> points, int firstIndex) {
double minDistance = Double.MAX_VALUE;
int index = 0;
for (int i = Math.max(0, firstIndex); i < points.size(); i++) {
double distance = MapUtils.getDistance(point.lat, point.lon, points.get(i).lat, points.get(i).lon);
if (distance < minDistance) {
minDistance = distance;
index = i;
}
}
return index;
}
private void updateSegmentsForSnap(boolean both) { private void updateSegmentsForSnap(boolean both) {
recreateSegments(beforeSegments = new ArrayList<>(), recreateSegments(beforeSegments = new ArrayList<>(),
beforeSegmentsForSnap = new ArrayList<>(), before.points, true); beforeSegmentsForSnap = new ArrayList<>(), before.points, true);
@ -966,7 +900,6 @@ public class MeasurementEditingContext {
} }
} }
void cancelSnapToRoad() { void cancelSnapToRoad() {
progressListener.hideProgressBar(); progressListener.hideProgressBar();
if (calculationProgress != null) { if (calculationProgress != null) {
@ -1108,8 +1041,10 @@ public class MeasurementEditingContext {
for (int i = startPointIndex; i < endPointIndex; i++) { for (int i = startPointIndex; i < endPointIndex; i++) {
Pair<WptPt, WptPt> pair = new Pair<>(before.points.get(i), before.points.get(i + 1)); Pair<WptPt, WptPt> pair = new Pair<>(before.points.get(i), before.points.get(i + 1));
RoadSegmentData data = this.roadSegmentData.get(pair); RoadSegmentData data = this.roadSegmentData.get(pair);
if (data != null && data.points != null && data.segments != null) { List<WptPt> dataPoints = data != null ? data.getPoints() : null;
for (WptPt pt : data.points) { List<RouteSegmentResult> dataSegments = data != null ? data.getSegments() : null;
if (dataPoints != null && dataSegments != null) {
for (WptPt pt : dataPoints) {
Location l = new Location(""); Location l = new Location("");
l.setLatitude(pt.getLatitude()); l.setLatitude(pt.getLatitude());
l.setLongitude(pt.getLongitude()); l.setLongitude(pt.getLongitude());
@ -1119,7 +1054,7 @@ public class MeasurementEditingContext {
locations.add(l); locations.add(l);
} }
pair.second.setTrkPtIndex(i + 1 < before.points.size() - 1 ? locations.size() : locations.size() - 1); pair.second.setTrkPtIndex(i + 1 < before.points.size() - 1 ? locations.size() : locations.size() - 1);
route.addAll(data.segments); route.addAll(dataSegments);
} }
} }
if (!locations.isEmpty() && !route.isEmpty()) { if (!locations.isEmpty() && !route.isEmpty()) {
@ -1156,14 +1091,8 @@ public class MeasurementEditingContext {
return res; return res;
} }
interface SnapToRoadProgressListener { @Override
public void onRouteSettingsChanged(@Nullable ApplicationMode mode) {
void showProgressBar(); recalculateRouteSegments(mode);
void updateProgress(int progress);
void hideProgressBar();
void refresh();
} }
} }

View file

@ -0,0 +1,67 @@
package net.osmand.plus.measurementtool;
import net.osmand.GPXUtilities;
import net.osmand.data.LatLon;
import net.osmand.router.RoutePlannerFrontEnd;
import net.osmand.router.RouteSegmentResult;
import net.osmand.util.MapUtils;
import java.util.List;
public class MeasurementEditingContextUtils {
static boolean isLastGpxPoint(List<RoutePlannerFrontEnd.GpxPoint> gpxPoints, int index) {
if (index == gpxPoints.size() - 1) {
return true;
} else {
for (int i = index + 1; i < gpxPoints.size(); i++) {
RoutePlannerFrontEnd.GpxPoint gp = gpxPoints.get(i);
for (int k = 0; k < gp.routeToTarget.size(); k++) {
RouteSegmentResult seg = gp.routeToTarget.get(k);
if (seg.getStartPointIndex() != seg.getEndPointIndex()) {
return false;
}
}
}
}
return true;
}
static int findPointIndex(GPXUtilities.WptPt point, List<GPXUtilities.WptPt> points, int firstIndex) {
double minDistance = Double.MAX_VALUE;
int index = 0;
for (int i = Math.max(0, firstIndex); i < points.size(); i++) {
double distance = MapUtils.getDistance(point.lat, point.lon, points.get(i).lat, points.get(i).lon);
if (distance < minDistance) {
minDistance = distance;
index = i;
}
}
return index;
}
static void addPointToArray(List<GPXUtilities.WptPt> points, RouteSegmentResult seg, int index, float[] heightArray) {
LatLon l = seg.getPoint(index);
GPXUtilities.WptPt pt = new GPXUtilities.WptPt();
if (heightArray != null && heightArray.length > index * 2 + 1) {
pt.ele = heightArray[index * 2 + 1];
}
pt.lat = l.getLatitude();
pt.lon = l.getLongitude();
points.add(pt);
}
static void fillPointsArray(List<GPXUtilities.WptPt> points, RouteSegmentResult seg, boolean includeEndPoint) {
int ind = seg.getStartPointIndex();
boolean plus = seg.isForwardDirection();
float[] heightArray = seg.getObject().calculateHeightArray();
while (ind != seg.getEndPointIndex()) {
addPointToArray(points, seg, ind, heightArray);
ind = plus ? ind + 1 : ind - 1;
}
if (includeEndPoint) {
addPointToArray(points, seg, ind, heightArray);
}
}
}

View file

@ -72,7 +72,6 @@ import net.osmand.plus.measurementtool.command.ReorderPointCommand;
import net.osmand.plus.measurementtool.command.ReversePointsCommand; import net.osmand.plus.measurementtool.command.ReversePointsCommand;
import net.osmand.plus.measurementtool.command.SplitPointsCommand; import net.osmand.plus.measurementtool.command.SplitPointsCommand;
import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet; import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet;
import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet.OnAppModeConfiguredCallback;
import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet.DialogMode; import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet.DialogMode;
import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.BaseCard;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
@ -98,7 +97,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.IndexConstants.GPX_INDEX_DIR; import static net.osmand.IndexConstants.GPX_INDEX_DIR;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode; import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.SnapToRoadProgressListener;
import static net.osmand.plus.measurementtool.SaveAsNewTrackBottomSheetDialogFragment.SaveAsNewTrackFragmentListener; import static net.osmand.plus.measurementtool.SaveAsNewTrackBottomSheetDialogFragment.SaveAsNewTrackFragmentListener;
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.SelectFileListener; import static net.osmand.plus.measurementtool.SelectFileBottomSheet.SelectFileListener;
@ -109,8 +107,7 @@ import static net.osmand.plus.measurementtool.command.ClearPointsCommand.ClearCo
public class MeasurementToolFragment extends BaseOsmAndFragment implements RouteBetweenPointsFragmentListener, public class MeasurementToolFragment extends BaseOsmAndFragment implements RouteBetweenPointsFragmentListener,
OptionsFragmentListener, GpxApproximationFragmentListener, SelectedPointFragmentListener, OptionsFragmentListener, GpxApproximationFragmentListener, SelectedPointFragmentListener,
SaveAsNewTrackFragmentListener, MapControlsThemeInfoProvider, SaveAsNewTrackFragmentListener, MapControlsThemeInfoProvider {
OnAppModeConfiguredCallback {
public static final String TAG = MeasurementToolFragment.class.getSimpleName(); public static final String TAG = MeasurementToolFragment.class.getSimpleName();
public static final String TAPS_DISABLED_KEY = "taps_disabled_key"; public static final String TAPS_DISABLED_KEY = "taps_disabled_key";
@ -241,7 +238,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
final MeasurementToolLayer measurementLayer = mapActivity.getMapLayers().getMeasurementToolLayer(); final MeasurementToolLayer measurementLayer = mapActivity.getMapLayers().getMeasurementToolLayer();
final OsmandApplication app = mapActivity.getMyApplication(); final OsmandApplication app = mapActivity.getMyApplication();
editingCtx.setApplication(mapActivity.getMyApplication()); app.setMeasurementEditingContext(editingCtx);
editingCtx.setApplication(app);
editingCtx.setProgressListener(new SnapToRoadProgressListener() { editingCtx.setProgressListener(new SnapToRoadProgressListener() {
@Override @Override
public void showProgressBar() { public void showProgressBar() {
@ -267,6 +265,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
updateDistancePointsText(); updateDistancePointsText();
} }
}); });
editingCtx.setupRouteSettingsListener();
measurementLayer.setEditingCtx(editingCtx); measurementLayer.setEditingCtx(editingCtx);
@ -1102,12 +1101,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
updateDistancePointsText(); updateDistancePointsText();
} }
@Override
public void onAppModeConfigured() {
editingCtx.recalculateRouteSegmentsForAppMode();
updateDistancePointsText();
}
@Override @Override
public void onChangeRouteTypeBefore() { public void onChangeRouteTypeBefore() {
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
@ -1910,6 +1903,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private void dismiss(@NonNull MapActivity mapActivity, boolean clearContext) { private void dismiss(@NonNull MapActivity mapActivity, boolean clearContext) {
try { try {
OsmandApplication app = mapActivity.getMyApplication();
if (clearContext) { if (clearContext) {
editingCtx.clearSegments(); editingCtx.clearSegments();
} }
@ -1920,13 +1914,15 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
GpxData gpxData = editingCtx.getGpxData(); GpxData gpxData = editingCtx.getGpxData();
GPXFile gpx = gpxData != null ? gpxData.getGpxFile() : null; GPXFile gpx = gpxData != null ? gpxData.getGpxFile() : null;
if (gpx != null) { if (gpx != null) {
Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization().getTrackActivity()); Intent newIntent = new Intent(mapActivity, app.getAppCustomization().getTrackActivity());
newIntent.putExtra(TrackActivity.TRACK_FILE_NAME, gpx.path); newIntent.putExtra(TrackActivity.TRACK_FILE_NAME, gpx.path);
newIntent.putExtra(TrackActivity.OPEN_TRACKS_LIST, true); newIntent.putExtra(TrackActivity.OPEN_TRACKS_LIST, true);
newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(newIntent); startActivity(newIntent);
} }
} }
editingCtx.resetRouteSettingsListener();
app.setMeasurementEditingContext(null);
mapActivity.getSupportFragmentManager().beginTransaction().remove(this).commitAllowingStateLoss(); mapActivity.getSupportFragmentManager().beginTransaction().remove(this).commitAllowingStateLoss();
} catch (Exception e) { } catch (Exception e) {
// ignore // ignore

View file

@ -0,0 +1,68 @@
package net.osmand.plus.measurementtool;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.router.RouteSegmentResult;
import net.osmand.util.MapUtils;
import java.util.Collections;
import java.util.List;
public class RoadSegmentData {
private final ApplicationMode appMode;
private final WptPt start;
private final WptPt end;
private final List<WptPt> points;
private final List<RouteSegmentResult> segments;
private final double distance;
public RoadSegmentData(@NonNull ApplicationMode appMode, @NonNull WptPt start, @NonNull WptPt end,
@Nullable List<WptPt> points, @Nullable List<RouteSegmentResult> segments) {
this.appMode = appMode;
this.start = start;
this.end = end;
this.points = points;
this.segments = segments;
double distance = 0;
if (points != null && points.size() > 1) {
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);
}
} else if (segments != null) {
for (RouteSegmentResult segment : segments) {
distance += segment.getDistance();
}
}
this.distance = distance;
}
public ApplicationMode getAppMode() {
return appMode;
}
public WptPt getStart() {
return start;
}
public WptPt getEnd() {
return end;
}
@Nullable
public List<WptPt> getPoints() {
return points != null ? Collections.unmodifiableList(points) : null;
}
@Nullable
public List<RouteSegmentResult> getSegments() {
return segments != null ? Collections.unmodifiableList(segments) : null;
}
public double getDistance() {
return distance;
}
}

View file

@ -0,0 +1,12 @@
package net.osmand.plus.measurementtool;
interface SnapToRoadProgressListener {
void showProgressBar();
void updateProgress(int progress);
void hideProgressBar();
void refresh();
}

View file

@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementEditingContext; import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementEditingContext.RoadSegmentData; import net.osmand.plus.measurementtool.RoadSegmentData;
import net.osmand.plus.measurementtool.MeasurementToolLayer; import net.osmand.plus.measurementtool.MeasurementToolLayer;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation; import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation;

View file

@ -4,7 +4,7 @@ import android.util.Pair;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementEditingContext; import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementEditingContext.RoadSegmentData; import net.osmand.plus.measurementtool.RoadSegmentData;
import net.osmand.plus.measurementtool.MeasurementToolLayer; import net.osmand.plus.measurementtool.MeasurementToolLayer;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;

View file

@ -4,7 +4,7 @@ import android.util.Pair;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementEditingContext; import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementEditingContext.RoadSegmentData; import net.osmand.plus.measurementtool.RoadSegmentData;
import net.osmand.plus.measurementtool.MeasurementToolLayer; import net.osmand.plus.measurementtool.MeasurementToolLayer;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -4,7 +4,7 @@ import android.util.Pair;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementEditingContext; import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementEditingContext.RoadSegmentData; import net.osmand.plus.measurementtool.RoadSegmentData;
import net.osmand.plus.measurementtool.MeasurementToolLayer; import net.osmand.plus.measurementtool.MeasurementToolLayer;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -4,12 +4,11 @@ import android.util.Pair;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementEditingContext; import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementEditingContext.RoadSegmentData; import net.osmand.plus.measurementtool.RoadSegmentData;
import net.osmand.plus.measurementtool.MeasurementToolLayer; import net.osmand.plus.measurementtool.MeasurementToolLayer;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;

View file

@ -2,11 +2,9 @@ package net.osmand.plus.measurementtool.command;
import android.util.Pair; import android.util.Pair;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.TrkSegment;
import net.osmand.GPXUtilities.WptPt; import net.osmand.GPXUtilities.WptPt;
import net.osmand.plus.measurementtool.MeasurementEditingContext; import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementEditingContext.RoadSegmentData; import net.osmand.plus.measurementtool.RoadSegmentData;
import net.osmand.plus.measurementtool.MeasurementToolLayer; import net.osmand.plus.measurementtool.MeasurementToolLayer;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -20,6 +20,7 @@ import androidx.fragment.app.Fragment;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
@ -32,6 +33,7 @@ import net.osmand.plus.base.bottomsheetmenu.simpleitems.SubtitleDividerItem;
import net.osmand.plus.dashboard.DashboardOnMap; import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.helpers.AvoidSpecificRoads; import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter;
import net.osmand.router.RouteSegmentResult;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
@ -52,6 +54,7 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr
private static final String AVOID_ROADS_TYPES_KEY = "avoid_roads_types"; private static final String AVOID_ROADS_TYPES_KEY = "avoid_roads_types";
private static final String HIDE_IMPASSABLE_ROADS_KEY = "hide_impassable_roads"; private static final String HIDE_IMPASSABLE_ROADS_KEY = "hide_impassable_roads";
private static final String AVOID_ROADS_OBJECTS_KEY = "avoid_roads_objects"; private static final String AVOID_ROADS_OBJECTS_KEY = "avoid_roads_objects";
private static final String AVOID_ROADS_APP_MODE_KEY = "avoid_roads_app_mode";
private RoutingOptionsHelper routingOptionsHelper; private RoutingOptionsHelper routingOptionsHelper;
@ -63,11 +66,16 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr
private boolean hideImpassableRoads; private boolean hideImpassableRoads;
@ColorRes @ColorRes
private int compoundButtonColorId = INVALID_ID; private int compoundButtonColorId = INVALID_ID;
private ApplicationMode appMode;
public void setHideImpassableRoads(boolean hideImpassableRoads) { public void setHideImpassableRoads(boolean hideImpassableRoads) {
this.hideImpassableRoads = hideImpassableRoads; this.hideImpassableRoads = hideImpassableRoads;
} }
public void setApplicationMode(ApplicationMode appMode) {
this.appMode = appMode;
}
@Override @Override
public void createMenuItems(Bundle savedInstanceState) { public void createMenuItems(Bundle savedInstanceState) {
final OsmandApplication app = getMyApplication(); final OsmandApplication app = getMyApplication();
@ -83,6 +91,9 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr
if (savedInstanceState.containsKey(AVOID_ROADS_OBJECTS_KEY)) { if (savedInstanceState.containsKey(AVOID_ROADS_OBJECTS_KEY)) {
removedImpassableRoads = (List<LatLon>) savedInstanceState.getSerializable(AVOID_ROADS_OBJECTS_KEY); removedImpassableRoads = (List<LatLon>) savedInstanceState.getSerializable(AVOID_ROADS_OBJECTS_KEY);
} }
if (savedInstanceState.containsKey(AVOID_ROADS_APP_MODE_KEY)) {
appMode = ApplicationMode.valueOfStringKey(savedInstanceState.getString(AVOID_ROADS_APP_MODE_KEY), null);
}
} }
if (routingParametersMap == null) { if (routingParametersMap == null) {
routingParametersMap = getRoutingParametersMap(app); routingParametersMap = getRoutingParametersMap(app);
@ -154,7 +165,7 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr
if (mapActivity != null) { if (mapActivity != null) {
mapActivity.getDashboard().setDashboardVisibility(false, DashboardOnMap.DashboardType.ROUTE_PREFERENCES); mapActivity.getDashboard().setDashboardVisibility(false, DashboardOnMap.DashboardType.ROUTE_PREFERENCES);
mapActivity.getMapRouteInfoMenu().hide(); mapActivity.getMapRouteInfoMenu().hide();
app.getAvoidSpecificRoads().selectFromMap(mapActivity); app.getAvoidSpecificRoads().selectFromMap(mapActivity, appMode);
Fragment fragment = getTargetFragment(); Fragment fragment = getTargetFragment();
if (fragment != null) { if (fragment != null) {
fragment.onActivityResult(getTargetRequestCode(), OPEN_AVOID_ROADS_DIALOG_REQUEST_CODE, null); fragment.onActivityResult(getTargetRequestCode(), OPEN_AVOID_ROADS_DIALOG_REQUEST_CODE, null);
@ -262,6 +273,9 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr
outState.putSerializable(AVOID_ROADS_TYPES_KEY, routingParametersMap); outState.putSerializable(AVOID_ROADS_TYPES_KEY, routingParametersMap);
outState.putSerializable(AVOID_ROADS_OBJECTS_KEY, (Serializable) removedImpassableRoads); outState.putSerializable(AVOID_ROADS_OBJECTS_KEY, (Serializable) removedImpassableRoads);
outState.putBoolean(HIDE_IMPASSABLE_ROADS_KEY, hideImpassableRoads); outState.putBoolean(HIDE_IMPASSABLE_ROADS_KEY, hideImpassableRoads);
if (appMode != null) {
outState.putString(AVOID_ROADS_APP_MODE_KEY, appMode.getStringKey());
}
} }
@Override @Override

View file

@ -1,7 +1,6 @@
package net.osmand.plus.routepreparationmenu; package net.osmand.plus.routepreparationmenu;
import android.app.Activity; import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
@ -13,7 +12,6 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.ColorRes; import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.SwitchCompat; import androidx.appcompat.widget.SwitchCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@ -400,7 +398,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
boolean enabled = !settings.ENABLE_TIME_CONDITIONAL_ROUTING.getModeValue(applicationMode); boolean enabled = !settings.ENABLE_TIME_CONDITIONAL_ROUTING.getModeValue(applicationMode);
settings.ENABLE_TIME_CONDITIONAL_ROUTING.setModeValue(applicationMode, enabled); settings.ENABLE_TIME_CONDITIONAL_ROUTING.setModeValue(applicationMode, enabled);
timeConditionalRoutingItem[0].setChecked(enabled); timeConditionalRoutingItem[0].setChecked(enabled);
app.getRoutingHelper().onSettingsChanged(true); app.getRoutingHelper().onSettingsChanged(applicationMode, true);
} }
}) })
.create(); .create();
@ -473,6 +471,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
AvoidRoadsBottomSheetDialogFragment avoidRoadsFragment = new AvoidRoadsBottomSheetDialogFragment(); AvoidRoadsBottomSheetDialogFragment avoidRoadsFragment = new AvoidRoadsBottomSheetDialogFragment();
avoidRoadsFragment.setTargetFragment(RouteOptionsBottomSheet.this, AvoidRoadsBottomSheetDialogFragment.REQUEST_CODE); avoidRoadsFragment.setTargetFragment(RouteOptionsBottomSheet.this, AvoidRoadsBottomSheetDialogFragment.REQUEST_CODE);
avoidRoadsFragment.setCompoundButtonColorId(selectedModeColorId); avoidRoadsFragment.setCompoundButtonColorId(selectedModeColorId);
avoidRoadsFragment.setApplicationMode(applicationMode);
avoidRoadsFragment.show(mapActivity.getSupportFragmentManager(), AvoidRoadsBottomSheetDialogFragment.TAG); avoidRoadsFragment.show(mapActivity.getSupportFragmentManager(), AvoidRoadsBottomSheetDialogFragment.TAG);
updateMenu(); updateMenu();
} }
@ -656,19 +655,6 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
} }
@Override
public void onDismiss(@NonNull DialogInterface dialog) {
super.onDismiss(dialog);
notifyAppModeConfigurationChanged();
}
private void notifyAppModeConfigurationChanged() {
Fragment fragment = getTargetFragment();
if (fragment instanceof OnAppModeConfiguredCallback) {
((OnAppModeConfiguredCallback) fragment).onAppModeConfigured();
}
}
private List<LocalRoutingParameter> getRoutingParameters(ApplicationMode applicationMode) { private List<LocalRoutingParameter> getRoutingParameters(ApplicationMode applicationMode) {
List<String> routingParameters; List<String> routingParameters;
@ -742,10 +728,6 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
} }
} }
public interface OnAppModeConfiguredCallback {
void onAppModeConfigured();
}
public enum AppModeOptions { public enum AppModeOptions {
CAR(MuteSoundRoutingParameter.KEY, CAR(MuteSoundRoutingParameter.KEY,

View file

@ -113,7 +113,7 @@ public class RoutingOptionsHelper {
public void selectRestrictedRoads(final MapActivity mapActivity) { public void selectRestrictedRoads(final MapActivity mapActivity) {
mapActivity.getDashboard().setDashboardVisibility(false, DashboardOnMap.DashboardType.ROUTE_PREFERENCES); mapActivity.getDashboard().setDashboardVisibility(false, DashboardOnMap.DashboardType.ROUTE_PREFERENCES);
mapActivity.getMapRouteInfoMenu().hide(); mapActivity.getMapRouteInfoMenu().hide();
mapActivity.getMyApplication().getAvoidSpecificRoads().showDialog(mapActivity); mapActivity.getMyApplication().getAvoidSpecificRoads().showDialog(mapActivity, null);
} }
public void selectVoiceGuidance(final MapActivity mapActivity, final CallbackWithObject<String> callback, ApplicationMode applicationMode) { public void selectVoiceGuidance(final MapActivity mapActivity, final CallbackWithObject<String> callback, ApplicationMode applicationMode) {
@ -230,7 +230,7 @@ public class RoutingOptionsHelper {
if (rp instanceof OtherLocalRoutingParameter) { if (rp instanceof OtherLocalRoutingParameter) {
updateGpxRoutingParameter((OtherLocalRoutingParameter) rp); updateGpxRoutingParameter((OtherLocalRoutingParameter) rp);
} }
routingHelper.onSettingsChanged(true); routingHelper.onSettingsChanged(rp.getApplicationMode(), true);
} }
public void updateGpxRoutingParameter(OtherLocalRoutingParameter gpxParam) { public void updateGpxRoutingParameter(OtherLocalRoutingParameter gpxParam) {

View file

@ -0,0 +1,12 @@
package net.osmand.plus.routing;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.plus.settings.backend.ApplicationMode;
public interface IRouteSettingsListener {
void onRouteSettingsChanged(@Nullable ApplicationMode mode);
}

View file

@ -1,6 +1,7 @@
package net.osmand.plus.routing; package net.osmand.plus.routing;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXFile;
import net.osmand.Location; import net.osmand.Location;
@ -28,6 +29,7 @@ import net.osmand.router.RouteExporter;
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;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import java.io.IOException; import java.io.IOException;
@ -50,6 +52,8 @@ public class RoutingHelper {
private List<WeakReference<IRouteInformationListener>> listeners = new LinkedList<>(); private List<WeakReference<IRouteInformationListener>> listeners = new LinkedList<>();
private List<WeakReference<IRoutingDataUpdateListener>> updateListeners = new LinkedList<>(); private List<WeakReference<IRoutingDataUpdateListener>> updateListeners = new LinkedList<>();
private List<WeakReference<IRouteSettingsListener>> settingsListeners = new LinkedList<>();
private final OsmandApplication app; private final OsmandApplication app;
private OsmandSettings settings; private OsmandSettings settings;
private final RouteProvider provider; private final RouteProvider provider;
@ -328,59 +332,47 @@ public class RoutingHelper {
return lastFixedLocation; return lastFixedLocation;
} }
public void addRouteDataListener(IRoutingDataUpdateListener listener) { public void addRouteDataListener(@NonNull IRoutingDataUpdateListener listener) {
updateListeners = updateListenersList(new ArrayList<>(updateListeners), listener, true); updateListeners = updateListeners(new ArrayList<>(updateListeners), listener, true);
} }
public void removeRouteDataListener(IRoutingDataUpdateListener listener) { public void removeRouteDataListener(@NonNull IRoutingDataUpdateListener listener) {
updateListeners = updateListenersList(new ArrayList<>(updateListeners), listener, false); updateListeners = updateListeners(new ArrayList<>(updateListeners), listener, false);
} }
private List<WeakReference<IRoutingDataUpdateListener>> updateListenersList( public void addRouteSettingsListener(@NonNull IRouteSettingsListener listener) {
List<WeakReference<IRoutingDataUpdateListener>> copyList, settingsListeners = updateListeners(new ArrayList<>(settingsListeners), listener, true);
IRoutingDataUpdateListener listener, boolean isNewListener) {
Iterator<WeakReference<IRoutingDataUpdateListener>> it = copyList.iterator();
while (it.hasNext()) {
WeakReference<IRoutingDataUpdateListener> ref = it.next();
IRoutingDataUpdateListener l = ref.get();
if (l == null || l == listener) {
it.remove();
}
}
if (isNewListener) {
copyList.add(new WeakReference<>(listener));
}
return copyList;
} }
public void addListener(IRouteInformationListener l) { public void removeRouteSettingsListener(@NonNull IRouteSettingsListener listener) {
listeners = updateInformationListeners(new ArrayList<>(listeners), l, true); settingsListeners = updateListeners(new ArrayList<>(settingsListeners), listener, false);
}
public void addListener(@NonNull IRouteInformationListener l) {
listeners = updateListeners(new ArrayList<>(listeners), l, true);
transportRoutingHelper.addListener(l); transportRoutingHelper.addListener(l);
} }
public void removeListener(IRouteInformationListener lt) { public void removeListener(@NonNull IRouteInformationListener lt) {
listeners = updateInformationListeners(new ArrayList<>(listeners), lt, false); listeners = updateListeners(new ArrayList<>(listeners), lt, false);
} }
private List<WeakReference<IRouteInformationListener>> updateInformationListeners( private <T> List<WeakReference<T>> updateListeners(List<WeakReference<T>> copyList,
List<WeakReference<IRouteInformationListener>> copyList, T listener, boolean isNewListener) {
IRouteInformationListener listener, boolean isNewListener) { Iterator<WeakReference<T>> it = copyList.iterator();
Iterator<WeakReference<IRouteInformationListener>> it = copyList.iterator();
while (it.hasNext()) { while (it.hasNext()) {
WeakReference<IRouteInformationListener> ref = it.next(); WeakReference<T> ref = it.next();
IRouteInformationListener l = ref.get(); T l = ref.get();
if (l == null || l == listener) { if (l == null || l == listener) {
it.remove(); it.remove();
} }
} }
if (isNewListener) { if (isNewListener) {
copyList.add(new WeakReference<>(listener)); copyList.add(new WeakReference<>(listener));
} }
return copyList; return copyList;
} }
public void updateLocation(Location currentLocation) { public void updateLocation(Location currentLocation) {
if (settings.getPointToStart() == null && settings.getMyLocationToStart() == null && currentLocation != null) { if (settings.getPointToStart() == null && settings.getMyLocationToStart() == null && currentLocation != null) {
app.getTargetPointsHelper().setMyLocationPoint( app.getTargetPointsHelper().setMyLocationPoint(
@ -571,15 +563,7 @@ public class RoutingHelper {
route.updateCurrentRoute(newCurrentRoute + 1); route.updateCurrentRoute(newCurrentRoute + 1);
currentRoute = newCurrentRoute + 1; currentRoute = newCurrentRoute + 1;
app.getNotificationHelper().refreshNotification(NotificationType.NAVIGATION); app.getNotificationHelper().refreshNotification(NotificationType.NAVIGATION);
if (!updateListeners.isEmpty()) { fireRoutingDataUpdateEvent();
ArrayList<WeakReference<IRoutingDataUpdateListener>> tmp = new ArrayList<>(updateListeners);
for (WeakReference<IRoutingDataUpdateListener> ref : tmp) {
IRoutingDataUpdateListener l = ref.get();
if (l != null) {
l.onRoutingDataUpdate();
}
}
}
} else { } else {
break; break;
} }
@ -688,6 +672,30 @@ public class RoutingHelper {
return false; return false;
} }
private void fireRoutingDataUpdateEvent() {
if (!updateListeners.isEmpty()) {
ArrayList<WeakReference<IRoutingDataUpdateListener>> tmp = new ArrayList<>(updateListeners);
for (WeakReference<IRoutingDataUpdateListener> ref : tmp) {
IRoutingDataUpdateListener l = ref.get();
if (l != null) {
l.onRoutingDataUpdate();
}
}
}
}
private void fireRouteSettingsChangedEvent(@Nullable ApplicationMode mode) {
if (!settingsListeners.isEmpty()) {
ArrayList<WeakReference<IRouteSettingsListener>> tmp = new ArrayList<>(settingsListeners);
for (WeakReference<IRouteSettingsListener> ref : tmp) {
IRouteSettingsListener l = ref.get();
if (l != null) {
l.onRouteSettingsChanged(mode);
}
}
}
}
public int getLeftDistance() { public int getLeftDistance() {
return route.getDistanceToFinish(lastFixedLocation); return route.getDistanceToFinish(lastFixedLocation);
} }
@ -766,9 +774,19 @@ public class RoutingHelper {
} }
public void onSettingsChanged(boolean forceRouteRecalculation) { public void onSettingsChanged(boolean forceRouteRecalculation) {
if (forceRouteRecalculation || isRouteCalculated() || isRouteBeingCalculated()) { onSettingsChanged(mode, forceRouteRecalculation);
}
public void onSettingsChanged(@Nullable ApplicationMode mode) {
onSettingsChanged(mode, false);
}
public void onSettingsChanged(@Nullable ApplicationMode mode, boolean forceRouteRecalculation) {
if (forceRouteRecalculation ||
((mode == null || mode.equals(this.mode)) && (isRouteCalculated() || isRouteBeingCalculated()))) {
recalculateRouteDueToSettingsChange(); recalculateRouteDueToSettingsChange();
} }
fireRouteSettingsChangedEvent(mode);
} }
private void recalculateRouteDueToSettingsChange() { private void recalculateRouteDueToSettingsChange() {

View file

@ -432,10 +432,7 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
mode.setStrAngle(angleValue[0]); mode.setStrAngle(angleValue[0]);
updateAllSettings(); updateAllSettings();
RoutingHelper routingHelper = app.getRoutingHelper(); app.getRoutingHelper().onSettingsChanged(mode);
if (mode.equals(routingHelper.getAppMode())) {
routingHelper.onSettingsChanged();
}
} }
}); });
builder.setNegativeButton(R.string.shared_string_cancel, null); builder.setNegativeButton(R.string.shared_string_cancel, null);
@ -643,11 +640,8 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP
return multiSelectPref; return multiSelectPref;
} }
private static void recalculateRoute(OsmandApplication app, ApplicationMode mode) { private static void recalculateRoute(@NonNull OsmandApplication app, ApplicationMode mode) {
RoutingHelper routingHelper = app.getRoutingHelper(); app.getRoutingHelper().onSettingsChanged(mode);
if (mode.equals(routingHelper.getAppMode())) {
routingHelper.onSettingsChanged();
}
} }
private void clearParameters() { private void clearParameters() {

View file

@ -193,10 +193,7 @@ public class VehicleParametersFragment extends BaseSettingsFragment implements O
} }
private void recalculateRoute() { private void recalculateRoute() {
RoutingHelper routingHelper = app.getRoutingHelper(); app.getRoutingHelper().onSettingsChanged(getSelectedAppMode());
if (getSelectedAppMode().equals(routingHelper.getAppMode())) {
routingHelper.onSettingsChanged();
}
} }
private void showSeekbarSettingsDialog(@NonNull Activity activity, final boolean defaultSpeedOnly) { private void showSeekbarSettingsDialog(@NonNull Activity activity, final boolean defaultSpeedOnly) {
@ -267,10 +264,7 @@ public class VehicleParametersFragment extends BaseSettingsFragment implements O
mode.setMinSpeed(minValue[0] / ratio[0]); mode.setMinSpeed(minValue[0] / ratio[0]);
mode.setMaxSpeed(maxValue[0] / ratio[0]); mode.setMaxSpeed(maxValue[0] / ratio[0]);
} }
RoutingHelper routingHelper = app.getRoutingHelper(); app.getRoutingHelper().onSettingsChanged(mode);
if (mode.equals(routingHelper.getAppMode())) {
routingHelper.onSettingsChanged();
}
} }
}); });
builder.setNegativeButton(R.string.shared_string_cancel, null); builder.setNegativeButton(R.string.shared_string_cancel, null);
@ -282,10 +276,7 @@ public class VehicleParametersFragment extends BaseSettingsFragment implements O
mode.setMinSpeed(0f); mode.setMinSpeed(0f);
mode.setMaxSpeed(0f); mode.setMaxSpeed(0f);
} }
RoutingHelper routingHelper = app.getRoutingHelper(); app.getRoutingHelper().onSettingsChanged(mode);
if (mode.equals(routingHelper.getAppMode())) {
routingHelper.onSettingsChanged();
}
} }
}); });