Add ability to choose gpx segment for routing

This commit is contained in:
Vitaliy 2021-02-14 16:51:24 +02:00
parent ea4ddfbc2d
commit b04115aad2
8 changed files with 138 additions and 113 deletions

View file

@ -45,7 +45,6 @@
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_regular" /> osmand:typeface="@string/font_roboto_regular" />
</LinearLayout> </LinearLayout>
<include <include
@ -55,7 +54,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dashPluginMargin" /> android:layout_marginBottom="@dimen/dashPluginMargin" />
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"

View file

@ -515,10 +515,6 @@ public class MapActivityActions implements DialogProvider {
} }
public void setGPXRouteParams(GPXFile result) { public void setGPXRouteParams(GPXFile result) {
setGPXRouteParams(result, -1);
}
public void setGPXRouteParams(GPXFile result, int selectedSegment) {
if (result == null) { if (result == null) {
mapActivity.getRoutingHelper().setGpxParams(null); mapActivity.getRoutingHelper().setGpxParams(null);
settings.FOLLOW_THE_GPX_ROUTE.set(null); settings.FOLLOW_THE_GPX_ROUTE.set(null);
@ -526,7 +522,7 @@ public class MapActivityActions implements DialogProvider {
GPXRouteParamsBuilder params = new GPXRouteParamsBuilder(result, settings); GPXRouteParamsBuilder params = new GPXRouteParamsBuilder(result, settings);
params.setCalculateOsmAndRouteParts(settings.GPX_ROUTE_CALC_OSMAND_PARTS.get()); params.setCalculateOsmAndRouteParts(settings.GPX_ROUTE_CALC_OSMAND_PARTS.get());
params.setCalculateOsmAndRoute(settings.GPX_ROUTE_CALC.get()); params.setCalculateOsmAndRoute(settings.GPX_ROUTE_CALC.get());
params.setSelectedSegment(selectedSegment); params.setSelectedSegment(settings.GPX_ROUTE_SEGMENT.get());
List<Location> ps = params.getPoints(settings.getContext()); List<Location> ps = params.getPoints(settings.getContext());
mapActivity.getRoutingHelper().setGpxParams(params); mapActivity.getRoutingHelper().setGpxParams(params);
settings.FOLLOW_THE_GPX_ROUTE.set(result.path); settings.FOLLOW_THE_GPX_ROUTE.set(result.path);

View file

@ -134,6 +134,9 @@ public class FailSafeFuntions {
if(settings.GPX_ROUTE_CALC.get()) { if(settings.GPX_ROUTE_CALC.get()) {
gpxRoute.setCalculateOsmAndRoute(true); gpxRoute.setCalculateOsmAndRoute(true);
} }
if (settings.GPX_ROUTE_SEGMENT.get() != -1) {
gpxRoute.setSelectedSegment(settings.GPX_ROUTE_SEGMENT.get());
}
} else { } else {
gpxRoute = null; gpxRoute = null;
} }

View file

@ -16,16 +16,18 @@ import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.helpers.TrackSelectSegmentAdapter.TrackViewHolder;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import java.util.List; import java.util.List;
public class TrackSelectSegmentAdapter extends RecyclerView.Adapter<TrackSelectSegmentAdapter.TrackViewHolder> { public class TrackSelectSegmentAdapter extends RecyclerView.Adapter<TrackViewHolder> {
private final OsmandApplication app; private final OsmandApplication app;
private final LayoutInflater themedInflater; private final LayoutInflater themedInflater;
private final UiUtilities iconsCache; private final UiUtilities iconsCache;
private final List<TrkSegment> segments; private final List<TrkSegment> segments;
private GpxTrackAdapter.OnItemClickListener onItemClickListener; private OnItemClickListener onItemClickListener;
public TrackSelectSegmentAdapter(Context ctx, List<TrkSegment> segments) { public TrackSelectSegmentAdapter(Context ctx, List<TrkSegment> segments) {
app = (OsmandApplication) ctx.getApplicationContext(); app = (OsmandApplication) ctx.getApplicationContext();
@ -36,17 +38,17 @@ public class TrackSelectSegmentAdapter extends RecyclerView.Adapter<TrackSelectS
@NonNull @NonNull
@Override @Override
public TrackSelectSegmentAdapter.TrackViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public TrackViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = themedInflater.inflate(R.layout.gpx_segment_list_item, parent, false); View view = themedInflater.inflate(R.layout.gpx_segment_list_item, parent, false);
ImageView distanceIcon = view.findViewById(R.id.distance_icon); ImageView distanceIcon = view.findViewById(R.id.distance_icon);
distanceIcon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_split_interval)); distanceIcon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_split_interval));
ImageView timeIcon = view.findViewById(R.id.time_icon); ImageView timeIcon = view.findViewById(R.id.time_icon);
timeIcon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_moving_16)); timeIcon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_moving_16));
return new TrackSelectSegmentAdapter.TrackViewHolder(view); return new TrackViewHolder(view);
} }
@Override @Override
public void onBindViewHolder(@NonNull final TrackSelectSegmentAdapter.TrackViewHolder holder, final int position) { public void onBindViewHolder(@NonNull final TrackViewHolder holder, int position) {
holder.icon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_split_interval)); holder.icon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_split_interval));
TrkSegment segment = segments.get(position); TrkSegment segment = segments.get(position);
@ -72,8 +74,12 @@ public class TrackSelectSegmentAdapter extends RecyclerView.Adapter<TrackSelectS
}); });
} }
@Override
public int getItemCount() {
return segments.size();
}
private long getSegmentTime(TrkSegment segment) { private long getSegmentTime(TrkSegment segment) {
long segmentTime;
long startTime = Long.MAX_VALUE; long startTime = Long.MAX_VALUE;
long endTime = Long.MIN_VALUE; long endTime = Long.MIN_VALUE;
for (int i = 0; i < segment.points.size(); i++) { for (int i = 0; i < segment.points.size(); i++) {
@ -84,9 +90,7 @@ public class TrackSelectSegmentAdapter extends RecyclerView.Adapter<TrackSelectS
endTime = Math.max(endTime, time); endTime = Math.max(endTime, time);
} }
} }
segmentTime = endTime - startTime; return endTime - startTime;
return segmentTime;
} }
private double getDistance(TrkSegment segment) { private double getDistance(TrkSegment segment) {
@ -99,18 +103,17 @@ public class TrackSelectSegmentAdapter extends RecyclerView.Adapter<TrackSelectS
} }
prevPoint = point; prevPoint = point;
} }
return distance; return distance;
} }
@Override public void setAdapterListener(OnItemClickListener onItemClickListener) {
public int getItemCount() { this.onItemClickListener = onItemClickListener;
return segments.size();
} }
public interface OnItemClickListener {
void onItemClick(int position);
public void setAdapterListener(GpxTrackAdapter.OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
} }
static class TrackViewHolder extends RecyclerView.ViewHolder { static class TrackViewHolder extends RecyclerView.ViewHolder {

View file

@ -63,7 +63,8 @@ import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.track.TrackSelectSegmentBottomSheet; import net.osmand.plus.track.TrackSelectSegmentBottomSheet;
import net.osmand.plus.views.layers.MapControlsLayer; import net.osmand.plus.track.TrackSelectSegmentBottomSheet.OnSegmentSelectedListener;
import net.osmand.plus.views.layers.MapControlsLayer.MapControlsThemeInfoProvider;
import net.osmand.plus.widgets.popup.PopUpMenuHelper; import net.osmand.plus.widgets.popup.PopUpMenuHelper;
import net.osmand.plus.widgets.popup.PopUpMenuItem; import net.osmand.plus.widgets.popup.PopUpMenuItem;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -76,7 +77,7 @@ import java.util.List;
public class FollowTrackFragment extends ContextMenuScrollFragment implements CardListener, public class FollowTrackFragment extends ContextMenuScrollFragment implements CardListener,
IRouteInformationListener, MapControlsLayer.MapControlsThemeInfoProvider { IRouteInformationListener, MapControlsThemeInfoProvider, OnSegmentSelectedListener {
public static final String TAG = FollowTrackFragment.class.getName(); public static final String TAG = FollowTrackFragment.class.getName();
@ -207,25 +208,25 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
if (mapActivity != null) { if (mapActivity != null) {
ViewGroup cardsContainer = getCardsContainer(); ViewGroup cardsContainer = getCardsContainer();
cardsContainer.removeAllViews(); cardsContainer.removeAllViews();
if (gpxFile == null || selectingTrack) { if (gpxFile == null || selectingTrack) {
setupTracksCard(); setupTracksCard();
} else { } else {
boolean isTrackContainsMultiSegment = gpxFile.getNonEmptySegmentsCount() > 1;
String fileName = null; String fileName = null;
File file = null; File file = null;
if (!Algorithms.isEmpty(gpxFile.path)) { if (!Algorithms.isEmpty(gpxFile.path)) {
file = new File(gpxFile.path); file = new File(gpxFile.path);
if (isTrackContainsMultiSegment) {
fileName = Algorithms.getFileNameWithoutExtension(file.getName()); fileName = Algorithms.getFileNameWithoutExtension(file.getName());
} else {
fileName = Algorithms.getFileNameWithoutExtension(file.getName());
}
} else if (!Algorithms.isEmpty(gpxFile.tracks)) { } else if (!Algorithms.isEmpty(gpxFile.tracks)) {
fileName = gpxFile.tracks.get(0).name; fileName = gpxFile.tracks.get(0).name;
} }
if (Algorithms.isEmpty(fileName)) { if (Algorithms.isEmpty(fileName)) {
fileName = app.getString(R.string.shared_string_gpx_track); fileName = app.getString(R.string.shared_string_gpx_track);
} }
GPXRouteParamsBuilder routeParams = app.getRoutingHelper().getCurrentGPXRoute();
if (gpxFile.getNonEmptySegmentsCount() > 1 && routeParams != null && routeParams.getSelectedSegment() != -1) {
fileName = fileName + " segment " + (routeParams.getSelectedSegment() + 1);
}
sortButton.setVisibility(View.GONE); sortButton.setVisibility(View.GONE);
GPXInfo gpxInfo = new GPXInfo(fileName, file != null ? file.lastModified() : 0, file != null ? file.length() : 0); GPXInfo gpxInfo = new GPXInfo(fileName, file != null ? file.lastModified() : 0, file != null ? file.length() : 0);
TrackEditCard importTrackCard = new TrackEditCard(mapActivity, gpxInfo); TrackEditCard importTrackCard = new TrackEditCard(mapActivity, gpxInfo);
@ -497,10 +498,10 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
if (selectedGpxFile != null) { if (selectedGpxFile != null) {
GPXFile gpxFile = selectedGpxFile.getGpxFile(); GPXFile gpxFile = selectedGpxFile.getGpxFile();
if (gpxFile.getNonEmptySegmentsCount() > 1) { if (gpxFile.getNonEmptySegmentsCount() > 1) {
TrackSelectSegmentBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), gpxFile); TrackSelectSegmentBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), gpxFile, this);
} else { } else {
updateSelectionMode(false);
selectTrackToFollow(gpxFile); selectTrackToFollow(gpxFile);
updateSelectionMode(false);
} }
} else { } else {
CallbackWithObject<GPXFile[]> callback = new CallbackWithObject<GPXFile[]>() { CallbackWithObject<GPXFile[]> callback = new CallbackWithObject<GPXFile[]>() {
@ -509,10 +510,10 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (mapActivity != null) { if (mapActivity != null) {
if (result[0].getNonEmptySegmentsCount() > 1) { if (result[0].getNonEmptySegmentsCount() > 1) {
TrackSelectSegmentBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), result[0]); TrackSelectSegmentBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), result[0], FollowTrackFragment.this);
} else { } else {
updateSelectionMode(false);
selectTrackToFollow(result[0]); selectTrackToFollow(result[0]);
updateSelectionMode(false);
} }
} }
return true; return true;
@ -536,7 +537,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
app.initVoiceCommandPlayer(mapActivity, mode, true, null, false, false, true); app.initVoiceCommandPlayer(mapActivity, mode, true, null, false, false, true);
} }
} }
mapActivity.getMapActions().setGPXRouteParams(gpxFile, 1); mapActivity.getMapActions().setGPXRouteParams(gpxFile);
app.getTargetPointsHelper().updateRouteAndRefresh(true); app.getTargetPointsHelper().updateRouteAndRefresh(true);
app.getRoutingHelper().onSettingsChanged(true); app.getRoutingHelper().onSettingsChanged(true);
} }
@ -719,7 +720,6 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
} }
} }
@Override @Override
public void routeWasCancelled() { public void routeWasCancelled() {
@ -734,4 +734,18 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
protected String getThemeInfoProviderTag() { protected String getThemeInfoProviderTag() {
return TAG; return TAG;
} }
@Override
public void onSegmentSelect(GPXFile gpxFile, int selectedSegment) {
selectTrackToFollow(gpxFile);
if (selectedSegment != -1) {
GPXRouteParamsBuilder paramsBuilder = app.getRoutingHelper().getCurrentGPXRoute();
if (paramsBuilder != null) {
paramsBuilder.setSelectedSegment(selectedSegment);
app.getSettings().GPX_ROUTE_SEGMENT.set(selectedSegment);
app.getRoutingHelper().onSettingsChanged(true);
}
}
updateSelectionMode(false);
}
} }

