diff --git a/OsmAnd/res/layout/add_new_favorite_category.xml b/OsmAnd/res/layout/add_new_favorite_category.xml
new file mode 100644
index 0000000000..74510f0842
--- /dev/null
+++ b/OsmAnd/res/layout/add_new_favorite_category.xml
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_btn.xml b/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_btn.xml
index a346825302..d4d052c868 100644
--- a/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_btn.xml
+++ b/OsmAnd/res/layout/bottom_sheet_item_with_descr_and_radio_btn.xml
@@ -9,6 +9,7 @@
+ Copy POI name
The recording will be continued.
+ Select category or add new one
Distance by tap
A toggle to show or hide the Coordinates widget on the map.
Show Coordinates widget
diff --git a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java
index 69c159bed0..10a8c2ae84 100644
--- a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java
+++ b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java
@@ -30,7 +30,7 @@ import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
import net.osmand.plus.helpers.enums.MetricsConstants;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
-import net.osmand.plus.routing.RouteProvider;
+import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.track.GpxSplitType;
import net.osmand.util.Algorithms;
@@ -928,7 +928,7 @@ public class GpxSelectionHelper {
}
public boolean isFollowTrack(OsmandApplication app) {
- RouteProvider.GPXRouteParamsBuilder routeParams = app.getRoutingHelper().getCurrentGPXRoute();
+ GPXRouteParamsBuilder routeParams = app.getRoutingHelper().getCurrentGPXRoute();
if (routeParams != null) {
return gpxFile.path.equals(routeParams.getFile().path);
}
diff --git a/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java b/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java
index 2dbd4f6dd9..8b62b540b3 100644
--- a/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java
+++ b/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java
@@ -18,7 +18,7 @@ import net.osmand.GPXUtilities;
import net.osmand.Location;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.GpxUiHelper;
-import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
+import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.settings.backend.ApplicationMode;
import java.util.ArrayList;
diff --git a/OsmAnd/src/net/osmand/plus/TargetPointsHelper.java b/OsmAnd/src/net/osmand/plus/TargetPointsHelper.java
index 472899862b..bd77ebf33b 100644
--- a/OsmAnd/src/net/osmand/plus/TargetPointsHelper.java
+++ b/OsmAnd/src/net/osmand/plus/TargetPointsHelper.java
@@ -10,7 +10,7 @@ import net.osmand.data.LatLon;
import net.osmand.data.LocationPoint;
import net.osmand.data.PointDescription;
import net.osmand.plus.GeocodingLookupService.AddressLookupRequest;
-import net.osmand.plus.routing.RouteProvider.RouteService;
+import net.osmand.plus.routing.RouteService;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.routing.RoutingHelperUtils;
import net.osmand.plus.settings.backend.ApplicationMode;
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
index 2273c91742..7e0a07e40c 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
@@ -93,6 +93,7 @@ import net.osmand.plus.importfiles.ImportHelper;
import net.osmand.plus.mapcontextmenu.AdditionalActionsBottomSheetDialogFragment;
import net.osmand.plus.mapcontextmenu.MapContextMenu;
import net.osmand.plus.mapcontextmenu.builders.cards.dialogs.ContextMenuCardDialogFragment;
+import net.osmand.plus.mapcontextmenu.editors.SelectFavoriteCategoryBottomSheet;
import net.osmand.plus.mapcontextmenu.other.DestinationReachedMenu;
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
import net.osmand.plus.mapmarkers.MapMarker;
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index bfc5077b2e..34f020fd17 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -69,7 +69,7 @@ import net.osmand.plus.profiles.ProfileDataObject;
import net.osmand.plus.profiles.ProfileDataUtils;
import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu;
import net.osmand.plus.routepreparationmenu.WaypointsFragment;
-import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
+import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
diff --git a/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java b/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java
index 46708ce5ae..26fe55e1e8 100644
--- a/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java
+++ b/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java
@@ -18,7 +18,7 @@ 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.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.settings.backend.OsmandSettings;
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/AddNewFavoriteCategoryBottomSheet.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/AddNewFavoriteCategoryBottomSheet.java
new file mode 100644
index 0000000000..d90c06b609
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/AddNewFavoriteCategoryBottomSheet.java
@@ -0,0 +1,248 @@
+package net.osmand.plus.mapcontextmenu.editors;
+
+import android.content.res.ColorStateList;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.FragmentActivity;
+
+import com.google.android.material.textfield.TextInputEditText;
+import com.google.android.material.textfield.TextInputLayout;
+
+import net.osmand.AndroidUtils;
+import net.osmand.plus.FavouritesDbHelper;
+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.MenuBottomSheetDialogFragment;
+import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
+import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
+import net.osmand.plus.helpers.ColorDialogs;
+import net.osmand.plus.myplaces.AddNewTrackFolderBottomSheet;
+import net.osmand.plus.routepreparationmenu.cards.BaseCard;
+import net.osmand.plus.track.ColorsCard;
+import net.osmand.plus.track.CustomColorBottomSheet;
+import net.osmand.util.Algorithms;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+public class AddNewFavoriteCategoryBottomSheet extends MenuBottomSheetDialogFragment implements CustomColorBottomSheet.ColorPickerListener, BaseCard.CardListener {
+
+
+ public static final String TAG = AddNewTrackFolderBottomSheet.class.getName();
+ private static final String KEY_CTX_EDIT_CAT_EDITOR_TAG = "key_ctx_edit_cat_editor_tag";
+ private static final String KEY_CTX_EDIT_GPX_FILE = "key_ctx_edit_gpx_file";
+ private static final String KEY_CTX_EDIT_GPX_CATEGORIES = "key_ctx_edit_gpx_categories";
+ private static final String KEY_CTX_EDIT_CAT_NEW = "key_ctx_edit_cat_new";
+ private static final String KEY_CTX_EDIT_CAT_NAME = "key_ctx_edit_cat_name";
+ private static final String KEY_CTX_EDIT_CAT_COLOR = "key_ctx_edit_cat_color";
+ FavouritesDbHelper favoritesHelper;
+ private boolean isNew = true;
+ private String name = "";
+ private boolean isGpx;
+ private ArrayList gpxCategories;
+ private int selectedColor;
+ private ColorsCard colorsCard;
+ private TextInputEditText editText;
+ private TextInputLayout nameTextBox;
+ private View view;
+ private String editorTag;
+ private SelectFavoriteCategoryBottomSheet.CategorySelectionListener selectionListener;
+
+ public static AddNewFavoriteCategoryBottomSheet createInstance(@NonNull String editorTag, @Nullable Set gpxCategories, boolean isGpx) {
+ AddNewFavoriteCategoryBottomSheet fragment = new AddNewFavoriteCategoryBottomSheet();
+ Bundle bundle = new Bundle();
+ bundle.putString(KEY_CTX_EDIT_CAT_EDITOR_TAG, editorTag);
+ bundle.putBoolean(KEY_CTX_EDIT_GPX_FILE, isGpx);
+ if (gpxCategories != null) {
+ bundle.putStringArrayList(KEY_CTX_EDIT_GPX_CATEGORIES, new ArrayList<>(gpxCategories));
+ }
+ fragment.setArguments(bundle);
+ fragment.setRetainInstance(true);
+ return fragment;
+ }
+
+ public void setSelectionListener(SelectFavoriteCategoryBottomSheet.CategorySelectionListener selectionListener) {
+ this.selectionListener = selectionListener;
+ }
+
+ @Override
+ protected int getRightBottomButtonTextId() {
+ return R.string.shared_string_save;
+ }
+
+ private boolean isGpxCategoryExists(@NonNull String name) {
+ boolean res = false;
+ if (gpxCategories != null) {
+ String nameLC = name.toLowerCase();
+ for (String category : gpxCategories) {
+ if (category.toLowerCase().equals(nameLC)) {
+ res = true;
+ break;
+ }
+ }
+ }
+ return res;
+ }
+
+ @Override
+ protected void onRightBottomButtonClick() {
+ name = editText.getText().toString().trim();
+ FragmentActivity activity = getActivity();
+ if (activity != null) {
+ boolean exists = isGpx ? isGpxCategoryExists(name) : favoritesHelper.groupExists(name);
+ if (exists) {
+ AlertDialog.Builder b = new AlertDialog.Builder(activity);
+ b.setMessage(getString(R.string.favorite_category_dublicate_message));
+ b.setNegativeButton(R.string.shared_string_ok, null);
+ b.show();
+ } else {
+ if (activity instanceof MapActivity) {
+ if (!isGpx) {
+ favoritesHelper.addEmptyCategory(name, selectedColor);
+ }
+ PointEditor editor = ((MapActivity) activity).getContextMenu().getPointEditor(editorTag);
+
+ if (editor != null) {
+ editor.setCategory(name, selectedColor);
+ }
+
+ if (selectionListener != null) {
+ selectionListener.onCategorySelected(name, selectedColor);
+ }
+ }
+ dismiss();
+ }
+ }
+ }
+
+ @Override
+ protected UiUtilities.DialogButtonType getRightBottomButtonType() {
+ return UiUtilities.DialogButtonType.PRIMARY;
+ }
+
+ @Nullable
+ public FavouritesDbHelper getHelper() {
+ return favoritesHelper;
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ saveState(outState);
+ super.onSaveInstanceState(outState);
+ }
+
+ public void saveState(Bundle bundle) {
+ bundle.putString(KEY_CTX_EDIT_CAT_EDITOR_TAG, editorTag);
+ bundle.putString(KEY_CTX_EDIT_CAT_NEW, Boolean.valueOf(isNew).toString());
+ bundle.putString(KEY_CTX_EDIT_CAT_NAME, editText.getText().toString().trim());
+ bundle.putString(KEY_CTX_EDIT_CAT_COLOR, "" + selectedColor);
+ bundle.putBoolean(KEY_CTX_EDIT_GPX_FILE, isGpx);
+ if (gpxCategories != null) {
+ bundle.putStringArrayList(KEY_CTX_EDIT_GPX_CATEGORIES, gpxCategories);
+ }
+ }
+
+ @Override
+ public void createMenuItems(Bundle savedInstanceState) {
+ OsmandApplication app = requiredMyApplication();
+ favoritesHelper = app.getFavorites();
+
+ if (savedInstanceState != null) {
+ restoreState(savedInstanceState);
+ } else if (getArguments() != null) {
+ restoreState(getArguments());
+ }
+
+
+ items.add(new TitleItem(getString(R.string.favorite_category_add_new_title)));
+ selectedColor = getResources().getColor(R.color.color_favorite);
+
+ view = UiUtilities.getInflater(app, nightMode).inflate(R.layout.add_new_favorite_category, null);
+ nameTextBox = view.findViewById(R.id.name_text_box);
+ nameTextBox.setBoxBackgroundColorResource(nightMode ? R.color.list_background_color_dark : R.color.activity_background_color_light);
+ nameTextBox.setHint(app.getResources().getString(R.string.favorite_category_name));
+ ColorStateList colorStateList = ColorStateList.valueOf(ContextCompat
+ .getColor(app, nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light));
+ nameTextBox.setDefaultHintTextColor(colorStateList);
+ editText = view.findViewById(R.id.name_edit_text);
+ editText.setText(name);
+ editText.requestFocus();
+ AndroidUtils.softKeyboardDelayed(getActivity(), editText);
+ nameTextBox.setStartIconTintList(ColorStateList.valueOf(selectedColor));
+ nameTextBox.setBoxStrokeColorStateList(ColorStateList.valueOf(selectedColor));
+
+ BaseBottomSheetItem editFolderName = new BaseBottomSheetItem.Builder()
+ .setCustomView(view)
+ .create();
+ items.add(editFolderName);
+ MapActivity mapActivity = (MapActivity) getActivity();
+ List colors = new ArrayList<>();
+ for (int color : ColorDialogs.pallette) {
+ colors.add(color);
+ }
+ colorsCard = new ColorsCard(mapActivity, selectedColor, this, colors, app.getSettings().CUSTOM_TRACK_COLORS, null);
+ colorsCard.setListener(this);
+ LinearLayout selectColor = view.findViewById(R.id.select_color);
+ selectColor.addView(colorsCard.build(view.getContext()));
+ }
+
+ private void updateColorSelector(int color) {
+ ((TextView) view.findViewById(R.id.color_name)).setText(ColorDialogs.getColorName(color));
+ selectedColor = color;
+ nameTextBox.setStartIconTintList(ColorStateList.valueOf(selectedColor));
+ nameTextBox.setBoxStrokeColorStateList(ColorStateList.valueOf(selectedColor));
+ }
+
+ @Override
+ public void onCardLayoutNeeded(@NonNull BaseCard card) {
+
+ }
+
+ @Override
+ public void onCardPressed(@NonNull BaseCard card) {
+ if (card instanceof ColorsCard) {
+ int color = ((ColorsCard) card).getSelectedColor();
+ updateColorSelector(color);
+ }
+ }
+
+ @Override
+ public void onCardButtonPressed(@NonNull BaseCard card, int buttonIndex) {
+
+ }
+
+ @Override
+ public void onColorSelected(Integer prevColor, int newColor) {
+ colorsCard.onColorSelected(prevColor, newColor);
+ int color = colorsCard.getSelectedColor();
+ updateColorSelector(color);
+ }
+
+ public void restoreState(Bundle bundle) {
+ editorTag = bundle.getString(KEY_CTX_EDIT_CAT_EDITOR_TAG);
+ String isNewStr = bundle.getString(KEY_CTX_EDIT_CAT_NEW);
+ if (isNewStr != null) {
+ isNew = Boolean.parseBoolean(isNewStr);
+ }
+ name = bundle.getString(KEY_CTX_EDIT_CAT_NAME);
+ if (name == null) {
+ name = "";
+ }
+ String colorStr = bundle.getString(KEY_CTX_EDIT_CAT_COLOR);
+ if (!Algorithms.isEmpty(colorStr)) {
+ selectedColor = Integer.parseInt(colorStr);
+ }
+ isGpx = bundle.getBoolean(KEY_CTX_EDIT_GPX_FILE, false);
+ gpxCategories = bundle.getStringArrayList(KEY_CTX_EDIT_GPX_CATEGORIES);
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragment.java
index c24a29ff71..8b8fc64f5b 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragment.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragment.java
@@ -24,6 +24,7 @@ import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandApplication;
@@ -31,6 +32,7 @@ import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndFragment;
+import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.widgets.AutoCompleteTextViewEx;
import net.osmand.util.Algorithms;
@@ -136,9 +138,10 @@ public abstract class PointEditorFragment extends BaseOsmAndFragment {
@Override
public boolean onTouch(final View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
+ FragmentManager fragmentManager = getFragmentManager();
DialogFragment dialogFragment = createSelectCategoryDialog();
- if (dialogFragment != null) {
- dialogFragment.show(getChildFragmentManager(), SelectCategoryDialogFragment.TAG);
+ if (fragmentManager != null && dialogFragment != null) {
+ dialogFragment.show(fragmentManager, SelectFavoriteCategoryBottomSheet.class.getSimpleName());
}
return true;
}
@@ -179,7 +182,7 @@ public abstract class PointEditorFragment extends BaseOsmAndFragment {
protected DialogFragment createSelectCategoryDialog() {
PointEditor editor = getEditor();
if (editor != null) {
- return SelectCategoryDialogFragment.createInstance(editor.getFragmentTag());
+ return SelectFavoriteCategoryBottomSheet.createInstance(editor.getFragmentTag());
} else {
return null;
}
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
index 84a1d64714..c4799987f0 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java
@@ -38,6 +38,7 @@ import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -49,6 +50,7 @@ import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndFragment;
+import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.ColorDialogs;
import net.osmand.plus.mapcontextmenu.MapContextMenu;
@@ -190,9 +192,10 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment implemen
groupList.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- DialogFragment dialogFragment = createSelectCategoryDialog();
- if (dialogFragment != null) {
- dialogFragment.show(getChildFragmentManager(), SelectCategoryDialogFragment.TAG);
+ FragmentManager fragmentManager = getFragmentManager();
+ DialogFragment dialogFragment = createSelectCategoryDialog();
+ if (fragmentManager != null && dialogFragment != null) {
+ dialogFragment.show(fragmentManager, SelectFavoriteCategoryBottomSheet.class.getSimpleName());
}
}
});
@@ -732,7 +735,18 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment implemen
protected DialogFragment createSelectCategoryDialog() {
PointEditor editor = getEditor();
if (editor != null) {
- return SelectCategoryDialogFragment.createInstance(editor.getFragmentTag());
+ return SelectFavoriteCategoryBottomSheet.createInstance(editor.getFragmentTag());
+ } else {
+ return null;
+ }
+ }
+
+ @Nullable
+ protected AddNewFavoriteCategoryBottomSheet createAddCategoryDialog() {
+ PointEditor editor = getEditor();
+ if (editor != null) {
+ return AddNewFavoriteCategoryBottomSheet.createInstance(editor.getFragmentTag(), getCategories(),
+ !editor.getFragmentTag().equals(FavoritePointEditor.TAG));
} else {
return null;
}
@@ -887,8 +901,6 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment implemen
return true;
}
- ;
-
String getNameTextValue() {
EditText nameEdit = view.findViewById(R.id.name_edit);
return nameEdit.getText().toString().trim();
@@ -1006,12 +1018,10 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment implemen
holder.groupButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- PointEditor editor = getEditor();
- if (editor != null) {
- EditCategoryDialogFragment dialogFragment =
- EditCategoryDialogFragment.createInstance(editor.getFragmentTag(), getCategories(),
- !editor.getFragmentTag().equals(FavoritePointEditor.TAG));
- dialogFragment.show(requireActivity().getSupportFragmentManager(), EditCategoryDialogFragment.TAG);
+ FragmentManager fragmentManager = getFragmentManager();
+ DialogFragment dialogFragment = createAddCategoryDialog();
+ if (fragmentManager != null && dialogFragment != null) {
+ dialogFragment.show(fragmentManager, SelectFavoriteCategoryBottomSheet.class.getSimpleName());
}
}
});
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/RtePtEditorFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/RtePtEditorFragment.java
index 840ebba24f..9bbbb0ec34 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/RtePtEditorFragment.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/RtePtEditorFragment.java
@@ -23,7 +23,7 @@ public class RtePtEditorFragment extends WptPtEditorFragment {
@Override
protected DialogFragment createSelectCategoryDialog() {
PointEditor editor = getEditor();
- return editor != null ? SelectCategoryDialogFragment.createInstance(editor.getFragmentTag()) : null;
+ return editor != null ? SelectFavoriteCategoryBottomSheet.createInstance(editor.getFragmentTag()) : null;
}
public static void showInstance(final MapActivity mapActivity) {
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/SelectFavoriteCategoryBottomSheet.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/SelectFavoriteCategoryBottomSheet.java
new file mode 100644
index 0000000000..c3ee4169dc
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/SelectFavoriteCategoryBottomSheet.java
@@ -0,0 +1,232 @@
+package net.osmand.plus.mapcontextmenu.editors;
+
+import android.app.Activity;
+import android.graphics.PorterDuff;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.RadioButton;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.content.res.AppCompatResources;
+import androidx.appcompat.widget.AppCompatImageView;
+import androidx.core.content.ContextCompat;
+import androidx.core.graphics.drawable.DrawableCompat;
+import androidx.fragment.app.FragmentActivity;
+
+import net.osmand.AndroidUtils;
+import net.osmand.GPXUtilities;
+import net.osmand.plus.FavouritesDbHelper;
+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.MenuBottomSheetDialogFragment;
+import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
+import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription;
+import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
+import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem;
+import net.osmand.plus.helpers.AndroidUiHelper;
+import net.osmand.plus.helpers.FontCache;
+import net.osmand.plus.myplaces.AddNewTrackFolderBottomSheet;
+import net.osmand.util.Algorithms;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class SelectFavoriteCategoryBottomSheet extends MenuBottomSheetDialogFragment {
+
+ public static final String TAG = SelectFavoriteCategoryBottomSheet.class.getSimpleName();
+ private static final String KEY_CTX_SEL_CAT_EDITOR_TAG = "key_ctx_sel_cat_editor_tag";
+ private static String editorTag;
+ private OsmandApplication app;
+ private GPXUtilities.GPXFile gpxFile;
+ private Map gpxCategories;
+ private SelectFavoriteCategoryBottomSheet.CategorySelectionListener selectionListener;
+
+
+ private static Drawable getIcon(final Activity activity, int resId, int color) {
+ Drawable drawable = AppCompatResources.getDrawable(activity, resId);
+ if (drawable != null) {
+ drawable = DrawableCompat.wrap(drawable).mutate();
+ drawable.clearColorFilter();
+ drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
+ }
+ return drawable;
+ }
+
+ public static SelectFavoriteCategoryBottomSheet createInstance(String editorTag) {
+ SelectFavoriteCategoryBottomSheet fragment = new SelectFavoriteCategoryBottomSheet();
+ Bundle bundle = new Bundle();
+ bundle.putString(KEY_CTX_SEL_CAT_EDITOR_TAG, editorTag);
+ fragment.setArguments(bundle);
+ fragment.setRetainInstance(true);
+ return fragment;
+ }
+
+ public void setSelectionListener(SelectFavoriteCategoryBottomSheet.CategorySelectionListener selectionListener) {
+ this.selectionListener = selectionListener;
+ }
+
+ public GPXUtilities.GPXFile getGpxFile() {
+ return gpxFile;
+ }
+
+ public void setGpxFile(GPXUtilities.GPXFile gpxFile) {
+ this.gpxFile = gpxFile;
+ }
+
+ public void setGpxCategories(Map gpxCategories) {
+ this.gpxCategories = gpxCategories;
+ }
+
+ @Override
+ public void createMenuItems(Bundle savedInstanceState) {
+ app = requiredMyApplication();
+ if (savedInstanceState != null) {
+ restoreState(savedInstanceState);
+ } else if (getArguments() != null) {
+ restoreState(getArguments());
+ }
+
+ BaseBottomSheetItem titleItem = new BottomSheetItemWithDescription.Builder()
+ .setDescription(getString(R.string.select_category_descr))
+ .setTitle(getString(R.string.favorite_category_select))
+ .setLayoutId(R.layout.bottom_sheet_item_title_with_description)
+ .create();
+ items.add(titleItem);
+ final FragmentActivity activity = requireActivity();
+
+ View addNewCategoryView = UiUtilities.getInflater(app, nightMode).inflate(R.layout.bottom_sheet_item_with_descr_64dp, null);
+ addNewCategoryView.setMinimumHeight(getResources().getDimensionPixelSize(R.dimen.bottom_sheet_list_item_height));
+ TextView title = addNewCategoryView.findViewById(R.id.title);
+ Typeface typeface = FontCache.getRobotoMedium(getContext());
+ title.setTypeface(typeface);
+ AndroidUiHelper.updateVisibility(addNewCategoryView.findViewById(R.id.description), false);
+ BaseBottomSheetItem addNewFolderItem = new SimpleBottomSheetItem.Builder()
+ .setTitle(getString(R.string.favorite_category_add_new))
+ .setTitleColorId(nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light)
+ .setIcon(getActiveIcon(R.drawable.ic_action_folder_add))
+ .setLayoutId(R.layout.bottom_sheet_item_with_descr_64dp)
+ .setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ MapActivity mapActivity = (MapActivity) getActivity();
+ Set categories = gpxCategories != null ? gpxCategories.keySet() : null;
+ AddNewFavoriteCategoryBottomSheet fragment = AddNewFavoriteCategoryBottomSheet.createInstance(editorTag, categories, gpxFile != null);
+ if (mapActivity != null) {
+ fragment.show(mapActivity.getSupportFragmentManager(), AddNewTrackFolderBottomSheet.class.getName());
+ }
+ fragment.setSelectionListener(selectionListener);
+ dismiss();
+ }
+ })
+ .setCustomView(addNewCategoryView)
+ .create();
+ items.add(addNewFolderItem);
+
+ DividerItem dividerItem = new DividerItem(app);
+ dividerItem.setMargins(0, 0, 0, 0);
+ items.add(dividerItem);
+
+ View favoriteCategoryList = UiUtilities.getInflater(app, nightMode).inflate(R.layout.favorite_categories_dialog, null);
+ ScrollView scrollContainer = favoriteCategoryList.findViewById(R.id.scroll_container);
+ final int dp16 = AndroidUtils.dpToPx(app, 16f);
+ scrollContainer.setPadding(dp16,0, dp16,0);
+ LinearLayout favoriteCategoryContainer = favoriteCategoryList.findViewById(R.id.list_container);
+
+ final FavouritesDbHelper favoritesHelper = app.getFavorites();
+ if (gpxFile != null) {
+ if (gpxCategories != null) {
+ for (Map.Entry e : gpxCategories.entrySet()) {
+ String categoryName = e.getKey();
+ String favoriteCategoryCount = String.valueOf(e.getKey().length());
+ favoriteCategoryContainer.addView(createCategoryItem(activity, nightMode, categoryName, e.getValue(), favoriteCategoryCount, false));
+ }
+ }
+ } else {
+ List gs = favoritesHelper.getFavoriteGroups();
+ for (final FavouritesDbHelper.FavoriteGroup category : gs) {
+ String favoriteCategoryCount;
+ if (Algorithms.isEmpty(category.getPoints())) {
+ favoriteCategoryCount = app.getString(R.string.shared_string_empty);
+ } else {
+ favoriteCategoryCount = String.valueOf(category.getPoints().size());
+ }
+ favoriteCategoryContainer.addView(createCategoryItem(activity, nightMode, category.getDisplayName(getContext()),
+ category.getColor(), favoriteCategoryCount, !category.isVisible()));
+ }
+ }
+ items.add(new BaseBottomSheetItem.Builder()
+ .setCustomView(favoriteCategoryList)
+ .create());
+ }
+
+ private View createCategoryItem(@NonNull final Activity activity, boolean nightMode, final String categoryName, final int categoryColor, String categoryPointCount, boolean isHidden) {
+ View itemView = UiUtilities.getInflater(activity, nightMode).inflate(R.layout.bottom_sheet_item_with_descr_and_radio_btn, null);
+ final AppCompatImageView button = (AppCompatImageView) itemView.findViewById(R.id.icon);
+ final int dp8 = AndroidUtils.dpToPx(app, 8f);
+ button.setPadding(0,0, dp8,0);
+ LinearLayout descriptionContainer = itemView.findViewById(R.id.descriptionContainer);
+ descriptionContainer.setPadding(0, 0, 0, 0);
+ View divider = itemView.findViewById(R.id.divider_bottom);
+ divider.setVisibility(View.GONE);
+ itemView.setPadding(0, 0, 0, 0);
+ final RadioButton compoundButton = itemView.findViewById(R.id.compound_button);
+ int activeColorId = nightMode ?
+ R.color.active_color_primary_dark : R.color.active_color_primary_light;
+ int disableColorId = nightMode ?
+ R.color.icon_color_default_dark : R.color.icon_color_default_light;
+ UiUtilities.setupCompoundButton(nightMode, ContextCompat.getColor(app,
+ nightMode ? activeColorId : disableColorId), compoundButton);
+
+ if (isHidden) {
+ button.setImageResource(R.drawable.ic_action_hide);
+ } else {
+ if (categoryColor != 0) {
+ button.setImageDrawable(getIcon(activity, R.drawable.ic_action_folder, categoryColor));
+ } else {
+ button.setImageDrawable(getIcon(activity, R.drawable.ic_action_folder, ContextCompat.getColor(activity,
+ gpxFile != null ? R.color.gpx_color_point : R.color.color_favorite)));
+ }
+ }
+ String name = categoryName.length() == 0 ? getString(R.string.shared_string_favorites) : categoryName;
+ TextView text = itemView.findViewById(R.id.title);
+ TextView description = itemView.findViewById(R.id.description);
+ text.setText(name);
+ description.setText(String.valueOf(categoryPointCount));
+ descriptionContainer.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ FragmentActivity a = getActivity();
+ compoundButton.setSelected(true);
+ if (a instanceof MapActivity) {
+ PointEditor pointEditor = ((MapActivity) a).getContextMenu().getPointEditor(editorTag);
+ if (pointEditor != null) {
+ pointEditor.setCategory(categoryName, categoryColor);
+ }
+ if (selectionListener != null) {
+ selectionListener.onCategorySelected(categoryName, categoryColor);
+ }
+ }
+ dismiss();
+ }
+ });
+ return itemView;
+ }
+
+ public void restoreState(Bundle bundle) {
+ editorTag = bundle.getString(KEY_CTX_SEL_CAT_EDITOR_TAG);
+ }
+
+ public interface CategorySelectionListener {
+
+ void onCategorySelected(String category, int color);
+ }
+
+}
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java
index f5ef3033c8..a3efbca5ad 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java
@@ -67,7 +67,7 @@ public class WptPtEditorFragment extends PointEditorFragment {
protected DialogFragment createSelectCategoryDialog() {
WptPtEditor editor = getWptPtEditor();
if (editor != null) {
- SelectCategoryDialogFragment selectCategoryDialogFragment = SelectCategoryDialogFragment.createInstance(editor.getFragmentTag());
+ SelectFavoriteCategoryBottomSheet selectCategoryDialogFragment = SelectFavoriteCategoryBottomSheet.createInstance(editor.getFragmentTag());
GPXFile gpx = editor.getGpxFile();
if (gpx != null) {
selectCategoryDialogFragment.setGpxFile(gpx);
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragmentNew.java
index c948b5414e..456049403e 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragmentNew.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragmentNew.java
@@ -81,7 +81,7 @@ public class WptPtEditorFragmentNew extends PointEditorFragmentNew {
protected DialogFragment createSelectCategoryDialog() {
WptPtEditor editor = getWptPtEditor();
if (editor != null) {
- SelectCategoryDialogFragment selectCategoryDialogFragment = SelectCategoryDialogFragment.createInstance(editor.getFragmentTag());
+ SelectFavoriteCategoryBottomSheet selectCategoryDialogFragment = SelectFavoriteCategoryBottomSheet.createInstance(editor.getFragmentTag());
GPXFile gpx = editor.getGpxFile();
if (gpx != null) {
selectCategoryDialogFragment.setGpxFile(gpx);
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/RoutePreferencesMenu.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/RoutePreferencesMenu.java
index 005433cbe2..897de79b6c 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/RoutePreferencesMenu.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/RoutePreferencesMenu.java
@@ -36,7 +36,7 @@ import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.LocalRoutingPar
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.MuteSoundRoutingParameter;
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.OtherSettingsRoutingParameter;
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.VoiceGuidanceRoutingParameter;
-import net.osmand.plus.routing.RouteProvider;
+import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
@@ -373,13 +373,13 @@ public class RoutePreferencesMenu {
}
private void updateSpinnerItems(final TextView gpxSpinner) {
- RouteProvider.GPXRouteParamsBuilder rp = mapActivity.getRoutingHelper().getCurrentGPXRoute();
+ GPXRouteParamsBuilder rp = mapActivity.getRoutingHelper().getCurrentGPXRoute();
gpxSpinner.setText(rp == null ? mapActivity.getString(R.string.shared_string_none) :
new File(rp.getFile().path).getName());
}
private void showOptionsMenu(final TextView gpxSpinner) {
- RouteProvider.GPXRouteParamsBuilder rp = mapActivity.getRoutingHelper().getCurrentGPXRoute();
+ GPXRouteParamsBuilder rp = mapActivity.getRoutingHelper().getCurrentGPXRoute();
final PopupMenu optionsMenu = new PopupMenu(gpxSpinner.getContext(), gpxSpinner);
MenuItem item = optionsMenu.getMenu().add(
mapActivity.getString(R.string.shared_string_none));
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/ShareMenu.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/ShareMenu.java
index 53384024ff..5d040765b6 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/ShareMenu.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/ShareMenu.java
@@ -38,7 +38,7 @@ public class ShareMenu extends BaseMenuController {
MESSAGE(R.drawable.ic_action_message, R.string.shared_string_send),
CLIPBOARD(R.drawable.ic_action_copy, R.string.shared_string_copy),
ADDRESS(R.drawable.ic_action_street_name, R.string.copy_address),
- NAME(R.drawable.ic_action_copy, R.string.copy_location_name),
+ NAME(R.drawable.ic_action_copy, R.string.copy_poi_name),
COORDINATES(R.drawable.ic_action_copy, R.string.copy_coordinates),
GEO(R.drawable.ic_world_globe_dark, R.string.share_geo),
QR_CODE(R.drawable.ic_action_qrcode, R.string.shared_string_qr_code);
diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
index 5454febb86..74f636802a 100644
--- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
+++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java
@@ -2073,7 +2073,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private void startTrackNavigation() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
- if (editingCtx.hasRoute()) {
+ if (editingCtx.hasRoute() || editingCtx.hasChanges()) {
String trackName = getSuggestedFileName();
GPXFile gpx = editingCtx.exportGpx(trackName);
if (gpx != null) {
diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java
index fbe79b0681..ecd277b092 100644
--- a/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java
+++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java
@@ -22,6 +22,7 @@ import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapcontextmenu.editors.EditCategoryDialogFragment;
import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditor;
import net.osmand.plus.mapcontextmenu.editors.SelectCategoryDialogFragment;
+import net.osmand.plus.mapcontextmenu.editors.SelectFavoriteCategoryBottomSheet;
import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.quickaction.QuickActionType;
import net.osmand.plus.widgets.AutoCompleteTextViewEx;
@@ -175,13 +176,13 @@ public class FavoriteAction extends QuickAction {
@Override
public void onClick(final View view) {
- SelectCategoryDialogFragment dialogFragment = SelectCategoryDialogFragment.createInstance("");
+ SelectFavoriteCategoryBottomSheet dialogFragment = SelectFavoriteCategoryBottomSheet.createInstance("");
dialogFragment.show(
activity.getSupportFragmentManager(),
SelectCategoryDialogFragment.TAG);
- dialogFragment.setSelectionListener(new SelectCategoryDialogFragment.CategorySelectionListener() {
+ dialogFragment.setSelectionListener(new SelectFavoriteCategoryBottomSheet.CategorySelectionListener() {
@Override
public void onCategorySelected(String category, int color) {
@@ -191,12 +192,12 @@ public class FavoriteAction extends QuickAction {
}
});
- SelectCategoryDialogFragment dialogFragment = (SelectCategoryDialogFragment)
+ SelectFavoriteCategoryBottomSheet dialogFragment = (SelectFavoriteCategoryBottomSheet)
activity.getSupportFragmentManager().findFragmentByTag(SelectCategoryDialogFragment.TAG);
if (dialogFragment != null) {
- dialogFragment.setSelectionListener(new SelectCategoryDialogFragment.CategorySelectionListener() {
+ dialogFragment.setSelectionListener(new SelectFavoriteCategoryBottomSheet.CategorySelectionListener() {
@Override
public void onCategorySelected(String category, int color) {
@@ -211,7 +212,7 @@ public class FavoriteAction extends QuickAction {
if (dialog != null) {
- dialogFragment.setSelectionListener(new SelectCategoryDialogFragment.CategorySelectionListener() {
+ dialogFragment.setSelectionListener(new SelectFavoriteCategoryBottomSheet.CategorySelectionListener() {
@Override
public void onCategorySelected(String category, int color) {
diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/GPXAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/GPXAction.java
index 6fc153bb23..d0bfd98cbf 100644
--- a/OsmAnd/src/net/osmand/plus/quickaction/actions/GPXAction.java
+++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/GPXAction.java
@@ -16,6 +16,7 @@ import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapcontextmenu.editors.EditCategoryDialogFragment;
import net.osmand.plus.mapcontextmenu.editors.SelectCategoryDialogFragment;
+import net.osmand.plus.mapcontextmenu.editors.SelectFavoriteCategoryBottomSheet;
import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.quickaction.QuickActionType;
import net.osmand.plus.widgets.AutoCompleteTextViewEx;
@@ -119,13 +120,13 @@ public class GPXAction extends QuickAction {
@Override
public void onClick(final View view) {
- SelectCategoryDialogFragment dialogFragment = SelectCategoryDialogFragment.createInstance("");
+ SelectFavoriteCategoryBottomSheet dialogFragment = SelectFavoriteCategoryBottomSheet.createInstance("");
dialogFragment.show(
activity.getSupportFragmentManager(),
- SelectCategoryDialogFragment.TAG);
+ SelectFavoriteCategoryBottomSheet.TAG);
- dialogFragment.setSelectionListener(new SelectCategoryDialogFragment.CategorySelectionListener() {
+ dialogFragment.setSelectionListener(new SelectFavoriteCategoryBottomSheet.CategorySelectionListener() {
@Override
public void onCategorySelected(String category, int color) {
@@ -135,12 +136,12 @@ public class GPXAction extends QuickAction {
}
});
- SelectCategoryDialogFragment dialogFragment = (SelectCategoryDialogFragment)
+ SelectFavoriteCategoryBottomSheet dialogFragment = (SelectFavoriteCategoryBottomSheet)
activity.getSupportFragmentManager().findFragmentByTag(SelectCategoryDialogFragment.TAG);
if (dialogFragment != null) {
- dialogFragment.setSelectionListener(new SelectCategoryDialogFragment.CategorySelectionListener() {
+ dialogFragment.setSelectionListener(new SelectFavoriteCategoryBottomSheet.CategorySelectionListener() {
@Override
public void onCategorySelected(String category, int color) {
@@ -155,7 +156,7 @@ public class GPXAction extends QuickAction {
if (dialog != null) {
- dialogFragment.setSelectionListener(new SelectCategoryDialogFragment.CategorySelectionListener() {
+ dialogFragment.setSelectionListener(new SelectFavoriteCategoryBottomSheet.CategorySelectionListener() {
@Override
public void onCategorySelected(String category, int color) {
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
index 89afe180e2..e75efb2c25 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/ChooseRouteFragment.java
@@ -58,7 +58,7 @@ import net.osmand.plus.routepreparationmenu.RouteDetailsFragment.CumulativeInfo;
import net.osmand.plus.routepreparationmenu.RouteDetailsFragment.RouteDetailsFragmentListener;
import net.osmand.plus.routepreparationmenu.cards.PublicTransportCard;
import net.osmand.plus.routing.RouteDirectionInfo;
-import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
+import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.routing.TransportRoutingHelper;
import net.osmand.plus.settings.backend.OsmandSettings;
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
index 93b26b82a4..b5abb80b65 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java
@@ -58,8 +58,8 @@ 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.GPXRouteParams.GPXRouteParamsBuilder;
+import net.osmand.plus.routing.RouteService;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.track.TrackSelectSegmentBottomSheet;
@@ -224,7 +224,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
RoutingHelper routingHelper = app.getRoutingHelper();
GPXRouteParamsBuilder rparams = routingHelper.getCurrentGPXRoute();
- boolean osmandRouter = mode.getRouteService() == RouteProvider.RouteService.OSMAND;
+ boolean osmandRouter = mode.getRouteService() == RouteService.OSMAND;
if (rparams != null && osmandRouter) {
cardsContainer.addView(buildDividerView(cardsContainer, false));
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java
index f88f499125..2475d70f34 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenu.java
@@ -100,7 +100,7 @@ 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.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.routing.RoutingHelperUtils;
import net.osmand.plus.routing.TransportRoutingHelper;
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java
index 25c158a042..9e3c633544 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java
@@ -47,7 +47,8 @@ import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.OtherSettingsRo
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.RouteSimulationItem;
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.ShowAlongTheRouteItem;
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.TimeConditionalRoutingItem;
-import net.osmand.plus.routing.RouteProvider;
+import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
+import net.osmand.plus.routing.RouteService;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.CommonPreference;
@@ -501,7 +502,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
}
private BaseBottomSheetItem createGpxRoutingItem(final LocalRoutingParameter optionsItem) {
- RouteProvider.GPXRouteParamsBuilder routeParamsBuilder = mapActivity.getRoutingHelper().getCurrentGPXRoute();
+ GPXRouteParamsBuilder routeParamsBuilder = mapActivity.getRoutingHelper().getCurrentGPXRoute();
String description = null;
int descriptionColorId;
if (routeParamsBuilder == null) {
@@ -661,11 +662,11 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
private List getRoutingParameters(ApplicationMode applicationMode) {
List routingParameters;
- boolean osmandRouter = applicationMode.getRouteService() == RouteProvider.RouteService.OSMAND;
+ boolean osmandRouter = applicationMode.getRouteService() == RouteService.OSMAND;
if (!osmandRouter) {
- if (applicationMode.getRouteService() == RouteProvider.RouteService.STRAIGHT) {
+ if (applicationMode.getRouteService() == RouteService.STRAIGHT) {
routingParameters = AppModeOptions.STRAIGHT.routingParameters;
- } else if (applicationMode.getRouteService() == RouteProvider.RouteService.DIRECT_TO) {
+ } else if (applicationMode.getRouteService() == RouteService.DIRECT_TO) {
routingParameters = AppModeOptions.DIRECT_TO.routingParameters;
} else {
routingParameters = AppModeOptions.OTHER.routingParameters;
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RoutingOptionsHelper.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RoutingOptionsHelper.java
index 165ca20944..5f405c90b6 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RoutingOptionsHelper.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RoutingOptionsHelper.java
@@ -37,9 +37,8 @@ import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.helpers.FileNameTranslationHelper;
-import net.osmand.plus.routing.RouteProvider;
-import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
-import net.osmand.plus.routing.RouteProvider.RouteService;
+import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
+import net.osmand.plus.routing.RouteService;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.voice.JSMediaCommandPlayerImpl;
@@ -243,24 +242,25 @@ public class RoutingOptionsHelper {
TargetPointsHelper tg = app.getTargetPointsHelper();
List ps = rp.getPoints(app);
if (ps.size() > 0) {
+ TargetPoint pointToStart = tg.getPointToStart();
+ TargetPoint pointToNavigate = tg.getPointToNavigate();
if (rp.getFile().hasRoute()) {
tg.clearStartPoint(false);
Location finishLoc = ps.get(ps.size() - 1);
- TargetPoint pn = tg.getPointToNavigate();
- tg.navigateToPoint(new LatLon(finishLoc.getLatitude(), finishLoc.getLongitude()), false, -1, pn != null ? pn.getOriginalPointDescription() : null);
+ tg.navigateToPoint(new LatLon(finishLoc.getLatitude(), finishLoc.getLongitude()),
+ false, -1, pointToNavigate != null ? pointToNavigate.getOriginalPointDescription() : null);
tg.updateRouteAndRefresh(true);
} else {
Location first = ps.get(0);
Location end = ps.get(ps.size() - 1);
- TargetPoint pn = tg.getPointToNavigate();
boolean update = false;
- if (pn == null
- || MapUtils.getDistance(pn.point, new LatLon(first.getLatitude(), first.getLongitude())) < 10) {
+ if (pointToNavigate == null
+ || MapUtils.getDistance(pointToNavigate.point, new LatLon(first.getLatitude(), first.getLongitude())) < 10) {
tg.navigateToPoint(new LatLon(end.getLatitude(), end.getLongitude()), false, -1);
update = true;
}
- if (tg.getPointToStart() == null
- || MapUtils.getDistance(tg.getPointToStart().point,
+ if (pointToStart == null
+ || MapUtils.getDistance(pointToStart.point,
new LatLon(end.getLatitude(), end.getLongitude())) < 10) {
tg.setStartPoint(new LatLon(first.getLatitude(), first.getLongitude()), false, null);
update = true;
@@ -458,7 +458,7 @@ public class RoutingOptionsHelper {
public List getOsmandRouterParameters(ApplicationMode am) {
OsmandSettings settings = app.getSettings();
List list = new ArrayList();
- boolean osmandRouter = am.getRouteService() == RouteProvider.RouteService.OSMAND;
+ boolean osmandRouter = am.getRouteService() == RouteService.OSMAND;
if (!osmandRouter) {
list.add(new OtherLocalRoutingParameter(R.string.calculate_osmand_route_without_internet,
app.getString(R.string.calculate_osmand_route_without_internet), settings.GPX_ROUTE_CALC_OSMAND_PARTS.get()));
@@ -490,7 +490,7 @@ public class RoutingOptionsHelper {
}
public List getRoutingParametersInner(ApplicationMode am) {
- boolean osmandRouter = am.getRouteService() == RouteProvider.RouteService.OSMAND;
+ boolean osmandRouter = am.getRouteService() == RouteService.OSMAND;
if (!osmandRouter) {
return getOsmandRouterParameters(am);
}
@@ -1061,7 +1061,7 @@ public class RoutingOptionsHelper {
private List getRoutingParametersForProfileType(ApplicationMode appMode) {
if (appMode != null) {
- boolean osmandRouter = appMode.getRouteService() == RouteProvider.RouteService.OSMAND;
+ boolean osmandRouter = appMode.getRouteService() == RouteService.OSMAND;
if (!osmandRouter) {
return PermanentAppModeOptions.OTHER.routingParameters;
} else if (appMode.isDerivedRoutingFrom(ApplicationMode.CAR)) {
diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TrackEditCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TrackEditCard.java
index 646e2da386..e924b46aba 100644
--- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TrackEditCard.java
+++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TrackEditCard.java
@@ -20,7 +20,7 @@ import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
import net.osmand.plus.helpers.TrackSelectSegmentAdapter;
-import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
+import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.util.Algorithms;
import java.io.File;
diff --git a/OsmAnd/src/net/osmand/plus/routing/GPXRouteParams.java b/OsmAnd/src/net/osmand/plus/routing/GPXRouteParams.java
new file mode 100644
index 0000000000..9290195acd
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/routing/GPXRouteParams.java
@@ -0,0 +1,214 @@
+package net.osmand.plus.routing;
+
+import net.osmand.GPXUtilities.GPXFile;
+import net.osmand.GPXUtilities.Route;
+import net.osmand.GPXUtilities.WptPt;
+import net.osmand.Location;
+import net.osmand.PlatformUtil;
+import net.osmand.data.LatLon;
+import net.osmand.data.LocationPoint;
+import net.osmand.data.WptLocationPoint;
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.R;
+import net.osmand.plus.settings.backend.OsmandSettings;
+import net.osmand.router.RouteSegmentResult;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static net.osmand.plus.routing.RouteProvider.collectSegmentPointsFromGpx;
+import static net.osmand.router.RouteExporter.OSMAND_ROUTER_V2;
+
+public class GPXRouteParams {
+
+ private static final String OSMAND_ROUTER = "OsmAndRouter";
+
+ protected List wpt;
+ protected List route;
+ protected List directions;
+ protected List points = new ArrayList<>();
+ protected List segmentEndpoints = new ArrayList<>();
+ protected List routePoints = new ArrayList<>();
+ protected boolean reverse;
+ protected boolean passWholeRoute;
+ protected boolean calculateOsmAndRoute;
+ protected boolean useIntermediatePointsRTE;
+ protected boolean calculateOsmAndRouteParts;
+
+ boolean addMissingTurns = true;
+
+ public List getPoints() {
+ return points;
+ }
+
+ public List getWpt() {
+ return wpt;
+ }
+
+ public Location getStartPointForRoute() {
+ if (!points.isEmpty()) {
+ return points.get(0);
+ }
+ return null;
+ }
+
+ public Location getEndPointForRoute() {
+ if (!points.isEmpty()) {
+ return points.get(points.size());
+ }
+ return null;
+ }
+
+ public LatLon getLastPoint() {
+ if (!points.isEmpty()) {
+ Location l = points.get(points.size() - 1);
+ return new LatLon(l.getLatitude(), l.getLongitude());
+ }
+ return null;
+ }
+
+ public GPXRouteParams prepareGPXFile(GPXRouteParamsBuilder builder) {
+ GPXFile file = builder.file;
+ reverse = builder.reverse;
+ passWholeRoute = builder.passWholeRoute;
+ calculateOsmAndRouteParts = builder.calculateOsmAndRouteParts;
+ useIntermediatePointsRTE = builder.isUseIntermediatePointsRTE();
+ builder.calculateOsmAndRoute = false; // Disabled temporary builder.calculateOsmAndRoute;
+ if (!file.isPointsEmpty()) {
+ wpt = new ArrayList(file.getPoints().size());
+ for (WptPt w : file.getPoints()) {
+ wpt.add(new WptLocationPoint(w));
+ }
+ }
+ int selectedSegment = builder.getSelectedSegment();
+ if (OSMAND_ROUTER_V2.equals(file.author)) {
+ route = RouteProvider.parseOsmAndGPXRoute(points, file, segmentEndpoints, selectedSegment);
+ if (selectedSegment == -1) {
+ routePoints = file.getRoutePoints();
+ } else {
+ routePoints = file.getRoutePoints(selectedSegment);
+ }
+ if (reverse) {
+ Collections.reverse(points);
+ Collections.reverse(routePoints);
+ Collections.reverse(segmentEndpoints);
+ }
+ addMissingTurns = route != null && route.isEmpty();
+ } else if (file.isCloudmadeRouteFile() || OSMAND_ROUTER.equals(file.author)) {
+ directions = RouteProvider.parseOsmAndGPXRoute(points, file, segmentEndpoints,
+ OSMAND_ROUTER.equals(file.author), builder.leftSide, 10, selectedSegment);
+ if (OSMAND_ROUTER.equals(file.author) && file.hasRtePt()) {
+ // For files generated by OSMAND_ROUTER use directions contained unaltered
+ addMissingTurns = false;
+ }
+ if (reverse) {
+ // clear directions all turns should be recalculated
+ directions = null;
+ Collections.reverse(points);
+ Collections.reverse(segmentEndpoints);
+ addMissingTurns = true;
+ }
+ } else {
+ // first of all check tracks
+ if (!useIntermediatePointsRTE) {
+ collectSegmentPointsFromGpx(file, points, segmentEndpoints, selectedSegment);
+ }
+ if (points.isEmpty()) {
+ for (Route rte : file.routes) {
+ for (WptPt pt : rte.points) {
+ points.add(RouteProvider.createLocation(pt));
+ }
+ }
+ }
+ if (reverse) {
+ Collections.reverse(points);
+ Collections.reverse(segmentEndpoints);
+ }
+ }
+ return this;
+ }
+
+ public static class GPXRouteParamsBuilder {
+
+ private static final org.apache.commons.logging.Log log = PlatformUtil.getLog(GPXRouteParamsBuilder.class);
+
+ boolean calculateOsmAndRoute = false;
+ // parameters
+ private final GPXFile file;
+ private boolean reverse;
+ private boolean leftSide;
+ private boolean passWholeRoute;
+ private boolean calculateOsmAndRouteParts;
+ private int selectedSegment = -1;
+
+ public GPXRouteParamsBuilder(GPXFile file, OsmandSettings settings) {
+ leftSide = settings.DRIVING_REGION.get().leftHandDriving;
+ this.file = file;
+ }
+
+ public boolean isReverse() {
+ return reverse;
+ }
+
+ public boolean isCalculateOsmAndRouteParts() {
+ return calculateOsmAndRouteParts;
+ }
+
+ public void setCalculateOsmAndRouteParts(boolean calculateOsmAndRouteParts) {
+ this.calculateOsmAndRouteParts = calculateOsmAndRouteParts;
+ }
+
+ public boolean isUseIntermediatePointsRTE() {
+ return file.hasRtePt() && !file.hasTrkPt();
+ }
+
+ public boolean isCalculateOsmAndRoute() {
+ return calculateOsmAndRoute;
+ }
+
+ public void setCalculateOsmAndRoute(boolean calculateOsmAndRoute) {
+ this.calculateOsmAndRoute = calculateOsmAndRoute;
+ }
+
+ public int getSelectedSegment() {
+ return selectedSegment;
+ }
+
+ public void setSelectedSegment(int selectedSegment) {
+ this.selectedSegment = selectedSegment;
+ }
+
+ public void setPassWholeRoute(boolean passWholeRoute) {
+ this.passWholeRoute = passWholeRoute;
+ }
+
+ public boolean isPassWholeRoute() {
+ return passWholeRoute;
+ }
+
+ public GPXRouteParams build(OsmandApplication app) {
+ GPXRouteParams res = new GPXRouteParams();
+ try {
+ res.prepareGPXFile(this);
+ } catch (RuntimeException e) {
+ log.error(e.getMessage(), e);
+ app.showShortToastMessage(app.getString(R.string.gpx_parse_error) + " " + e.getMessage());
+ }
+ return res;
+ }
+
+ public void setReverse(boolean reverse) {
+ this.reverse = reverse;
+ }
+
+ public GPXFile getFile() {
+ return file;
+ }
+
+ public List getPoints(OsmandApplication app) {
+ GPXRouteParams copy = build(app);
+ return copy.getPoints();
+ }
+ }
+}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java b/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java
index 65e683a734..ca10de2812 100644
--- a/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java
+++ b/OsmAnd/src/net/osmand/plus/routing/GpxApproximator.java
@@ -7,7 +7,6 @@ import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher;
import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication;
-import net.osmand.plus.routing.RouteProvider.RoutingEnvironment;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.router.RouteCalculationProgress;
import net.osmand.router.RoutePlannerFrontEnd.GpxPoint;
diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationParams.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationParams.java
index 7b38b5c91a..0c4f2a4cb6 100644
--- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationParams.java
+++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationParams.java
@@ -4,7 +4,6 @@ import net.osmand.Location;
import net.osmand.data.LatLon;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.OsmandApplication;
-import net.osmand.plus.routing.RouteProvider.GPXRouteParams;
import net.osmand.router.RouteCalculationProgress;
import java.util.List;
diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
index e6efcc321f..7b7bd7d8d9 100644
--- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
+++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java
@@ -15,7 +15,6 @@ import net.osmand.data.QuadRect;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.routing.AlarmInfo.AlarmInfoType;
-import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.router.ExitInfo;
import net.osmand.router.RouteSegmentResult;
@@ -291,12 +290,16 @@ public class RouteCalculationResult {
}
public List getOriginalRoute(int startIndex) {
+ return getOriginalRoute(startIndex, segments.size());
+ }
+
+ public List getOriginalRoute(int startIndex, int endIndex) {
if (segments.size() == 0) {
return null;
}
- List list = new ArrayList();
+ List list = new ArrayList<>();
list.add(segments.get(startIndex++));
- for (int i = startIndex; i < segments.size(); i++) {
+ for (int i = startIndex; i < endIndex; i++) {
if (segments.get(i - 1) != segments.get(i)) {
list.add(segments.get(i));
}
diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java
index 19d0fcd3f7..e5974fc32d 100644
--- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java
+++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java
@@ -1,7 +1,6 @@
package net.osmand.plus.routing;
-import android.content.Context;
import android.os.Bundle;
import android.util.Base64;
@@ -16,8 +15,6 @@ import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.data.LatLon;
-import net.osmand.data.LocationPoint;
-import net.osmand.data.WptLocationPoint;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper;
@@ -25,6 +22,7 @@ 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.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings;
@@ -70,279 +68,14 @@ import javax.xml.parsers.ParserConfigurationException;
import btools.routingapp.IBRouterService;
-import static net.osmand.router.RouteExporter.OSMAND_ROUTER_V2;
-
public class RouteProvider {
+
private static final org.apache.commons.logging.Log log = PlatformUtil.getLog(RouteProvider.class);
- private static final String OSMAND_ROUTER = "OsmAndRouter";
private static final int MIN_DISTANCE_FOR_INSERTING_ROUTE_SEGMENT = 60;
private static final int ADDITIONAL_DISTANCE_FOR_START_POINT = 300;
private static final int MIN_STRAIGHT_DIST = 50000;
- public enum RouteService {
- OSMAND("OsmAnd (offline)"),
- BROUTER("BRouter (offline)"),
- STRAIGHT("Straight line"),
- DIRECT_TO("Direct To"),
- ONLINE("Online engine");
-
- private final String name;
-
- RouteService(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public boolean isOnline() {
- return this != OSMAND && this != BROUTER;
- }
-
- boolean isAvailable(OsmandApplication ctx) {
- if (this == BROUTER) {
- return ctx.getBRouterService() != null;
- }
- return true;
- }
-
- public static RouteService[] getAvailableRouters(OsmandApplication ctx) {
- List list = new ArrayList<>();
- for (RouteService r : values()) {
- if (r.isAvailable(ctx)) {
- list.add(r);
- }
- }
- return list.toArray(new RouteService[0]);
- }
- }
-
- public static class RoutingEnvironment {
- private RoutePlannerFrontEnd router;
- private RoutingContext ctx;
- private RoutingContext complexCtx;
- private PrecalculatedRouteDirection precalculated;
-
- public RoutingEnvironment(RoutePlannerFrontEnd router, RoutingContext ctx, RoutingContext complexCtx, PrecalculatedRouteDirection precalculated) {
- this.router = router;
- this.ctx = ctx;
- this.complexCtx = complexCtx;
- this.precalculated = precalculated;
- }
-
- public RoutePlannerFrontEnd getRouter() {
- return router;
- }
-
- public RoutingContext getCtx() {
- return ctx;
- }
-
- public RoutingContext getComplexCtx() {
- return complexCtx;
- }
-
- public PrecalculatedRouteDirection getPrecalculated() {
- return precalculated;
- }
- }
-
- public RouteProvider() {
- }
-
- public static class GPXRouteParamsBuilder {
- boolean calculateOsmAndRoute = false;
- // parameters
- private final GPXFile file;
- private boolean reverse;
- private boolean leftSide;
- private boolean passWholeRoute;
- private boolean calculateOsmAndRouteParts;
- private int selectedSegment = -1;
-
- public GPXRouteParamsBuilder(GPXFile file, OsmandSettings settings) {
- leftSide = settings.DRIVING_REGION.get().leftHandDriving;
- this.file = file;
- }
-
- public boolean isReverse() {
- return reverse;
- }
-
- public boolean isCalculateOsmAndRouteParts() {
- return calculateOsmAndRouteParts;
- }
-
- public void setCalculateOsmAndRouteParts(boolean calculateOsmAndRouteParts) {
- this.calculateOsmAndRouteParts = calculateOsmAndRouteParts;
- }
-
- public boolean isUseIntermediatePointsRTE() {
- return file.hasRtePt() && !file.hasTrkPt();
- }
-
- public boolean isCalculateOsmAndRoute() {
- return calculateOsmAndRoute;
- }
-
- public void setCalculateOsmAndRoute(boolean calculateOsmAndRoute) {
- this.calculateOsmAndRoute = calculateOsmAndRoute;
- }
-
- public int getSelectedSegment() {
- return selectedSegment;
- }
-
- public void setSelectedSegment(int selectedSegment) {
- this.selectedSegment = selectedSegment;
- }
-
- public void setPassWholeRoute(boolean passWholeRoute) {
- this.passWholeRoute = passWholeRoute;
- }
-
- public boolean isPassWholeRoute() {
- return passWholeRoute;
- }
-
- public GPXRouteParams build(OsmandApplication app) {
- GPXRouteParams res = new GPXRouteParams();
- try {
- res.prepareGPXFile(this);
- } catch (RuntimeException e) {
- log.error(e.getMessage(), e);
- app.showShortToastMessage(app.getString(R.string.gpx_parse_error) + " " + e.getMessage());
- }
- return res;
- }
-
- public void setReverse(boolean reverse) {
- this.reverse = reverse;
- }
-
- public GPXFile getFile() {
- return file;
- }
-
- public List getPoints(OsmandApplication app) {
- GPXRouteParams copy = build(app);
- return copy.getPoints();
- }
- }
-
- public static class GPXRouteParams {
- List points = new ArrayList<>();
- List directions;
- List route;
- List routePoints = new ArrayList<>();
- boolean reverse;
- boolean calculateOsmAndRoute;
- boolean passWholeRoute;
- boolean calculateOsmAndRouteParts;
- boolean useIntermediatePointsRTE;
- private List wpt;
-
- boolean addMissingTurns = true;
-
- public List getPoints() {
- return points;
- }
-
- public Location getStartPointForRoute(){
- if(!points.isEmpty()){
- return points.get(0);
- }
- return null;
- }
-
- public Location getEndPointForRoute(){
- if(!points.isEmpty()){
- return points.get(points.size());
- }
- return null;
- }
-
- public LatLon getLastPoint() {
- if(!points.isEmpty()){
- Location l = points.get(points.size() - 1);
- LatLon point = new LatLon(l.getLatitude(), l.getLongitude());
- return point;
- }
- return null;
- }
-
- public GPXRouteParams prepareGPXFile(GPXRouteParamsBuilder builder) {
- GPXFile file = builder.file;
- reverse = builder.reverse;
- passWholeRoute = builder.passWholeRoute;
- calculateOsmAndRouteParts = builder.calculateOsmAndRouteParts;
- useIntermediatePointsRTE = builder.isUseIntermediatePointsRTE();
- builder.calculateOsmAndRoute = false; // Disabled temporary builder.calculateOsmAndRoute;
- if (!file.isPointsEmpty()) {
- wpt = new ArrayList(file.getPoints().size());
- for(WptPt w : file.getPoints()) {
- wpt.add(new WptLocationPoint(w));
- }
- }
- int selectedSegment = builder.getSelectedSegment();
- if (OSMAND_ROUTER_V2.equals(file.author)) {
- route = parseOsmAndGPXRoute(points, file, selectedSegment);
- if (selectedSegment == -1) {
- routePoints = file.getRoutePoints();
- } else {
- routePoints = file.getRoutePoints(selectedSegment);
- }
- if (reverse) {
- Collections.reverse(points);
- Collections.reverse(routePoints);
- }
- addMissingTurns = route != null && route.isEmpty();
- } else if (file.isCloudmadeRouteFile() || OSMAND_ROUTER.equals(file.author)) {
- directions = parseOsmAndGPXRoute(points, file, OSMAND_ROUTER.equals(file.author), builder.leftSide, 10, selectedSegment);
- if (OSMAND_ROUTER.equals(file.author) && file.hasRtePt()) {
- // For files generated by OSMAND_ROUTER use directions contained unaltered
- addMissingTurns = false;
- }
- if (reverse) {
- // clear directions all turns should be recalculated
- directions = null;
- Collections.reverse(points);
- addMissingTurns = true;
- }
- } else {
- // first of all check tracks
- if (!useIntermediatePointsRTE) {
- List segments = file.getNonEmptyTrkSegments(false);
- if (selectedSegment != -1 && segments.size() > selectedSegment) {
- TrkSegment segment = segments.get(selectedSegment);
- for (WptPt p : segment.points) {
- points.add(createLocation(p));
- }
- } else {
- for (TrkSegment tkSeg : segments) {
- for (WptPt p : tkSeg.points) {
- points.add(createLocation(p));
- }
- }
- }
- }
- if (points.isEmpty()) {
- for (Route rte : file.routes) {
- for (WptPt pt : rte.points) {
- points.add(createLocation(pt));
- }
- }
- }
- if (reverse) {
- Collections.reverse(points);
- }
- }
- return this;
- }
- }
-
public static Location createLocation(WptPt pt){
Location loc = new Location("OsmandRouteProvider");
loc.setLatitude(pt.lat);
@@ -420,8 +153,9 @@ public class RouteProvider {
GPXRouteParams gpxParams = routeParams.gpxRoute;
boolean calcWholeRoute = routeParams.gpxRoute.passWholeRoute && (routeParams.previousToRecalculate == null || !routeParams.onlyStartPointChanged);
boolean calculateOsmAndRouteParts = gpxParams.calculateOsmAndRouteParts;
+ boolean reverseRoutePoints = gpxParams.reverse && gpxParams.routePoints.size() > 1;
List gpxRouteResult = routeParams.gpxRoute.route;
- if (gpxParams.reverse && gpxParams.routePoints.size() > 1) {
+ if (reverseRoutePoints) {
List gpxRouteLocations = new ArrayList<>();
List gpxRoute = new ArrayList<>();
WptPt firstGpxPoint = gpxParams.routePoints.get(0);
@@ -481,18 +215,25 @@ public class RouteProvider {
List firstSegmentRoute = null;
List lastSegmentRoute = null;
List gpxRoute;
+
if (nearestGpxPointInd > 0) {
nearestGpxLocation = gpxRouteLocations.get(nearestGpxPointInd);
- gpxRoute = result.getOriginalRoute(nearestGpxPointInd);
- if (gpxRoute.size() > 0) {
- gpxRoute.remove(0);
- }
- } else {
- if (!gpxRouteLocations.isEmpty()) {
- nearestGpxLocation = gpxRouteLocations.get(0);
- }
- gpxRoute = result.getOriginalRoute();
+ } else if (!gpxRouteLocations.isEmpty()) {
+ nearestGpxLocation = gpxRouteLocations.get(0);
}
+ if (calculateOsmAndRouteParts && !reverseRoutePoints && !Algorithms.isEmpty(gpxParams.segmentEndpoints)) {
+ gpxRoute = findRouteWithIntermediateSegments(routeParams, result, gpxRouteLocations, gpxParams.segmentEndpoints, nearestGpxPointInd);
+ } else {
+ if (nearestGpxPointInd > 0) {
+ gpxRoute = result.getOriginalRoute(nearestGpxPointInd);
+ if (gpxRoute.size() > 0) {
+ gpxRoute.remove(0);
+ }
+ } else {
+ gpxRoute = result.getOriginalRoute();
+ }
+ }
+
if (calculateOsmAndRouteParts
&& routeParams.start != null && nearestGpxLocation != null
&& nearestGpxLocation.distanceTo(routeParams.start) > MIN_DISTANCE_FOR_INSERTING_ROUTE_SEGMENT) {
@@ -534,6 +275,7 @@ public class RouteProvider {
}
final List inputDirections = gpxParams.directions;
List gpxDirections = calcDirections(startI, endI, inputDirections);
+ insertIntermediateSegments(routeParams, gpxRoute, gpxDirections, gpxParams.segmentEndpoints, calculateOsmAndRouteParts);
insertInitialSegment(routeParams, gpxRoute, gpxDirections, calculateOsmAndRouteParts);
insertFinalSegment(routeParams, gpxRoute, gpxDirections, calculateOsmAndRouteParts);
@@ -683,6 +425,68 @@ public class RouteProvider {
}
}
+ public void insertIntermediateSegments(RouteCalculationParams routeParams, List points, List directions,
+ List segmentEndpoints, boolean calculateOsmAndRouteParts) {
+ for (int i = 0; i < segmentEndpoints.size() - 1; i++) {
+ Location prevSegmentPoint = segmentEndpoints.get(i);
+ Location newSegmentPoint = segmentEndpoints.get(i + 1);
+
+ if (prevSegmentPoint.distanceTo(newSegmentPoint) <= MIN_DISTANCE_FOR_INSERTING_ROUTE_SEGMENT) {
+ continue;
+ }
+ int index = points.indexOf(newSegmentPoint);
+ if (calculateOsmAndRouteParts && index != -1 && points.contains(prevSegmentPoint)) {
+ LatLon end = new LatLon(newSegmentPoint.getLatitude(), newSegmentPoint.getLongitude());
+ RouteCalculationResult newRes = findOfflineRouteSegment(routeParams, prevSegmentPoint, end);
+
+ if (newRes != null && newRes.isCalculated()) {
+ List loct = newRes.getImmutableAllLocations();
+ List dt = newRes.getImmutableAllDirections();
+
+ for (RouteDirectionInfo directionInfo : dt) {
+ directionInfo.routePointOffset += points.size();
+ }
+ points.addAll(index, loct);
+ directions.addAll(dt);
+ }
+ }
+ }
+ }
+
+ public List findRouteWithIntermediateSegments(RouteCalculationParams routeParams,
+ RouteCalculationResult result,
+ List gpxRouteLocations,
+ List segmentEndpoints,
+ int nearestGpxPointInd) {
+ List newGpxRoute = new ArrayList<>();
+
+ int lastIndex = nearestGpxPointInd;
+ for (int i = 0; i < segmentEndpoints.size() - 1; i++) {
+ Location prevSegmentPoint = segmentEndpoints.get(i);
+ Location newSegmentPoint = segmentEndpoints.get(i + 1);
+
+ if (prevSegmentPoint.distanceTo(newSegmentPoint) <= MIN_DISTANCE_FOR_INSERTING_ROUTE_SEGMENT) {
+ continue;
+ }
+ int indexNew = findNearestGpxPointIndexFromRoute(gpxRouteLocations, newSegmentPoint, routeParams.gpxRoute.calculateOsmAndRouteParts);
+ int indexPrev = findNearestGpxPointIndexFromRoute(gpxRouteLocations, prevSegmentPoint, routeParams.gpxRoute.calculateOsmAndRouteParts);
+ if (indexPrev != -1 && indexPrev > nearestGpxPointInd && indexNew != -1) {
+ newGpxRoute.addAll(result.getOriginalRoute(lastIndex, indexPrev));
+ lastIndex = indexNew;
+
+ LatLon end = new LatLon(newSegmentPoint.getLatitude(), newSegmentPoint.getLongitude());
+ RouteCalculationResult newRes = findOfflineRouteSegment(routeParams, prevSegmentPoint, end);
+ List segmentResults = newRes.getOriginalRoute();
+ if (!Algorithms.isEmpty(segmentResults)) {
+ newGpxRoute.addAll(segmentResults);
+ }
+ }
+ }
+ newGpxRoute.addAll(result.getOriginalRoute(lastIndex));
+
+ return newGpxRoute;
+ }
+
private RouteCalculationResult findOfflineRouteSegment(RouteCalculationParams rParams, Location start,
LatLon end) {
RouteCalculationParams newParams = new RouteCalculationParams();
@@ -771,13 +575,6 @@ public class RouteProvider {
return nearestPointIndex;
}
- protected String getString(Context ctx, int resId){
- if(ctx == null){
- return ""; //$NON-NLS-1$
- }
- return ctx.getString(resId);
- }
-
public RoutingEnvironment getRoutingEnvironment(OsmandApplication ctx, ApplicationMode mode, LatLon start, LatLon end) throws IOException {
RouteCalculationParams params = new RouteCalculationParams();
params.ctx = ctx;
@@ -788,11 +585,11 @@ public class RouteProvider {
}
public List generateGpxPoints(RoutingEnvironment env, GpxRouteApproximation gctx, LocationsHolder locationsHolder) {
- return env.router.generateGpxPoints(gctx, locationsHolder);
+ return env.getRouter().generateGpxPoints(gctx, locationsHolder);
}
public GpxRouteApproximation calculateGpxPointsApproximation(RoutingEnvironment env, GpxRouteApproximation gctx, List points, ResultMatcher resultMatcher) throws IOException, InterruptedException {
- return env.router.searchGpxRoute(gctx, points, resultMatcher);
+ return env.getRouter().searchGpxRoute(gctx, points, resultMatcher);
}
protected RoutingEnvironment calculateRoutingEnvironment(RouteCalculationParams params, boolean calcGPXRoute, boolean skipComplex) throws IOException {
@@ -885,7 +682,7 @@ public class RouteProvider {
if (params.intermediates != null) {
inters = new ArrayList(params.intermediates);
}
- return calcOfflineRouteImpl(params, env.router, env.ctx, env.complexCtx, st, en, inters, env.precalculated);
+ return calcOfflineRouteImpl(params, env.getRouter(), env.getCtx(), env.getComplexCtx(), st, en, inters, env.getPrecalculated());
}
private RoutingConfiguration initOsmAndRoutingConfig(Builder config, final RouteCalculationParams params, OsmandSettings settings,
@@ -1012,7 +809,9 @@ public class RouteProvider {
return new RouteCalculationResult("Empty result");
}
- private static List parseOsmAndGPXRoute(List points, GPXFile gpxFile, int selectedSegment) {
+ protected static List parseOsmAndGPXRoute(List points, GPXFile gpxFile,
+ List segmentEndpoints,
+ int selectedSegment) {
List segments = gpxFile.getNonEmptyTrkSegments(false);
if (selectedSegment != -1 && segments.size() > selectedSegment) {
TrkSegment segment = segments.get(selectedSegment);
@@ -1022,37 +821,51 @@ public class RouteProvider {
RouteImporter routeImporter = new RouteImporter(segment);
return routeImporter.importRoute();
} else {
- for (TrkSegment ts : segments) {
- for (WptPt p : ts.points) {
- points.add(createLocation(p));
- }
- }
+ collectPointsFromSegments(segments, points, segmentEndpoints);
RouteImporter routeImporter = new RouteImporter(gpxFile);
return routeImporter.importRoute();
}
}
- private static List parseOsmAndGPXRoute(List points, GPXFile gpxFile, boolean osmandRouter,
- boolean leftSide, float defSpeed, int selectedSegment) {
+ protected static void collectSegmentPointsFromGpx(GPXFile gpxFile, List points,
+ List segmentEndpoints, int selectedSegment) {
+ List segments = gpxFile.getNonEmptyTrkSegments(false);
+ if (selectedSegment != -1 && segments.size() > selectedSegment) {
+ TrkSegment segment = segments.get(selectedSegment);
+ for (WptPt wptPt : segment.points) {
+ points.add(createLocation(wptPt));
+ }
+ } else {
+ collectPointsFromSegments(segments, points, segmentEndpoints);
+ }
+ }
+
+ protected static void collectPointsFromSegments(List segments, List points, List segmentEndpoints) {
+ Location lastPoint = null;
+ for (int i = 0; i < segments.size(); i++) {
+ TrkSegment segment = segments.get(i);
+ for (WptPt wptPt : segment.points) {
+ points.add(createLocation(wptPt));
+ }
+ if (i <= segments.size() - 1 && lastPoint != null) {
+ segmentEndpoints.add(lastPoint);
+ segmentEndpoints.add(points.get((points.size() - segment.points.size())));
+ }
+ lastPoint = points.get(points.size() - 1);
+ }
+ }
+
+ protected static List parseOsmAndGPXRoute(List points, GPXFile gpxFile,
+ List segmentEndpoints,
+ boolean osmandRouter, boolean leftSide,
+ float defSpeed, int selectedSegment) {
List directions = null;
if (!osmandRouter) {
for (WptPt pt : gpxFile.getPoints()) {
points.add(createLocation(pt));
}
} else {
- List segments = gpxFile.getNonEmptyTrkSegments(false);
- 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) {
- points.add(createLocation(p));
- }
- }
- }
+ collectSegmentPointsFromGpx(gpxFile, points, segmentEndpoints, selectedSegment);
}
float[] distanceToEnd = new float[points.size()];
for (int i = points.size() - 2; i >= 0; i--) {
@@ -1317,9 +1130,10 @@ public class RouteProvider {
bpars.putString("turnInstructionFormat", "osmand");
bpars.putString("acceptCompressedResult", "true");
- OsmandApplication ctx = (OsmandApplication) params.ctx;
+ OsmandApplication ctx = params.ctx;
List res = new ArrayList();
- List dir = new ArrayList<>();
+ List dir = new ArrayList<>();
+ List segmentEndpoints = new ArrayList<>();
IBRouterService brouterService = ctx.getBRouterService();
if (brouterService == null) {
@@ -1332,22 +1146,22 @@ public class RouteProvider {
boolean isZ64Encoded = gpxMessage.startsWith("ejY0"); // base-64 version of "z64"
- if (!( isZ64Encoded || gpxMessage.startsWith("<") ) ) {
+ if (!(isZ64Encoded || gpxMessage.startsWith("<"))) {
return new RouteCalculationResult(gpxMessage);
}
InputStream gpxStream;
- if ( isZ64Encoded ) {
- ByteArrayInputStream bais = new ByteArrayInputStream( Base64.decode(gpxMessage, Base64.DEFAULT) );
- bais.read( new byte[3] ); // skip prefix
- gpxStream = new GZIPInputStream( bais );
+ if (isZ64Encoded) {
+ ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(gpxMessage, Base64.DEFAULT));
+ bais.read(new byte[3]); // skip prefix
+ gpxStream = new GZIPInputStream(bais);
} else {
gpxStream = new ByteArrayInputStream(gpxMessage.getBytes("UTF-8"));
}
GPXFile gpxFile = GPXUtilities.loadGPXFile(gpxStream);
- dir = parseOsmAndGPXRoute(res, gpxFile, true, params.leftSide, params.mode.getDefaultSpeed(), -1);
+ dir = parseOsmAndGPXRoute(res, gpxFile, segmentEndpoints, true, params.leftSide, params.mode.getDefaultSpeed(), -1);
if (dir != null) {
addMissingTurns = false;
@@ -1390,6 +1204,4 @@ public class RouteProvider {
}
return new RouteCalculationResult(segments, computeDirections, params, null, false);
}
-
-
-}
+}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteRecalculationHelper.java b/OsmAnd/src/net/osmand/plus/routing/RouteRecalculationHelper.java
index 175003fe18..8fb8201dea 100644
--- a/OsmAnd/src/net/osmand/plus/routing/RouteRecalculationHelper.java
+++ b/OsmAnd/src/net/osmand/plus/routing/RouteRecalculationHelper.java
@@ -6,6 +6,7 @@ import net.osmand.Location;
import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
+import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.router.RouteCalculationProgress;
@@ -179,7 +180,7 @@ class RouteRecalculationHelper {
}
public void recalculateRouteInBackground(final Location start, final LatLon end, final List intermediates,
- final RouteProvider.GPXRouteParamsBuilder gpxRoute, final RouteCalculationResult previousRoute, boolean paramsChanged, boolean onlyStartPointChanged) {
+ final GPXRouteParamsBuilder gpxRoute, final RouteCalculationResult previousRoute, boolean paramsChanged, boolean onlyStartPointChanged) {
if (start == null || end == null) {
return;
}
@@ -207,7 +208,7 @@ class RouteRecalculationHelper {
params.mode = mode;
params.ctx = app;
boolean updateProgress = false;
- if (params.mode.getRouteService() == RouteProvider.RouteService.OSMAND) {
+ if (params.mode.getRouteService() == RouteService.OSMAND) {
params.calculationProgress = new RouteCalculationProgress();
updateProgress = true;
} else {
diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteService.java b/OsmAnd/src/net/osmand/plus/routing/RouteService.java
new file mode 100644
index 0000000000..6565b09106
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/routing/RouteService.java
@@ -0,0 +1,45 @@
+package net.osmand.plus.routing;
+
+import net.osmand.plus.OsmandApplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public enum RouteService {
+ OSMAND("OsmAnd (offline)"),
+ BROUTER("BRouter (offline)"),
+ STRAIGHT("Straight line"),
+ DIRECT_TO("Direct To"),
+ ONLINE("Online engine");
+
+ private final String name;
+
+ RouteService(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isOnline() {
+ return this != OSMAND && this != BROUTER;
+ }
+
+ boolean isAvailable(OsmandApplication ctx) {
+ if (this == BROUTER) {
+ return ctx.getBRouterService() != null;
+ }
+ return true;
+ }
+
+ public static RouteService[] getAvailableRouters(OsmandApplication ctx) {
+ List list = new ArrayList<>();
+ for (RouteService r : values()) {
+ if (r.isAvailable(ctx)) {
+ list.add(r);
+ }
+ }
+ return list.toArray(new RouteService[0]);
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingEnvironment.java b/OsmAnd/src/net/osmand/plus/routing/RoutingEnvironment.java
new file mode 100644
index 0000000000..15b484cc67
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/routing/RoutingEnvironment.java
@@ -0,0 +1,36 @@
+package net.osmand.plus.routing;
+
+import net.osmand.router.PrecalculatedRouteDirection;
+import net.osmand.router.RoutePlannerFrontEnd;
+import net.osmand.router.RoutingContext;
+
+public class RoutingEnvironment {
+
+ private RoutingContext ctx;
+ private RoutingContext complexCtx;
+ private RoutePlannerFrontEnd router;
+ private PrecalculatedRouteDirection precalculated;
+
+ public RoutingEnvironment(RoutePlannerFrontEnd router, RoutingContext ctx, RoutingContext complexCtx, PrecalculatedRouteDirection precalculated) {
+ this.router = router;
+ this.ctx = ctx;
+ this.complexCtx = complexCtx;
+ this.precalculated = precalculated;
+ }
+
+ public RoutePlannerFrontEnd getRouter() {
+ return router;
+ }
+
+ public RoutingContext getCtx() {
+ return ctx;
+ }
+
+ public RoutingContext getComplexCtx() {
+ return complexCtx;
+ }
+
+ public PrecalculatedRouteDirection getPrecalculated() {
+ return precalculated;
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java
index 1addb2f50a..8ab9405ee1 100644
--- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java
+++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java
@@ -20,9 +20,7 @@ import net.osmand.plus.TargetPointsHelper.TargetPoint;
import net.osmand.plus.helpers.enums.MetricsConstants;
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.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmAndAppCustomization.OsmAndAppCustomizationListener;
import net.osmand.plus.settings.backend.OsmandSettings;
@@ -670,9 +668,9 @@ public class RoutingHelper {
private static float getDefaultAllowedDeviation(OsmandSettings settings, ApplicationMode mode, float posTolerance) {
if (settings.DISABLE_OFFROUTE_RECALC.getModeValue(mode)) {
return -1.0f;
- } else if (mode.getRouteService() == RouteProvider.RouteService.DIRECT_TO) {
+ } else if (mode.getRouteService() == RouteService.DIRECT_TO) {
return -1.0f;
- } else if (mode.getRouteService() == RouteProvider.RouteService.STRAIGHT) {
+ } else if (mode.getRouteService() == RouteService.STRAIGHT) {
MetricsConstants mc = settings.METRIC_SYSTEM.getModeValue(mode);
if (mc == MetricsConstants.KILOMETERS_AND_METERS || mc == MetricsConstants.MILES_AND_METERS) {
return 500.f;
diff --git a/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java
index 08da774f27..637e3078e7 100644
--- a/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java
+++ b/OsmAnd/src/net/osmand/plus/routing/TransportRoutingHelper.java
@@ -18,7 +18,6 @@ import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.render.NativeOsmandLibrary;
import net.osmand.plus.routing.RouteCalculationParams.RouteCalculationResultListener;
-import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings;
diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java
index f707f82f88..3d84bcf850 100644
--- a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java
+++ b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java
@@ -14,7 +14,7 @@ import net.osmand.plus.R;
import net.osmand.plus.profiles.LocationIcon;
import net.osmand.plus.profiles.NavigationIcon;
import net.osmand.plus.profiles.ProfileIconColors;
-import net.osmand.plus.routing.RouteProvider.RouteService;
+import net.osmand.plus.routing.RouteService;
import net.osmand.util.Algorithms;
import org.apache.commons.lang3.StringUtils;
diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
index 2854520bbf..0762f453f1 100644
--- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
+++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java
@@ -48,7 +48,7 @@ import net.osmand.plus.profiles.NavigationIcon;
import net.osmand.plus.profiles.ProfileIconColors;
import net.osmand.plus.rastermaps.LayerTransparencySeekbarMode;
import net.osmand.plus.render.RendererRegistry;
-import net.osmand.plus.routing.RouteProvider.RouteService;
+import net.osmand.plus.routing.RouteService;
import net.osmand.plus.srtmplugin.TerrainMode;
import net.osmand.plus.views.layers.RadiusRulerControlLayer.RadiusRulerMode;
import net.osmand.plus.voice.CommandPlayer;
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/NavigationFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/NavigationFragment.java
index 8c45d89def..2e86899ee8 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/NavigationFragment.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/NavigationFragment.java
@@ -14,14 +14,13 @@ import net.osmand.plus.profiles.ProfileDataObject;
import net.osmand.plus.profiles.ProfileDataUtils;
import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet;
import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet.DialogMode;
-import net.osmand.plus.routing.RouteProvider.RouteService;
+import net.osmand.plus.routing.RouteService;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources;
import net.osmand.plus.profiles.SelectProfileBottomSheet;
import net.osmand.plus.profiles.SelectProfileBottomSheet.OnSelectProfileCallback;
-import net.osmand.plus.routing.RouteProvider;
import net.osmand.plus.settings.preferences.SwitchPreferenceEx;
import net.osmand.util.Algorithms;
@@ -151,17 +150,17 @@ public class NavigationFragment extends BaseSettingsFragment implements OnSelect
navigationType.setIcon(getActiveIcon(selectedRoutingProfileDataObject.getIconRes()));
ApplicationMode appMode = getSelectedAppMode();
- RouteProvider.RouteService routeService;
+ RouteService routeService;
if (profileKey.equals(RoutingProfilesResources.STRAIGHT_LINE_MODE.name())) {
- routeService = RouteProvider.RouteService.STRAIGHT;
+ routeService = RouteService.STRAIGHT;
} else if (profileKey.equals(RoutingProfilesResources.DIRECT_TO_MODE.name())) {
- routeService = RouteProvider.RouteService.DIRECT_TO;
+ routeService = RouteService.DIRECT_TO;
} else if (profileKey.equals(RoutingProfilesResources.BROUTER_MODE.name())) {
- routeService = RouteProvider.RouteService.BROUTER;
+ routeService = RouteService.BROUTER;
} else if (profileKey.startsWith(ONLINE_ROUTING_ENGINE_PREFIX)) {
routeService = RouteService.ONLINE;
} else {
- routeService = RouteProvider.RouteService.OSMAND;
+ routeService = RouteService.OSMAND;
}
appMode.setRouteService(routeService);
appMode.setRoutingProfile(profileKey);
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java
index 32136b8c09..309c89ec47 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java
@@ -26,6 +26,9 @@ import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
+import net.osmand.plus.activities.MapActivity;
+import net.osmand.plus.routing.RouteService;
+import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.UiUtilities.DialogButtonType;
@@ -1003,7 +1006,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
Integer customColor = null;
int iconRes;
String routingProfile;
- RouteProvider.RouteService routeService;
+ RouteService routeService;
NavigationIcon navigationIcon;
LocationIcon locationIcon;
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java
index d9290bdcbe..eb4f09f4aa 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java
@@ -31,6 +31,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
+import net.osmand.plus.routing.RouteService;
import net.osmand.plus.development.OsmandDevelopmentPlugin;
import net.osmand.plus.routing.RouteProvider;
import net.osmand.plus.routing.RoutingHelper;
@@ -229,7 +230,7 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP
fastRoute.setSummaryOn(R.string.shared_string_on);
fastRoute.setSummaryOff(R.string.shared_string_off);
- if (am.getRouteService() == RouteProvider.RouteService.OSMAND) {
+ if (am.getRouteService() == RouteService.OSMAND) {
GeneralRouter router = app.getRouter(am);
clearParameters();
if (router != null) {
@@ -308,10 +309,10 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP
}
}
setupTimeConditionalRoutingPref();
- } else if (am.getRouteService() == RouteProvider.RouteService.BROUTER) {
+ } else if (am.getRouteService() == RouteService.BROUTER) {
screen.addPreference(fastRoute);
setupTimeConditionalRoutingPref();
- } else if (am.getRouteService() == RouteProvider.RouteService.STRAIGHT) {
+ } else if (am.getRouteService() == RouteService.STRAIGHT) {
Preference straightAngle = new Preference(app.getApplicationContext());
straightAngle.setPersistent(false);
straightAngle.setKey(settings.ROUTE_STRAIGHT_ANGLE.getId());
diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java
index 3972b61c20..1b6f80848f 100644
--- a/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java
+++ b/OsmAnd/src/net/osmand/plus/settings/fragments/VehicleParametersFragment.java
@@ -25,8 +25,7 @@ import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.helpers.enums.SpeedConstants;
-import net.osmand.plus.routing.RouteProvider.RouteService;
-import net.osmand.plus.routing.RoutingHelper;
+import net.osmand.plus.routing.RouteService;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.StringPreference;
import net.osmand.plus.settings.bottomsheets.VehicleParametersBottomSheet;
diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java
index b72d4803fe..c674ea82ab 100644
--- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java
+++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java
@@ -81,7 +81,7 @@ import net.osmand.plus.myplaces.TrackActivityFragmentAdapter;
import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener;
-import net.osmand.plus.routing.RouteProvider;
+import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener;
import net.osmand.plus.track.TrackSelectSegmentBottomSheet.OnSegmentSelectedListener;
import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint;
@@ -1156,7 +1156,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
startNavigationForGPX(gpxFile, mapActivity.getMapActions());
- RouteProvider.GPXRouteParamsBuilder paramsBuilder = app.getRoutingHelper().getCurrentGPXRoute();
+ GPXRouteParamsBuilder paramsBuilder = app.getRoutingHelper().getCurrentGPXRoute();
if (paramsBuilder != null) {
paramsBuilder.setSelectedSegment(selectedSegment);
app.getRoutingHelper().onSettingsChanged(true);
diff --git a/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java
index f966b7d897..083d94f4ff 100644
--- a/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java
+++ b/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java
@@ -32,7 +32,7 @@ import net.osmand.plus.measurementtool.MeasurementToolFragment;
import net.osmand.plus.profiles.LocationIcon;
import net.osmand.plus.routing.RouteCalculationResult;
import net.osmand.plus.routing.RouteDirectionInfo;
-import net.osmand.plus.routing.RouteProvider;
+import net.osmand.plus.routing.RouteService;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.routing.TransportRoutingHelper;
import net.osmand.plus.views.OsmandMapLayer;
@@ -360,8 +360,8 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont
}
} else {
RouteCalculationResult route = helper.getRoute();
- boolean directTo = route.getRouteService() == RouteProvider.RouteService.DIRECT_TO;
- boolean straight = route.getRouteService() == RouteProvider.RouteService.STRAIGHT;
+ boolean directTo = route.getRouteService() == RouteService.DIRECT_TO;
+ boolean straight = route.getRouteService() == RouteService.STRAIGHT;
publicTransportRouteGeometry.clearRoute();
routeGeometry.updateRoute(tb, route);
if (directTo) {