Merge pull request #11054 from osmandapp/master

update test branch
This commit is contained in:
Hardy 2021-03-02 15:28:20 +01:00 committed by GitHub
commit 99b592762a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 1107 additions and 418 deletions

View file

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:osmand="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:focusable="true"
android:focusableInTouchMode="true" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/name_text_box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/favorite_category_name"
android:paddingStart="@dimen/content_padding"
android:paddingLeft="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
app:startIconDrawable="@drawable/ic_action_folder">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/name_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapSentences"
android:lineSpacingMultiplier="@dimen/bottom_sheet_text_spacing_multiplier" />
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<net.osmand.plus.widgets.TextViewEx
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:letterSpacing="@dimen/description_letter_spacing"
android:paddingLeft="@dimen/content_padding"
android:paddingTop="@dimen/context_menu_first_line_top_margin"
android:paddingRight="@dimen/content_padding"
android:paddingBottom="@dimen/context_menu_first_line_top_margin"
android:text="@string/select_color"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/color_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
android:letterSpacing="@dimen/description_letter_spacing"
android:paddingLeft="@dimen/content_padding"
android:paddingTop="@dimen/context_menu_first_line_top_margin"
android:paddingRight="@dimen/content_padding"
android:paddingBottom="@dimen/context_menu_first_line_top_margin"
android:text="@string/select_color"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium" />
</LinearLayout>
<LinearLayout
android:id="@+id/select_color"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding_small"
android:layout_marginLeft="@dimen/content_padding_small"
android:layout_marginTop="@dimen/context_menu_padding_margin_tiny"
android:layout_marginBottom="@dimen/content_padding_half"
android:orientation="horizontal" />
</LinearLayout>

View file

@ -9,6 +9,7 @@
<LinearLayout
android:layout_width="match_parent"
android:id="@+id/descriptionContainer"
android:layout_height="@dimen/bottom_sheet_large_list_item_height"
android:gravity="center_vertical"
android:orientation="horizontal"

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scroll_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/dialog_content_bottom_margin"

View file

@ -12,7 +12,9 @@
-->
<string name="copy_poi_name">Copy POI name</string>
<string name="track_recording_will_be_continued">The recording will be continued.</string>
<string name="select_category_descr">Select category or add new one</string>
<string name="map_widget_distance_by_tap">Distance by tap</string>
<string name="quick_action_coordinates_widget_descr">A toggle to show or hide the Coordinates widget on the map.</string>
<string name="quick_action_coordinates_widget_show">Show Coordinates widget</string>

View file

@ -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);
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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<String> 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<String> 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<Integer> 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);
}
}

View file

@ -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;
}

View file

@ -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) {
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());
}
}
});
@ -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());
}
}
});

View file

@ -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) {

View file

@ -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<String, Integer> 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<String, Integer> 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<String> 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<String, Integer> 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<FavouritesDbHelper.FavoriteGroup> 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);
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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));

View file

@ -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);

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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;

View file

@ -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));

View file

@ -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;

View file

@ -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<LocalRoutingParameter> getRoutingParameters(ApplicationMode applicationMode) {
List<String> 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;

View file

@ -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<Location> 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<LocalRoutingParameter> getOsmandRouterParameters(ApplicationMode am) {
OsmandSettings settings = app.getSettings();
List<LocalRoutingParameter> list = new ArrayList<LocalRoutingParameter>();
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<LocalRoutingParameter> 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<String> 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)) {

View file

@ -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;

View file

@ -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<LocationPoint> wpt;
protected List<RouteSegmentResult> route;
protected List<RouteDirectionInfo> directions;
protected List<Location> points = new ArrayList<>();
protected List<Location> segmentEndpoints = new ArrayList<>();
protected List<WptPt> routePoints = new ArrayList<>();
protected boolean reverse;
protected boolean passWholeRoute;
protected boolean calculateOsmAndRoute;
protected boolean useIntermediatePointsRTE;
protected boolean calculateOsmAndRouteParts;
boolean addMissingTurns = true;
public List<Location> getPoints() {
return points;
}
public List<LocationPoint> 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<LocationPoint>(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<Location> getPoints(OsmandApplication app) {
GPXRouteParams copy = build(app);
return copy.getPoints();
}
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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<RouteSegmentResult> getOriginalRoute(int startIndex) {
return getOriginalRoute(startIndex, segments.size());
}
public List<RouteSegmentResult> getOriginalRoute(int startIndex, int endIndex) {
if (segments.size() == 0) {
return null;
}
List<RouteSegmentResult> list = new ArrayList<RouteSegmentResult>();
List<RouteSegmentResult> 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));
}