View file

@ -8,7 +8,6 @@ import android.util.Base64;
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.Route;
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;
import net.osmand.Location; import net.osmand.Location;
@ -20,15 +19,15 @@ import net.osmand.data.LatLon;
import net.osmand.data.LocationPoint; import net.osmand.data.LocationPoint;
import net.osmand.data.WptLocationPoint; import net.osmand.data.WptLocationPoint;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper;
import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.TargetPointsHelper.TargetPoint;
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse;
import net.osmand.plus.render.NativeOsmandLibrary; import net.osmand.plus.render.NativeOsmandLibrary;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter;
import net.osmand.router.GeneralRouter.RoutingParameter; import net.osmand.router.GeneralRouter.RoutingParameter;
import net.osmand.router.GeneralRouter.RoutingParameterType; import net.osmand.router.GeneralRouter.RoutingParameterType;
@ -161,6 +160,7 @@ public class RouteProvider {
private boolean leftSide; private boolean leftSide;
private boolean passWholeRoute; private boolean passWholeRoute;
private boolean calculateOsmAndRouteParts; private boolean calculateOsmAndRouteParts;
private int selectedSegment = -1;
public GPXRouteParamsBuilder(GPXFile file, OsmandSettings settings) { public GPXRouteParamsBuilder(GPXFile file, OsmandSettings settings) {
leftSide = settings.DRIVING_REGION.get().leftHandDriving; leftSide = settings.DRIVING_REGION.get().leftHandDriving;
@ -191,6 +191,14 @@ public class RouteProvider {
this.calculateOsmAndRoute = calculateOsmAndRoute; this.calculateOsmAndRoute = calculateOsmAndRoute;
} }
public int getSelectedSegment() {
return selectedSegment;
}
public void setSelectedSegment(int selectedSegment) {
this.selectedSegment = selectedSegment;
}
public void setPassWholeRoute(boolean passWholeRoute) { public void setPassWholeRoute(boolean passWholeRoute) {
this.passWholeRoute = passWholeRoute; this.passWholeRoute = passWholeRoute;
} }
@ -278,8 +286,9 @@ public class RouteProvider {
wpt.add(new WptLocationPoint(w)); wpt.add(new WptLocationPoint(w));
} }
} }
int selectedSegment = builder.getSelectedSegment();
if (OSMAND_ROUTER_V2.equals(file.author)) { if (OSMAND_ROUTER_V2.equals(file.author)) {
route = parseOsmAndGPXRoute(points, file); route = parseOsmAndGPXRoute(points, file, selectedSegment);
routePoints = file.getRoutePoints(); routePoints = file.getRoutePoints();
if (reverse) { if (reverse) {
Collections.reverse(points); Collections.reverse(points);
@ -287,7 +296,7 @@ public class RouteProvider {
} }
addMissingTurns = route != null && route.isEmpty(); addMissingTurns = route != null && route.isEmpty();
} else if (file.isCloudmadeRouteFile() || OSMAND_ROUTER.equals(file.author)) { } else if (file.isCloudmadeRouteFile() || OSMAND_ROUTER.equals(file.author)) {
directions = parseOsmAndGPXRoute(points, file, OSMAND_ROUTER.equals(file.author), builder.leftSide, 10); directions = parseOsmAndGPXRoute(points, file, OSMAND_ROUTER.equals(file.author), builder.leftSide, 10, selectedSegment);
if (OSMAND_ROUTER.equals(file.author) && file.hasRtePt()) { if (OSMAND_ROUTER.equals(file.author) && file.hasRtePt()) {
// For files generated by OSMAND_ROUTER use directions contained unaltered // For files generated by OSMAND_ROUTER use directions contained unaltered
addMissingTurns = false; addMissingTurns = false;
@ -301,12 +310,16 @@ public class RouteProvider {
} else { } else {
// first of all check tracks // first of all check tracks
if (!useIntermediatePointsRTE) { if (!useIntermediatePointsRTE) {
for (Track tr : file.tracks) { List<TrkSegment> segments = file.getNonEmptyTrkSegments(false);
if (!tr.generalTrack) { if (selectedSegment != -1 && segments.size() > selectedSegment) {
for (TrkSegment tkSeg : tr.segments) { TrkSegment segment = segments.get(selectedSegment);
for (WptPt pt : tkSeg.points) { for (WptPt p : segment.points) {
points.add(createLocation(pt)); points.add(createLocation(p));
} }
} else {
for (TrkSegment tkSeg : segments) {
for (WptPt p : tkSeg.points) {
points.add(createLocation(p));
} }
} }
} }
@ -998,28 +1011,42 @@ public class RouteProvider {
return new RouteCalculationResult("Empty result"); return new RouteCalculationResult("Empty result");
} }
private static List<RouteSegmentResult> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile) { private static List<RouteSegmentResult> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile, int selectedSegment) {
for (Track tr : gpxFile.tracks) { List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(false);
for (TrkSegment ts : tr.segments) { if (selectedSegment != -1 && segments.size() > selectedSegment) {
for (WptPt p : ts.points) { TrkSegment segment = segments.get(selectedSegment);
for (WptPt p : segment.points) {
points.add(createLocation(p)); points.add(createLocation(p));
} }
RouteImporter routeImporter = new RouteImporter(segment);
return routeImporter.importRoute();
} else {
for (TrkSegment ts : segments) {
for (WptPt p : ts.points) {
points.add(createLocation(p));
} }
} }
RouteImporter routeImporter = new RouteImporter(gpxFile); RouteImporter routeImporter = new RouteImporter(gpxFile);
return routeImporter.importRoute(); return routeImporter.importRoute();
} }
}
private static List<RouteDirectionInfo> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile, boolean osmandRouter, private static List<RouteDirectionInfo> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile, boolean osmandRouter,
boolean leftSide, float defSpeed) { boolean leftSide, float defSpeed, int selectedSegment) {
List<RouteDirectionInfo> directions = null; List<RouteDirectionInfo> directions = null;
if (!osmandRouter) { if (!osmandRouter) {
for (WptPt pt : gpxFile.getPoints()) { for (WptPt pt : gpxFile.getPoints()) {
points.add(createLocation(pt)); points.add(createLocation(pt));
} }
} else { } else {
for (Track tr : gpxFile.tracks) { List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(false);
for (TrkSegment ts : tr.segments) { if (selectedSegment != -1 && segments.size() > selectedSegment) {
TrkSegment segment = segments.get(selectedSegment);
for (WptPt p : segment.points) {
points.add(createLocation(p));
}
} else {
for (TrkSegment ts : segments) {
for (WptPt p : ts.points) { for (WptPt p : ts.points) {
points.add(createLocation(p)); points.add(createLocation(p));
} }
@ -1307,7 +1334,7 @@ public class RouteProvider {
GPXFile gpxFile = GPXUtilities.loadGPXFile(gpxStream); GPXFile gpxFile = GPXUtilities.loadGPXFile(gpxStream);
dir = parseOsmAndGPXRoute(res, gpxFile, true, params.leftSide, params.mode.getDefaultSpeed()); dir = parseOsmAndGPXRoute(res, gpxFile, true, params.leftSide, params.mode.getDefaultSpeed(), -1);
if (dir != null) { if (dir != null) {
addMissingTurns = false; addMissingTurns = false;

View file

@ -45,10 +45,8 @@ import net.osmand.plus.helpers.enums.DrivingRegion;
import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.helpers.enums.MetricsConstants;
import net.osmand.plus.helpers.enums.SpeedConstants; import net.osmand.plus.helpers.enums.SpeedConstants;
import net.osmand.plus.helpers.enums.TracksSortByMode; import net.osmand.plus.helpers.enums.TracksSortByMode;
import net.osmand.plus.mapillary.MapillaryPlugin;
import net.osmand.plus.mapmarkers.CoordinateInputFormats.Format; import net.osmand.plus.mapmarkers.CoordinateInputFormats.Format;
import net.osmand.plus.mapmarkers.MapMarkersMode; import net.osmand.plus.mapmarkers.MapMarkersMode;
import net.osmand.plus.openplacereviews.OpenPlaceReviewsPlugin;
import net.osmand.plus.profiles.LocationIcon; import net.osmand.plus.profiles.LocationIcon;
import net.osmand.plus.profiles.NavigationIcon; import net.osmand.plus.profiles.NavigationIcon;
import net.osmand.plus.profiles.ProfileIconColors; import net.osmand.plus.profiles.ProfileIconColors;
@ -1389,6 +1387,7 @@ public class OsmandSettings {
public final OsmandPreference<Boolean> GPX_ROUTE_CALC_OSMAND_PARTS = new BooleanPreference(this, "gpx_routing_calculate_osmand_route", true).makeGlobal().makeShared().cache(); public final OsmandPreference<Boolean> GPX_ROUTE_CALC_OSMAND_PARTS = new BooleanPreference(this, "gpx_routing_calculate_osmand_route", true).makeGlobal().makeShared().cache();
public final OsmandPreference<Boolean> GPX_CALCULATE_RTEPT = new BooleanPreference(this, "gpx_routing_calculate_rtept", true).makeGlobal().makeShared().cache(); public final OsmandPreference<Boolean> GPX_CALCULATE_RTEPT = new BooleanPreference(this, "gpx_routing_calculate_rtept", true).makeGlobal().makeShared().cache();
public final OsmandPreference<Boolean> GPX_ROUTE_CALC = new BooleanPreference(this, "calc_gpx_route", false).makeGlobal().makeShared().cache(); public final OsmandPreference<Boolean> GPX_ROUTE_CALC = new BooleanPreference(this, "calc_gpx_route", false).makeGlobal().makeShared().cache();
public final OsmandPreference<Integer> GPX_ROUTE_SEGMENT = new IntPreference(this, "gpx_route_segment", -1).makeGlobal().makeShared().cache();
public final OsmandPreference<Boolean> SHOW_START_FINISH_ICONS = new BooleanPreference(this, "show_start_finish_icons", true).makeGlobal().makeShared().cache(); public final OsmandPreference<Boolean> SHOW_START_FINISH_ICONS = new BooleanPreference(this, "show_start_finish_icons", true).makeGlobal().makeShared().cache();
public final OsmandPreference<Boolean> AVOID_TOLL_ROADS = new BooleanPreference(this, "avoid_toll_roads", false).makeProfile().cache(); public final OsmandPreference<Boolean> AVOID_TOLL_ROADS = new BooleanPreference(this, "avoid_toll_roads", false).makeProfile().cache();

View file

@ -9,31 +9,30 @@ import android.text.style.ForegroundColorSpan;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatImageView; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.GPXUtilities; import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.TrkSegment; import net.osmand.GPXUtilities.TrkSegment;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.MenuBottomSheetDialogFragment;
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
import net.osmand.plus.helpers.FontCache; import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.helpers.GpxTrackAdapter;
import net.osmand.plus.helpers.TrackSelectSegmentAdapter; import net.osmand.plus.helpers.TrackSelectSegmentAdapter;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.helpers.TrackSelectSegmentAdapter.OnItemClickListener;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.widgets.style.CustomTypefaceSpan; import net.osmand.plus.widgets.style.CustomTypefaceSpan;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -42,33 +41,18 @@ import java.util.List;
public class TrackSelectSegmentBottomSheet extends MenuBottomSheetDialogFragment { public class TrackSelectSegmentBottomSheet extends MenuBottomSheetDialogFragment {
public static final String TAG = TrackSelectSegmentBottomSheet.class.getSimpleName(); public static final String TAG = TrackSelectSegmentBottomSheet.class.getSimpleName();
protected TrackSelectSegmentAdapter adapterSegments;
private MapActivity mapActivity;
private GPXUtilities.GPXFile gpxFile;
private OsmandApplication app;
public static void showInstance(@NonNull FragmentManager fragmentManager, @NonNull GPXUtilities.GPXFile gpxFile) { private OsmandApplication app;
if (!fragmentManager.isStateSaved()) { private GPXFile gpxFile;
TrackSelectSegmentBottomSheet fragment = new TrackSelectSegmentBottomSheet();
fragment.setRetainInstance(true);
fragment.gpxFile = gpxFile;
fragment.show(fragmentManager, TAG);
}
}
@Override @Override
public void createMenuItems(Bundle savedInstanceState) { public void createMenuItems(Bundle savedInstanceState) {
app = requiredMyApplication();
Context context = requireContext(); Context context = requireContext();
LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); LayoutInflater inflater = UiUtilities.getInflater(context, nightMode);
View itemView = inflater.inflate(R.layout.bottom_sheet_select_segment, null, false); View itemView = inflater.inflate(R.layout.bottom_sheet_select_segment, null, false);
app = getMyApplication();
if (app == null) {
return;
}
mapActivity = (MapActivity) getActivity();
String titleGpxTrack = Algorithms.getFileWithoutDirs(gpxFile.path); String titleGpxTrack = Algorithms.getFileWithoutDirs(gpxFile.path);
Typeface typeface = FontCache.getRobotoMedium(app); Typeface typeface = FontCache.getRobotoMedium(app);
String selectSegmentDescription = getString(R.string.select_segments_description, titleGpxTrack); String selectSegmentDescription = getString(R.string.select_segments_description, titleGpxTrack);
@ -86,9 +70,9 @@ public class TrackSelectSegmentBottomSheet extends MenuBottomSheetDialogFragment
LinearLayout gpxTrackContainer = itemView.findViewById(R.id.gpx_track_container); LinearLayout gpxTrackContainer = itemView.findViewById(R.id.gpx_track_container);
GPXUtilities.GPXTrackAnalysis analysis = gpxFile.getAnalysis(0); GPXUtilities.GPXTrackAnalysis analysis = gpxFile.getAnalysis(0);
AppCompatImageView icon = gpxTrackContainer.findViewById(R.id.icon); ImageView icon = gpxTrackContainer.findViewById(R.id.icon);
int sidePadding = AndroidUtils.dpToPx(mapActivity, 16f); int sidePadding = AndroidUtils.dpToPx(context, 16f);
int bottomTopPadding = AndroidUtils.dpToPx(mapActivity, 2f); int bottomTopPadding = AndroidUtils.dpToPx(context, 2f);
LinearLayout readContainer = gpxTrackContainer.findViewById(R.id.read_section); LinearLayout readContainer = gpxTrackContainer.findViewById(R.id.read_section);
readContainer.setPadding(0, bottomTopPadding, 0, bottomTopPadding); readContainer.setPadding(0, bottomTopPadding, 0, bottomTopPadding);
@ -111,15 +95,19 @@ public class TrackSelectSegmentBottomSheet extends MenuBottomSheetDialogFragment
time.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); time.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
time.setText(analysis.isTimeSpecified() ? Algorithms.formatDuration((int) (analysis.timeSpan / 1000), app.accessibilityEnabled()) : ""); time.setText(analysis.isTimeSpecified() ? Algorithms.formatDuration((int) (analysis.timeSpan / 1000), app.accessibilityEnabled()) : "");
final RecyclerView recyclerView = itemView.findViewById(R.id.gpx_segment_list); RecyclerView recyclerView = itemView.findViewById(R.id.gpx_segment_list);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setNestedScrollingEnabled(false); recyclerView.setNestedScrollingEnabled(false);
final List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(true);
adapterSegments = new TrackSelectSegmentAdapter(requireContext(), segments); List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(false);
adapterSegments.setAdapterListener(new GpxTrackAdapter.OnItemClickListener() { TrackSelectSegmentAdapter adapterSegments = new TrackSelectSegmentAdapter(context, segments);
adapterSegments.setAdapterListener(new OnItemClickListener() {
@Override @Override
public void onItemClick(int position) { public void onItemClick(int position) {
//select segment Fragment fragment = getTargetFragment();
if (fragment instanceof OnSegmentSelectedListener) {
((OnSegmentSelectedListener) fragment).onSegmentSelect(gpxFile, position);
}
dismiss(); dismiss();
} }
}); });
@ -128,30 +116,27 @@ public class TrackSelectSegmentBottomSheet extends MenuBottomSheetDialogFragment
gpxTrackContainer.setOnClickListener(new View.OnClickListener() { gpxTrackContainer.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
selectSegmentToFollow(gpxFile); Fragment fragment = getTargetFragment();
if (fragment instanceof OnSegmentSelectedListener) {
((OnSegmentSelectedListener) fragment).onSegmentSelect(gpxFile, -1);
}
dismiss(); dismiss();
} }
}); });
} }
private void selectSegmentToFollow(GPXUtilities.GPXFile gpxFile) { public interface OnSegmentSelectedListener {
if (mapActivity != null) { void onSegmentSelect(GPXFile gpxFile, int selectedSegment);
this.gpxFile = gpxFile;
TargetPointsHelper targetPointsHelper = app.getTargetPointsHelper();
RoutingHelper routingHelper = app.getRoutingHelper();
List<GPXUtilities.WptPt> points = gpxFile.getRoutePoints();
if (!points.isEmpty()) {
ApplicationMode mode = ApplicationMode.valueOfStringKey(points.get(0).getProfileType(), null);
if (mode != null) {
routingHelper.setAppMode(mode);
app.initVoiceCommandPlayer(mapActivity, mode, true, null, false, false, true);
}
}
mapActivity.getMapActions().setGPXRouteParams(gpxFile);
targetPointsHelper.updateRouteAndRefresh(true);
routingHelper.onSettingsChanged(true);
}
}
} }
public static void showInstance(@NonNull FragmentManager fragmentManager, @NonNull GPXFile gpxFile, @Nullable Fragment target) {
if (!fragmentManager.isStateSaved()) {
TrackSelectSegmentBottomSheet fragment = new TrackSelectSegmentBottomSheet();
fragment.setRetainInstance(true);
fragment.setTargetFragment(target, 0);
fragment.gpxFile = gpxFile;
fragment.show(fragmentManager, TAG);
}
}
}