diff --git a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java index 8281a127e4..7217e8af5f 100644 --- a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java +++ b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java @@ -9,6 +9,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; +import net.osmand.CallbackWithObject; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXTrackAnalysis; @@ -19,6 +20,7 @@ import net.osmand.GPXUtilities.WptPt; import net.osmand.IProgress; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; +import net.osmand.StateChangedListener; import net.osmand.data.LatLon; import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.MapMarkersHelper.MapMarkersGroup; @@ -26,6 +28,7 @@ import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType; import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType; +import net.osmand.plus.routing.RouteProvider; import net.osmand.plus.settings.backend.OsmandSettings.MetricsConstants; import net.osmand.plus.track.GpxSplitType; import net.osmand.plus.track.GradientScaleType; @@ -40,6 +43,7 @@ import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -48,6 +52,8 @@ import java.util.Set; public class GpxSelectionHelper { + private final static Log LOG = PlatformUtil.getLog(GpxSelectionHelper.class); + public static final String CURRENT_TRACK = "currentTrack"; private static final String FILE = "file"; private static final String BACKUP = "backup"; @@ -61,15 +67,18 @@ public class GpxSelectionHelper { private OsmandApplication app; @NonNull - private List selectedGPXFiles = new java.util.ArrayList<>(); - private Map selectedGpxFilesBackUp = new java.util.HashMap<>(); + private List selectedGPXFiles = new ArrayList<>(); + private Map selectedGpxFilesBackUp = new HashMap<>(); private SavingTrackHelper savingTrackHelper; - private final static Log LOG = PlatformUtil.getLog(GpxSelectionHelper.class); private SelectGpxTask selectGpxTask; + private SelectedGpxFile trackToFollow; + private StateChangedListener followTrackListener; + private boolean shouldHideTrackToFollow; - public GpxSelectionHelper(OsmandApplication osmandApplication, SavingTrackHelper trackHelper) { - this.app = osmandApplication; + public GpxSelectionHelper(OsmandApplication app, SavingTrackHelper trackHelper) { + this.app = app; savingTrackHelper = trackHelper; + app.getSettings().FOLLOW_THE_GPX_ROUTE.addListener(getFollowTrackListener()); } public void clearAllGpxFilesToShow(boolean backupSelection) { @@ -86,10 +95,18 @@ public class GpxSelectionHelper { public void restoreSelectedGpxFiles() { for (Entry gpxEntry : selectedGpxFilesBackUp.entrySet()) { if (!Algorithms.isEmpty(gpxEntry.getKey().path)) { - final File file = new File(gpxEntry.getKey().path); + File file = new File(gpxEntry.getKey().path); if (file.exists() && !file.isDirectory()) { if (file.lastModified() > gpxEntry.getValue()) { - new GpxFileLoaderTask(file, app).execute(); + new GpxFileLoaderTask(file, new CallbackWithObject() { + @Override + public boolean processResult(GPXFile result) { + if (result != null) { + selectGpxFile(result, true, false); + } + return true; + } + }).execute(); } else { selectGpxFile(gpxEntry.getKey(), true, false); } @@ -99,14 +116,52 @@ public class GpxSelectionHelper { } } + public boolean shouldHideTrackToFollow() { + return shouldHideTrackToFollow; + } + + private StateChangedListener getFollowTrackListener() { + if (followTrackListener == null) { + followTrackListener = new StateChangedListener() { + @Override + public void stateChanged(String gpxRoutePath) { + if (trackToFollow != null) { + if (shouldHideTrackToFollow) { + selectGpxFile(trackToFollow.getGpxFile(), false, false); + shouldHideTrackToFollow = false; + } + trackToFollow = null; + } + if (!Algorithms.isEmpty(gpxRoutePath)) { + trackToFollow = getSelectedFileByPath(gpxRoutePath); + if (trackToFollow == null) { + shouldHideTrackToFollow = true; + File file = new File(gpxRoutePath); + if (file.exists() && !file.isDirectory()) { + new GpxFileLoaderTask(file, new CallbackWithObject() { + @Override + public boolean processResult(GPXFile result) { + trackToFollow = selectGpxFile(result, true, false); + return true; + } + }).execute(); + } + } + } + } + }; + } + return followTrackListener; + } + private static class GpxFileLoaderTask extends AsyncTask { - File fileToLoad; - GpxSelectionHelper helper; + private File fileToLoad; + private CallbackWithObject callback; - GpxFileLoaderTask(File fileToLoad, OsmandApplication app) { + GpxFileLoaderTask(File fileToLoad, CallbackWithObject callback) { this.fileToLoad = fileToLoad; - this.helper = app.getSelectedGpxHelper(); + this.callback = callback; } @Override @@ -116,8 +171,8 @@ public class GpxSelectionHelper { @Override protected void onPostExecute(GPXFile gpxFile) { - if (gpxFile != null) { - helper.selectGpxFile(gpxFile, true, false); + if (callback != null) { + callback.processResult(gpxFile); } } } @@ -875,7 +930,13 @@ public class GpxSelectionHelper { this.displayGroups = displayGroups; } - + public boolean isFollowTrack(OsmandApplication app) { + RouteProvider.GPXRouteParamsBuilder routeParams = app.getRoutingHelper().getCurrentGPXRoute(); + if (routeParams != null) { + return gpxFile.path.equals(routeParams.getFile().path); + } + return false; + } } public enum GpxDisplayItemType { diff --git a/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java b/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java index d47eb92724..d898505b76 100644 --- a/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java +++ b/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java @@ -14,13 +14,13 @@ import net.osmand.GPXUtilities.GPXFile; import net.osmand.PlatformUtil; import net.osmand.data.LatLon; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder; import net.osmand.plus.routing.RoutingHelper; +import net.osmand.plus.settings.backend.OsmandSettings; import org.apache.commons.logging.Log; @@ -161,9 +161,8 @@ public class FailSafeFuntions { OsmandApplication app = ma.getMyApplication(); ma.getMapViewTrackingUtilities().backToLocationImpl(); RoutingHelper routingHelper = app.getRoutingHelper(); - if(gpxRoute == null) { - app.getSettings().FOLLOW_THE_GPX_ROUTE.set(null); - } + app.getSettings().FOLLOW_THE_GPX_ROUTE.set(gpxRoute != null ? gpxRoute.getFile().path : null); + routingHelper.setGpxParams(gpxRoute); if (app.getTargetPointsHelper().getPointToStart() == null) { app.getTargetPointsHelper().setStartPoint(null, false, null); diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java index 54747b068e..12346bcf12 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java @@ -27,7 +27,9 @@ import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.TrkSegment; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; +import net.osmand.ValueHolder; import net.osmand.data.QuadRect; +import net.osmand.data.RotatedTileBox; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -55,6 +57,7 @@ import net.osmand.plus.routepreparationmenu.cards.ReverseTrackCard; import net.osmand.plus.routepreparationmenu.cards.SelectTrackCard; import net.osmand.plus.routepreparationmenu.cards.TrackEditCard; import net.osmand.plus.routepreparationmenu.cards.TracksToFollowCard; +import net.osmand.plus.routing.IRouteInformationListener; import net.osmand.plus.routing.RouteProvider; import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder; import net.osmand.plus.routing.RoutingHelper; @@ -66,7 +69,7 @@ import java.io.File; import java.util.List; -public class FollowTrackFragment extends ContextMenuScrollFragment implements CardListener { +public class FollowTrackFragment extends ContextMenuScrollFragment implements CardListener, IRouteInformationListener { public static final String TAG = FollowTrackFragment.class.getName(); @@ -264,12 +267,14 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca @Override public void onResume() { super.onResume(); + app.getRoutingHelper().addListener(this); MapRouteInfoMenu.followTrackVisible = true; } @Override public void onPause() { super.onPause(); + app.getRoutingHelper().removeListener(this); MapRouteInfoMenu.followTrackVisible = false; } @@ -293,10 +298,56 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca updateStatusBarColor(); } + @Override + protected int applyPosY(int currentY, boolean needCloseMenu, boolean needMapAdjust, int previousMenuState, int newMenuState, int dZoom, boolean animated) { + int y = super.applyPosY(currentY, needCloseMenu, needMapAdjust, previousMenuState, newMenuState, dZoom, animated); + if (needMapAdjust) { + adjustMapPosition(y); + } + return y; + } + + private void adjustMapPosition(int y) { + MapActivity mapActivity = getMapActivity(); + if (mapActivity == null) { + return; + } + + RoutingHelper rh = app.getRoutingHelper(); + if (rh.isRoutePlanningMode() && mapActivity.getMapView() != null) { + QuadRect rect = mapActivity.getMapRouteInfoMenu().getRouteRect(mapActivity); + + if (gpxFile != null) { + QuadRect gpxRect = gpxFile.getRect(); + + rect.left = Math.min(rect.left, gpxRect.left); + rect.right = Math.max(rect.right, gpxRect.right); + rect.top = Math.max(rect.top, gpxRect.top); + rect.bottom = Math.min(rect.bottom, gpxRect.bottom); + } + + RotatedTileBox tb = mapActivity.getMapView().getCurrentRotatedTileBox().copy(); + int tileBoxWidthPx = 0; + int tileBoxHeightPx = 0; + + if (!isPortrait()) { + tileBoxWidthPx = tb.getPixWidth() - getWidth(); + } else { + int fHeight = getViewHeight() - y - AndroidUtils.getStatusBarHeight(app); + tileBoxHeightPx = tb.getPixHeight() - fHeight; + } + if (rect.left != 0 && rect.right != 0) { + mapActivity.getMapView().fitRectToMap(rect.left, rect.right, rect.top, rect.bottom, + tileBoxWidthPx, tileBoxHeightPx, 0); + } + } + } + @Override public void onDestroyView() { super.onDestroyView(); exitTrackAppearanceMode(); + onDismiss(); } @Override @@ -554,4 +605,36 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca log.error(e); } } + + private void onDismiss() { + try { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + if (!mapActivity.isChangingConfigurations()) { + mapActivity.getMapRouteInfoMenu().cancelSelectionFromTracks(); + } + mapActivity.getMapLayers().getMapControlsLayer().showRouteInfoControlDialog(); + } + } catch (Exception e) { + log.error(e); + } + } + + @Override + public void newRouteIsCalculated(boolean newRoute, ValueHolder showToast) { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null && newRoute && app.getRoutingHelper().isRoutePlanningMode()) { + adjustMapPosition(getHeight()); + } + } + + @Override + public void routeWasCancelled() { + + } + + @Override + public void routeWasFinished() { + + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java index e6ad1b1728..876804b945 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java @@ -43,6 +43,7 @@ import net.osmand.ValueHolder; import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; +import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.FavouritesDbHelper.FavoritesListener; @@ -95,6 +96,7 @@ import net.osmand.plus.routepreparationmenu.cards.PublicTransportNotFoundWarning import net.osmand.plus.routepreparationmenu.cards.SimpleRouteCard; import net.osmand.plus.routepreparationmenu.cards.TracksCard; import net.osmand.plus.routing.IRouteInformationListener; +import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.TransportRoutingHelper; @@ -147,6 +149,7 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener private PointType selectFromMapPointType; private int selectFromMapMenuState = MenuState.HEADER_ONLY; private boolean selectFromMapWaypoints; + private boolean selectFromTracks; private boolean showMenu = false; private int showMenuState = DEFAULT_MENU_STATE; @@ -1563,8 +1566,7 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener if (mapActivity != null) { GPXRouteParamsBuilder routeParams = mapActivity.getRoutingHelper().getCurrentGPXRoute(); if (routeParams != null) { - FollowTrackFragment trackOptionsFragment = new FollowTrackFragment(); - FollowTrackFragment.showInstance(mapActivity, trackOptionsFragment); + selectTrack(); } } } @@ -1577,6 +1579,7 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener FrameLayout viaButton = mainView.findViewById(R.id.via_button); AndroidUiHelper.updateVisibility(viaButton, routeParams == null || isFinishPointFromTrack()); + viaButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -1949,6 +1952,19 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener } } + public void selectTrack() { + selectFromTracks = true; + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + FollowTrackFragment trackOptionsFragment = new FollowTrackFragment(); + FollowTrackFragment.showInstance(mapActivity, trackOptionsFragment); + } + } + + public void cancelSelectionFromTracks() { + selectFromTracks = false; + } + public void setupFields(PointType pointType) { View mainView = getMainView(); if (mainView != null) { @@ -2248,7 +2264,7 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener if (switched) { mapActivity.getMapLayers().getMapControlsLayer().switchToRouteFollowingLayout(); } - if (mapActivity.getPointToNavigate() == null && !selectFromMapTouch) { + if (mapActivity.getPointToNavigate() == null && !selectFromMapTouch && !selectFromTracks) { mapActivity.getMapActions().stopNavigationWithoutConfirm(); } mapActivity.updateStatusBarColor(); @@ -2363,6 +2379,32 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener updateMenu(); } + @NonNull + public QuadRect getRouteRect(@NonNull MapActivity mapActivity) { + OsmandApplication app = mapActivity.getMyApplication(); + RoutingHelper routingHelper = app.getRoutingHelper(); + MapRouteInfoMenu menu = mapActivity.getMapRouteInfoMenu(); + + QuadRect rect = new QuadRect(0, 0, 0, 0); + if (menu.isTransportRouteCalculated()) { + TransportRoutingHelper transportRoutingHelper = app.getTransportRoutingHelper(); + TransportRouteResult result = transportRoutingHelper.getCurrentRouteResult(); + if (result != null) { + QuadRect transportRouteRect = transportRoutingHelper.getTransportRouteRect(result); + if (transportRouteRect != null) { + rect = transportRouteRect; + } + } + } else if (routingHelper.isRouteCalculated()) { + RouteCalculationResult result = routingHelper.getRoute(); + QuadRect routeRect = routingHelper.getRouteRect(result); + if (routeRect != null) { + rect = routeRect; + } + } + return rect; + } + public enum MapRouteMenuType { ROUTE_INFO, ROUTE_DETAILS diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenuFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenuFragment.java index 537901f6f2..bd1d382677 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenuFragment.java @@ -16,23 +16,16 @@ import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import net.osmand.AndroidUtils; -import net.osmand.Location; import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; -import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.ContextMenuFragment; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.routing.RoutingHelper; -import net.osmand.plus.routing.TransportRoutingHelper; +import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.widgets.TextViewExProgress; -import net.osmand.router.TransportRouteResult; -import net.osmand.util.MapUtils; - -import java.util.List; public class MapRouteInfoMenuFragment extends ContextMenuFragment { public static final String TAG = MapRouteInfoMenuFragment.class.getName(); @@ -289,36 +282,7 @@ public class MapRouteInfoMenuFragment extends ContextMenuFragment { RoutingHelper rh = app.getRoutingHelper(); if (rh.isRoutePlanningMode() && mapActivity.getMapView() != null) { - QuadRect r = new QuadRect(0, 0, 0, 0); - if (menu.isTransportRouteCalculated()) { - TransportRoutingHelper transportRoutingHelper = app.getTransportRoutingHelper(); - TransportRouteResult result = transportRoutingHelper.getCurrentRouteResult(); - if (result != null) { - QuadRect transportRouteRect = transportRoutingHelper.getTransportRouteRect(result); - if (transportRouteRect != null) { - r = transportRouteRect; - } - } - } else if (rh.isRouteCalculated()) { - Location lt = rh.getLastProjection(); - if (lt == null) { - lt = app.getTargetPointsHelper().getPointToStartLocation(); - } - if (lt == null) { - lt = app.getLocationProvider().getLastKnownLocation(); - } - if (lt != null) { - MapUtils.insetLatLonRect(r, lt.getLatitude(), lt.getLongitude()); - } - List list = rh.getCurrentCalculatedRoute(); - for (Location l : list) { - MapUtils.insetLatLonRect(r, l.getLatitude(), l.getLongitude()); - } - List targetPoints = app.getTargetPointsHelper().getIntermediatePointsWithTarget(); - for (TargetPoint l : targetPoints) { - MapUtils.insetLatLonRect(r, l.getLatitude(), l.getLongitude()); - } - } + QuadRect r = menu.getRouteRect(mapActivity); RotatedTileBox tb = mapActivity.getMapView().getCurrentRotatedTileBox().copy(); int tileBoxWidthPx = 0; int tileBoxHeightPx = 0; diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java index c6d3df05ca..0d23e78673 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java @@ -5,7 +5,6 @@ import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; -import android.view.MenuItem; import android.view.View; import android.widget.CompoundButton; import android.widget.ImageView; @@ -13,14 +12,10 @@ import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.ColorRes; -import androidx.appcompat.view.ContextThemeWrapper; -import androidx.appcompat.widget.PopupMenu; import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentManager; import net.osmand.AndroidUtils; -import net.osmand.CallbackWithObject; -import net.osmand.GPXUtilities; import net.osmand.StateChangedListener; import net.osmand.plus.OsmAndLocationSimulation; import net.osmand.plus.OsmandApplication; @@ -35,7 +30,6 @@ import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerStartItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; -import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.AvoidPTTypesRoutingParameter; import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.AvoidRoadsRoutingParameter; import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.DividerItem; @@ -367,8 +361,9 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - FollowTrackFragment trackOptionsFragment = new FollowTrackFragment(); - FollowTrackFragment.showInstance(mapActivity, trackOptionsFragment); + MapRouteInfoMenu mapRouteInfoMenu = mapActivity.getMapRouteInfoMenu(); + mapRouteInfoMenu.hide(); + mapRouteInfoMenu.selectTrack(); dismiss(); } }) @@ -500,58 +495,6 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { f.show(fragmentManager, RouteOptionsBottomSheet.TAG); } - protected void openGPXFileSelection() { - GpxUiHelper.selectGPXFile(mapActivity, false, false, new CallbackWithObject() { - - @Override - public boolean processResult(GPXUtilities.GPXFile[] result) { - mapActivity.getMapActions().setGPXRouteParams(result[0]); - app.getTargetPointsHelper().updateRouteAndRefresh(true); - updateParameters(); - routingHelper.recalculateRouteDueToSettingsChange(); - return true; - } - }, nightMode); - } - - private void showOptionsMenu(View view) { - RouteProvider.GPXRouteParamsBuilder rp = mapActivity.getRoutingHelper().getCurrentGPXRoute(); - final PopupMenu optionsMenu = new PopupMenu(new ContextThemeWrapper(view.getContext(), themeRes), view); - MenuItem item = optionsMenu.getMenu().add( - mapActivity.getString(R.string.shared_string_none)); - item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - if (mapActivity.getRoutingHelper().getCurrentGPXRoute() != null) { - mapActivity.getRoutingHelper().setGpxParams(null); - settings.FOLLOW_THE_GPX_ROUTE.set(null); - mapActivity.getRoutingHelper().recalculateRouteDueToSettingsChange(); - } - updateParameters(); - return true; - } - }); - item = optionsMenu.getMenu().add(mapActivity.getString(R.string.select_gpx)); - item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - openGPXFileSelection(); - return true; - } - }); - if (rp != null) { - item = optionsMenu.getMenu().add(new File(rp.getFile().path).getName()); - item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - // nothing to change - return true; - } - }); - } - optionsMenu.show(); - } - public void updateParameters() { Activity activity = getActivity(); View mainView = getView(); diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index 57becfe9a6..4fd5b1dd65 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -1,9 +1,10 @@ package net.osmand.plus.routing; -import net.osmand.GPXUtilities; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import net.osmand.GPXUtilities.GPXFile; -import net.osmand.GPXUtilities.WptPt; import net.osmand.Location; import net.osmand.LocationsHolder; import net.osmand.PlatformUtil; @@ -12,14 +13,11 @@ import net.osmand.ValueHolder; import net.osmand.binary.RouteDataObject; import net.osmand.data.LatLon; import net.osmand.data.QuadPoint; -import net.osmand.plus.routing.RouteProvider.RoutingEnvironment; -import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.data.QuadRect; import net.osmand.plus.NavigationService; -import net.osmand.plus.settings.backend.OsmAndAppCustomization.OsmAndAppCustomizationListener; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper.TargetPoint; @@ -27,9 +25,12 @@ import net.osmand.plus.notifications.OsmandNotification.NotificationType; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder; import net.osmand.plus.routing.RouteProvider.RouteService; +import net.osmand.plus.routing.RouteProvider.RoutingEnvironment; +import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.plus.settings.backend.OsmAndAppCustomization.OsmAndAppCustomizationListener; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.router.RouteCalculationProgress; import net.osmand.router.RouteExporter; -import net.osmand.router.RoutePlannerFrontEnd; import net.osmand.router.RoutePlannerFrontEnd.GpxPoint; import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation; import net.osmand.router.RouteSegmentResult; @@ -1041,7 +1042,30 @@ public class RoutingHelper { return route.getRouteDirections(); } + @Nullable + public QuadRect getRouteRect(@NonNull RouteCalculationResult result) { + QuadRect rect = new QuadRect(0, 0, 0, 0); + Location lt = getLastProjection(); + if (lt == null) { + lt = app.getTargetPointsHelper().getPointToStartLocation(); + } + if (lt == null) { + lt = app.getLocationProvider().getLastKnownLocation(); + } + if (lt != null) { + MapUtils.insetLatLonRect(rect, lt.getLatitude(), lt.getLongitude()); + } + List list = result.getImmutableAllLocations(); + for (Location l : list) { + MapUtils.insetLatLonRect(rect, l.getLatitude(), l.getLongitude()); + } + List targetPoints = app.getTargetPointsHelper().getIntermediatePointsWithTarget(); + for (TargetPoint l : targetPoints) { + MapUtils.insetLatLonRect(rect, l.getLatitude(), l.getLongitude()); + } + return rect.left == 0 && rect.right == 0 ? null : rect; + } private class RouteRecalculationThread extends Thread { @@ -1344,6 +1368,7 @@ public class RoutingHelper { // NEVER returns null + @NonNull public RouteCalculationResult getRoute() { return route; } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index 2f7cf6cb5f..4752e180f7 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -43,11 +43,13 @@ import net.osmand.plus.MapMarkersHelper.MapMarkersGroup; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; +import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.PointImageDrawable; import net.osmand.plus.mapcontextmenu.controllers.SelectedGpxMenuController.SelectedGpxPoint; import net.osmand.plus.mapcontextmenu.other.TrackChartPoints; import net.osmand.plus.render.OsmandRenderer; import net.osmand.plus.render.OsmandRenderer.RenderingContext; +import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference; import net.osmand.plus.track.SaveGpxAsyncTask; import net.osmand.plus.track.TrackDrawInfo; @@ -70,6 +72,7 @@ import org.apache.commons.logging.Log; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -234,7 +237,15 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM @Override public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) { - List selectedGPXFiles = selectedGpxHelper.getSelectedGPXFiles(); + List selectedGPXFiles = new ArrayList<>(selectedGpxHelper.getSelectedGPXFiles()); + + Iterator iterator = selectedGPXFiles.iterator(); + while (iterator.hasNext()) { + SelectedGpxFile selectedGpxFile = iterator.next(); + if (selectedGpxFile.isFollowTrack(view.getApplication()) && !showTrackToFollow()) { + iterator.remove(); + } + } cache.clear(); if (!selectedGPXFiles.isEmpty()) { drawSelectedFilesSegments(canvas, tileBox, selectedGPXFiles, settings); @@ -710,6 +721,21 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM || gpxFile.path.equals(trackDrawInfo.getFilePath())); } + private boolean showTrackToFollow() { + if (view.getContext() instanceof MapActivity) { + MapActivity mapActivity = (MapActivity) view.getContext(); + OsmandApplication app = mapActivity.getMyApplication(); + MapRouteInfoMenu routeInfoMenu = mapActivity.getMapRouteInfoMenu(); + return !app.getSelectedGpxHelper().shouldHideTrackToFollow() + || routeInfoMenu.isVisible() + || app.getRoutingHelper().isFollowingMode() + || MapRouteInfoMenu.followTrackVisible + || MapRouteInfoMenu.chooseRoutesVisible + || MapRouteInfoMenu.waypointsVisible; + } + return false; + } + private boolean isPointVisited(WptPt o) { boolean visit = false; String visited = o.getExtensionsToRead().get("VISITED_KEY"); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java index cd6bf62ced..6f4708e381 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java @@ -58,7 +58,6 @@ import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin; import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu.PointType; import net.osmand.plus.routing.RoutingHelper; -import net.osmand.plus.routing.TransportRoutingHelper; import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchType; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmAndAppCustomization; @@ -847,7 +846,6 @@ public class MapControlsLayer extends OsmandMapLayer { // default buttons boolean routePlanningMode = false; RoutingHelper rh = mapActivity.getRoutingHelper(); - TransportRoutingHelper trh = mapActivity.getRoutingHelper().getTransportRoutingHelper(); if (rh.isRoutePlanningMode()) { routePlanningMode = true; } else if ((rh.isRouteCalculated() || rh.isRouteBeingCalculated()) && !rh.isFollowingMode()) { @@ -860,33 +858,25 @@ public class MapControlsLayer extends OsmandMapLayer { ((app.accessibilityEnabled() || (System.currentTimeMillis() - touchEvent < TIMEOUT_TO_SHOW_BUTTONS)) && routeFollowingMode); boolean routeDialogOpened = mapRouteInfoMenu.isVisible() || (showRouteCalculationControls && mapRouteInfoMenu.needShowMenu()); updateMyLocationVisibility(backToLocationControl, rh, routeDialogOpened || contextMenuOpened); - boolean showButtons = (showRouteCalculationControls || !routeFollowingMode) + //routePlanningBtn.setIconResId(routeFollowingMode ? R.drawable.ic_action_info_dark : R.drawable.ic_action_gdirections_dark); + + updateRoutePlaningButton(rh, routePlanningMode); + + boolean showBottomMenuButtons = (showRouteCalculationControls || !routeFollowingMode) && !isInMovingMarkerMode() && !isInGpxDetailsMode() && !isInMeasurementToolMode() && !isInPlanRouteMode() && !contextMenuOpened && !isInChoosingRoutesMode() - && !isInWaypointsChoosingMode() && !isInTrackAppearanceMode(); - //routePlanningBtn.setIconResId(routeFollowingMode ? R.drawable.ic_action_info_dark : R.drawable.ic_action_gdirections_dark); - int routePlanningBtnImage = mapRouteInfoMenu.getRoutePlanningBtnImage(); - if (routePlanningBtnImage != 0) { - routePlanningBtn.setIconResId(routePlanningBtnImage); - routePlanningBtn.setIconColorId(R.color.color_myloc_distance); - } else if (rh.isFollowingMode()) { - routePlanningBtn.setIconResId(R.drawable.ic_action_start_navigation); - routePlanningBtn.setIconColorId(R.color.color_myloc_distance); - } else if (routePlanningMode) { - routePlanningBtn.setIconResId(R.drawable.ic_action_gdirections_dark); - routePlanningBtn.setIconColorId(R.color.color_myloc_distance); - } else { - routePlanningBtn.setIconResId(R.drawable.ic_action_gdirections_dark); - routePlanningBtn.resetIconColors(); - } - routePlanningBtn.updateVisibility(showButtons); - menuControl.updateVisibility(showButtons); + && !isInWaypointsChoosingMode() && !isInFollowTrackMode() && !isInTrackAppearanceMode(); + routePlanningBtn.updateVisibility(showBottomMenuButtons); + menuControl.updateVisibility(showBottomMenuButtons); + boolean showZoomButtons = !routeDialogOpened && !contextMenuOpened && !isInTrackAppearanceMode() + && !isInFollowTrackMode() && (!isInChoosingRoutesMode() || !isInWaypointsChoosingMode() || !portrait); + mapZoomIn.updateVisibility(showZoomButtons); + mapZoomOut.updateVisibility(showZoomButtons); - mapZoomIn.updateVisibility(!routeDialogOpened && !contextMenuOpened && !isInTrackAppearanceMode() && (!isInChoosingRoutesMode() || !isInWaypointsChoosingMode() || !portrait)); - mapZoomOut.updateVisibility(!routeDialogOpened && !contextMenuOpened && !isInTrackAppearanceMode() && (!isInChoosingRoutesMode() || !isInWaypointsChoosingMode() || !portrait)); - boolean forceHideCompass = routeDialogOpened || trackDialogOpened - || isInMeasurementToolMode() || isInPlanRouteMode() || contextMenuOpened || isInChoosingRoutesMode() || isInTrackAppearanceMode() || isInWaypointsChoosingMode(); + boolean forceHideCompass = routeDialogOpened || trackDialogOpened || isInMeasurementToolMode() + || isInPlanRouteMode() || contextMenuOpened || isInChoosingRoutesMode() + || isInTrackAppearanceMode() || isInWaypointsChoosingMode() || isInFollowTrackMode(); compassHud.forceHideCompass = forceHideCompass; compassHud.updateVisibility(!forceHideCompass && shouldShowCompass()); @@ -895,10 +885,11 @@ public class MapControlsLayer extends OsmandMapLayer { if (layersHud.setIconResId(appMode.getIconRes())) { layersHud.update(app, isNight); } - layersHud.updateVisibility(!routeDialogOpened && !trackDialogOpened && !isInMeasurementToolMode() && !isInPlanRouteMode() - && !contextMenuOpened && !isInChoosingRoutesMode() && !isInTrackAppearanceMode() && !isInWaypointsChoosingMode()); - quickSearchHud.updateVisibility(!routeDialogOpened && !trackDialogOpened && !isInMeasurementToolMode() && !isInPlanRouteMode() - && !contextMenuOpened && !isInChoosingRoutesMode() && !isInTrackAppearanceMode() && !isInWaypointsChoosingMode()); + boolean showTopButtons = !routeDialogOpened && !trackDialogOpened && !contextMenuOpened + && !isInMeasurementToolMode() && !isInPlanRouteMode() && !isInChoosingRoutesMode() + && !isInTrackAppearanceMode() && !isInWaypointsChoosingMode() && !isInFollowTrackMode(); + layersHud.updateVisibility(showTopButtons); + quickSearchHud.updateVisibility(showTopButtons); if (mapView.isZooming()) { lastZoom = System.currentTimeMillis(); @@ -948,6 +939,23 @@ public class MapControlsLayer extends OsmandMapLayer { } } + private void updateRoutePlaningButton(RoutingHelper routingHelper, boolean routePlanningMode) { + int routePlanningBtnImage = mapRouteInfoMenu.getRoutePlanningBtnImage(); + if (routePlanningBtnImage != 0) { + routePlanningBtn.setIconResId(routePlanningBtnImage); + routePlanningBtn.setIconColorId(R.color.color_myloc_distance); + } else if (routingHelper.isFollowingMode()) { + routePlanningBtn.setIconResId(R.drawable.ic_action_start_navigation); + routePlanningBtn.setIconColorId(R.color.color_myloc_distance); + } else if (routePlanningMode) { + routePlanningBtn.setIconResId(R.drawable.ic_action_gdirections_dark); + routePlanningBtn.setIconColorId(R.color.color_myloc_distance); + } else { + routePlanningBtn.setIconResId(R.drawable.ic_action_gdirections_dark); + routePlanningBtn.resetIconColors(); + } + } + private boolean shouldShowCompass() { float mapRotate = mapActivity.getMapView().getRotate(); return forceShowCompass || mapRotate != 0 @@ -987,7 +995,7 @@ public class MapControlsLayer extends OsmandMapLayer { boolean tracked = mapActivity.getMapViewTrackingUtilities().isMapLinkedToLocation(); boolean visible = !(tracked && rh.isFollowingMode()); backToLocationControl.updateVisibility(visible && !dialogOpened && !isInPlanRouteMode() - && !isInTrackAppearanceMode() && (!isInChoosingRoutesMode() || !isInWaypointsChoosingMode() || !isPotrait())); + && !isInTrackAppearanceMode() && (!isInChoosingRoutesMode() || !isInWaypointsChoosingMode() || !isInFollowTrackMode() || !isPotrait())); } public boolean onSingleTap(PointF point, RotatedTileBox tileBox) { @@ -1303,6 +1311,10 @@ public class MapControlsLayer extends OsmandMapLayer { return MapRouteInfoMenu.waypointsVisible; } + private boolean isInFollowTrackMode() { + return MapRouteInfoMenu.followTrackVisible; + } + public static View.OnLongClickListener getOnClickMagnifierListener(final OsmandMapTileView view) { return new View.OnLongClickListener() { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java index 722b5133c6..0353776edb 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java @@ -426,6 +426,7 @@ public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRe mapRouteInfoMenu.isVisible() || MapRouteInfoMenu.chooseRoutesVisible || MapRouteInfoMenu.waypointsVisible || + MapRouteInfoMenu.followTrackVisible || contextMenu.isVisible() && contextMenuMenuFragment != null && !contextMenuMenuFragment.isRemoving() || contextMenu.isVisible() && contextMenuMenuFragment != null && contextMenuMenuFragment.isAdded() || multiSelectionMenu.isVisible() && multiMenuFragment != null && multiMenuFragment.isAdded() || diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/LanesControl.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/LanesControl.java index 05f7a7586c..45ba996045 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/LanesControl.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/LanesControl.java @@ -18,7 +18,7 @@ import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.views.OsmandMapLayer; +import net.osmand.plus.views.OsmandMapLayer.DrawSettings; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.mapwidgets.widgets.TextInfoWidget; import net.osmand.router.RouteResultPreparation; @@ -61,7 +61,7 @@ public class LanesControl { TextInfoWidget.updateTextColor(lanesText, lanesShadowText, textColor, textShadowColor, textBold, shadowRadius); } - public boolean updateInfo(OsmandMapLayer.DrawSettings drawSettings) { + public boolean updateInfo(DrawSettings drawSettings) { boolean visible = false; int locimminent = -1; int[] loclanes = null; @@ -105,7 +105,8 @@ public class LanesControl { } } } - visible = loclanes != null && loclanes.length > 0 && !MapRouteInfoMenu.chooseRoutesVisible && !MapRouteInfoMenu.waypointsVisible; + visible = loclanes != null && loclanes.length > 0 && !MapRouteInfoMenu.chooseRoutesVisible + && !MapRouteInfoMenu.waypointsVisible && !MapRouteInfoMenu.followTrackVisible; if (visible) { if (!Arrays.equals(lanesDrawable.lanes, loclanes) || (locimminent == 0) != lanesDrawable.imminent) { diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java index d01f042bd8..9979b3820b 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java @@ -1232,7 +1232,8 @@ public class MapInfoWidgetsFactory { boolean visible = settings.SHOW_COORDINATES_WIDGET.get() && map.getContextMenu().shouldShowTopControls() && map.getMapRouteInfoMenu().shouldShowTopControls() && !map.isTopToolbarActive() && !map.getMapLayers().getGpxLayer().isInTrackAppearanceMode() - && !MapRouteInfoMenu.chooseRoutesVisible && !MapRouteInfoMenu.waypointsVisible; + && !MapRouteInfoMenu.chooseRoutesVisible && !MapRouteInfoMenu.waypointsVisible + && !MapRouteInfoMenu.followTrackVisible; updateVisibility(visible); if (visible) {