View file

@ -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<RouteService> 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<Location> getPoints(OsmandApplication app) {
GPXRouteParams copy = build(app);
return copy.getPoints();
}
}
public static class GPXRouteParams {
List<Location> points = new ArrayList<>();
List<RouteDirectionInfo> directions;
List<RouteSegmentResult> route;
List<WptPt> routePoints = new ArrayList<>();
boolean reverse;
boolean calculateOsmAndRoute;
boolean passWholeRoute;
boolean calculateOsmAndRouteParts;
boolean useIntermediatePointsRTE;
private List<LocationPoint> wpt;
boolean addMissingTurns = true;
public List<Location> 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<LocationPoint>(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<TrkSegment> 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<RouteSegmentResult> gpxRouteResult = routeParams.gpxRoute.route;
if (gpxParams.reverse && gpxParams.routePoints.size() > 1) {
if (reverseRoutePoints) {
List<Location> gpxRouteLocations = new ArrayList<>();
List<RouteSegmentResult> gpxRoute = new ArrayList<>();
WptPt firstGpxPoint = gpxParams.routePoints.get(0);
@ -481,18 +215,25 @@ public class RouteProvider {
List<RouteSegmentResult> firstSegmentRoute = null;
List<RouteSegmentResult> lastSegmentRoute = null;
List<RouteSegmentResult> gpxRoute;
if (nearestGpxPointInd > 0) {
nearestGpxLocation = gpxRouteLocations.get(nearestGpxPointInd);
} 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 {
if (!gpxRouteLocations.isEmpty()) {
nearestGpxLocation = gpxRouteLocations.get(0);
}
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<RouteDirectionInfo> inputDirections = gpxParams.directions;
List<RouteDirectionInfo> 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<Location> points, List<RouteDirectionInfo> directions,
List<Location> 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<Location> loct = newRes.getImmutableAllLocations();
List<RouteDirectionInfo> dt = newRes.getImmutableAllDirections();
for (RouteDirectionInfo directionInfo : dt) {
directionInfo.routePointOffset += points.size();
}
points.addAll(index, loct);
directions.addAll(dt);
}
}
}
}
public List<RouteSegmentResult> findRouteWithIntermediateSegments(RouteCalculationParams routeParams,
RouteCalculationResult result,
List<Location> gpxRouteLocations,
List<Location> segmentEndpoints,
int nearestGpxPointInd) {
List<RouteSegmentResult> 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<RouteSegmentResult> 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<GpxPoint> 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<GpxPoint> points, ResultMatcher<GpxRouteApproximation> 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<LatLon>(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<RouteSegmentResult> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile, int selectedSegment) {
protected static List<RouteSegmentResult> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile,
List<Location> segmentEndpoints,
int selectedSegment) {
List<TrkSegment> 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<RouteDirectionInfo> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile, boolean osmandRouter,
boolean leftSide, float defSpeed, int selectedSegment) {
protected static void collectSegmentPointsFromGpx(GPXFile gpxFile, List<Location> points,
List<Location> segmentEndpoints, int selectedSegment) {
List<TrkSegment> 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<TrkSegment> segments, List<Location> points, List<Location> 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<RouteDirectionInfo> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile,
List<Location> segmentEndpoints,
boolean osmandRouter, boolean leftSide,
float defSpeed, int selectedSegment) {
List<RouteDirectionInfo> directions = null;
if (!osmandRouter) {
for (WptPt pt : gpxFile.getPoints()) {
points.add(createLocation(pt));
}
} else {
List<TrkSegment> 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<Location> res = new ArrayList<Location>();
List<RouteDirectionInfo> dir = new ArrayList<>();
List<Location> segmentEndpoints = new ArrayList<>();
IBRouterService brouterService = ctx.getBRouterService();
if (brouterService == null) {
@ -1347,7 +1161,7 @@ public class RouteProvider {
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);
}
}

View file

@ -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<LatLon> 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 {

View file

@ -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<RouteService> list = new ArrayList<>();
for (RouteService r : values()) {
if (r.isAvailable(ctx)) {
list.add(r);
}
}
return list.toArray(new RouteService[0]);
}
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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());

View file

@ -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;

View file

@ -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);

View file

@ -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) {