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 <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:id="@+id/descriptionContainer"
android:layout_height="@dimen/bottom_sheet_large_list_item_height" android:layout_height="@dimen/bottom_sheet_large_list_item_height"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal" android:orientation="horizontal"

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scroll_container"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingBottom="@dimen/dialog_content_bottom_margin" 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="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="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_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> <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.helpers.enums.MetricsConstants;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.mapmarkers.MapMarkersHelper; 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.plus.track.GpxSplitType;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -928,7 +928,7 @@ public class GpxSelectionHelper {
} }
public boolean isFollowTrack(OsmandApplication app) { public boolean isFollowTrack(OsmandApplication app) {
RouteProvider.GPXRouteParamsBuilder routeParams = app.getRoutingHelper().getCurrentGPXRoute(); GPXRouteParamsBuilder routeParams = app.getRoutingHelper().getCurrentGPXRoute();
if (routeParams != null) { if (routeParams != null) {
return gpxFile.path.equals(routeParams.getFile().path); return gpxFile.path.equals(routeParams.getFile().path);
} }

View file

@ -18,7 +18,7 @@ import net.osmand.GPXUtilities;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.GpxUiHelper; 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 net.osmand.plus.settings.backend.ApplicationMode;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -10,7 +10,7 @@ import net.osmand.data.LatLon;
import net.osmand.data.LocationPoint; import net.osmand.data.LocationPoint;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.plus.GeocodingLookupService.AddressLookupRequest; 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.RoutingHelper;
import net.osmand.plus.routing.RoutingHelperUtils; import net.osmand.plus.routing.RoutingHelperUtils;
import net.osmand.plus.settings.backend.ApplicationMode; 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.AdditionalActionsBottomSheetDialogFragment;
import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.mapcontextmenu.MapContextMenu;
import net.osmand.plus.mapcontextmenu.builders.cards.dialogs.ContextMenuCardDialogFragment; 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.DestinationReachedMenu;
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu; import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
import net.osmand.plus.mapmarkers.MapMarker; 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.profiles.ProfileDataUtils;
import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu;
import net.osmand.plus.routepreparationmenu.WaypointsFragment; 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.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings; 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;
import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.TargetPointsHelper.TargetPoint;
import net.osmand.plus.activities.MapActivity; 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.routing.RoutingHelper;
import net.osmand.plus.settings.backend.OsmandSettings; 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.core.content.ContextCompat;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
@ -31,6 +32,7 @@ import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.widgets.AutoCompleteTextViewEx; import net.osmand.plus.widgets.AutoCompleteTextViewEx;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -136,9 +138,10 @@ public abstract class PointEditorFragment extends BaseOsmAndFragment {
@Override @Override
public boolean onTouch(final View v, MotionEvent event) { public boolean onTouch(final View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) { if (event.getAction() == MotionEvent.ACTION_UP) {
FragmentManager fragmentManager = getFragmentManager();
DialogFragment dialogFragment = createSelectCategoryDialog(); DialogFragment dialogFragment = createSelectCategoryDialog();
if (dialogFragment != null) { if (fragmentManager != null && dialogFragment != null) {
dialogFragment.show(getChildFragmentManager(), SelectCategoryDialogFragment.TAG); dialogFragment.show(fragmentManager, SelectFavoriteCategoryBottomSheet.class.getSimpleName());
} }
return true; return true;
} }
@ -179,7 +182,7 @@ public abstract class PointEditorFragment extends BaseOsmAndFragment {
protected DialogFragment createSelectCategoryDialog() { protected DialogFragment createSelectCategoryDialog() {
PointEditor editor = getEditor(); PointEditor editor = getEditor();
if (editor != null) { if (editor != null) {
return SelectCategoryDialogFragment.createInstance(editor.getFragmentTag()); return SelectFavoriteCategoryBottomSheet.createInstance(editor.getFragmentTag());
} else { } else {
return null; return null;
} }

View file

@ -38,6 +38,7 @@ import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -49,6 +50,7 @@ import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.ColorDialogs; import net.osmand.plus.helpers.ColorDialogs;
import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.mapcontextmenu.MapContextMenu;
@ -190,9 +192,10 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment implemen
groupList.setOnClickListener(new View.OnClickListener() { groupList.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
DialogFragment dialogFragment = createSelectCategoryDialog(); FragmentManager fragmentManager = getFragmentManager();
if (dialogFragment != null) { DialogFragment dialogFragment = createSelectCategoryDialog();
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() { protected DialogFragment createSelectCategoryDialog() {
PointEditor editor = getEditor(); PointEditor editor = getEditor();
if (editor != null) { 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 { } else {
return null; return null;
} }
@ -887,8 +901,6 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment implemen
return true; return true;
} }
;
String getNameTextValue() { String getNameTextValue() {
EditText nameEdit = view.findViewById(R.id.name_edit); EditText nameEdit = view.findViewById(R.id.name_edit);
return nameEdit.getText().toString().trim(); return nameEdit.getText().toString().trim();
@ -1006,12 +1018,10 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment implemen
holder.groupButton.setOnClickListener(new View.OnClickListener() { holder.groupButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
PointEditor editor = getEditor(); FragmentManager fragmentManager = getFragmentManager();
if (editor != null) { DialogFragment dialogFragment = createAddCategoryDialog();
EditCategoryDialogFragment dialogFragment = if (fragmentManager != null && dialogFragment != null) {
EditCategoryDialogFragment.createInstance(editor.getFragmentTag(), getCategories(), dialogFragment.show(fragmentManager, SelectFavoriteCategoryBottomSheet.class.getSimpleName());
!editor.getFragmentTag().equals(FavoritePointEditor.TAG));
dialogFragment.show(requireActivity().getSupportFragmentManager(), EditCategoryDialogFragment.TAG);
} }
} }
}); });

View file

@ -23,7 +23,7 @@ public class RtePtEditorFragment extends WptPtEditorFragment {
@Override @Override
protected DialogFragment createSelectCategoryDialog() { protected DialogFragment createSelectCategoryDialog() {
PointEditor editor = getEditor(); 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) { 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() { protected DialogFragment createSelectCategoryDialog() {
WptPtEditor editor = getWptPtEditor(); WptPtEditor editor = getWptPtEditor();
if (editor != null) { if (editor != null) {
SelectCategoryDialogFragment selectCategoryDialogFragment = SelectCategoryDialogFragment.createInstance(editor.getFragmentTag()); SelectFavoriteCategoryBottomSheet selectCategoryDialogFragment = SelectFavoriteCategoryBottomSheet.createInstance(editor.getFragmentTag());
GPXFile gpx = editor.getGpxFile(); GPXFile gpx = editor.getGpxFile();
if (gpx != null) { if (gpx != null) {
selectCategoryDialogFragment.setGpxFile(gpx); selectCategoryDialogFragment.setGpxFile(gpx);

View file

@ -81,7 +81,7 @@ public class WptPtEditorFragmentNew extends PointEditorFragmentNew {
protected DialogFragment createSelectCategoryDialog() { protected DialogFragment createSelectCategoryDialog() {
WptPtEditor editor = getWptPtEditor(); WptPtEditor editor = getWptPtEditor();
if (editor != null) { if (editor != null) {
SelectCategoryDialogFragment selectCategoryDialogFragment = SelectCategoryDialogFragment.createInstance(editor.getFragmentTag()); SelectFavoriteCategoryBottomSheet selectCategoryDialogFragment = SelectFavoriteCategoryBottomSheet.createInstance(editor.getFragmentTag());
GPXFile gpx = editor.getGpxFile(); GPXFile gpx = editor.getGpxFile();
if (gpx != null) { if (gpx != null) {
selectCategoryDialogFragment.setGpxFile(gpx); 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.MuteSoundRoutingParameter;
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.OtherSettingsRoutingParameter; import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.OtherSettingsRoutingParameter;
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.VoiceGuidanceRoutingParameter; 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.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
@ -373,13 +373,13 @@ public class RoutePreferencesMenu {
} }
private void updateSpinnerItems(final TextView gpxSpinner) { 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) : gpxSpinner.setText(rp == null ? mapActivity.getString(R.string.shared_string_none) :
new File(rp.getFile().path).getName()); new File(rp.getFile().path).getName());
} }
private void showOptionsMenu(final TextView gpxSpinner) { 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); final PopupMenu optionsMenu = new PopupMenu(gpxSpinner.getContext(), gpxSpinner);
MenuItem item = optionsMenu.getMenu().add( MenuItem item = optionsMenu.getMenu().add(
mapActivity.getString(R.string.shared_string_none)); 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), MESSAGE(R.drawable.ic_action_message, R.string.shared_string_send),
CLIPBOARD(R.drawable.ic_action_copy, R.string.shared_string_copy), CLIPBOARD(R.drawable.ic_action_copy, R.string.shared_string_copy),
ADDRESS(R.drawable.ic_action_street_name, R.string.copy_address), 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), COORDINATES(R.drawable.ic_action_copy, R.string.copy_coordinates),
GEO(R.drawable.ic_world_globe_dark, R.string.share_geo), GEO(R.drawable.ic_world_globe_dark, R.string.share_geo),
QR_CODE(R.drawable.ic_action_qrcode, R.string.shared_string_qr_code); 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() { private void startTrackNavigation() {
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (mapActivity != null) { if (mapActivity != null) {
if (editingCtx.hasRoute()) { if (editingCtx.hasRoute() || editingCtx.hasChanges()) {
String trackName = getSuggestedFileName(); String trackName = getSuggestedFileName();
GPXFile gpx = editingCtx.exportGpx(trackName); GPXFile gpx = editingCtx.exportGpx(trackName);
if (gpx != null) { 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.EditCategoryDialogFragment;
import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditor; import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditor;
import net.osmand.plus.mapcontextmenu.editors.SelectCategoryDialogFragment; 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.QuickAction;
import net.osmand.plus.quickaction.QuickActionType; import net.osmand.plus.quickaction.QuickActionType;
import net.osmand.plus.widgets.AutoCompleteTextViewEx; import net.osmand.plus.widgets.AutoCompleteTextViewEx;
@ -175,13 +176,13 @@ public class FavoriteAction extends QuickAction {
@Override @Override
public void onClick(final View view) { public void onClick(final View view) {
SelectCategoryDialogFragment dialogFragment = SelectCategoryDialogFragment.createInstance(""); SelectFavoriteCategoryBottomSheet dialogFragment = SelectFavoriteCategoryBottomSheet.createInstance("");
dialogFragment.show( dialogFragment.show(
activity.getSupportFragmentManager(), activity.getSupportFragmentManager(),
SelectCategoryDialogFragment.TAG); SelectCategoryDialogFragment.TAG);
dialogFragment.setSelectionListener(new SelectCategoryDialogFragment.CategorySelectionListener() { dialogFragment.setSelectionListener(new SelectFavoriteCategoryBottomSheet.CategorySelectionListener() {
@Override @Override
public void onCategorySelected(String category, int color) { 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); activity.getSupportFragmentManager().findFragmentByTag(SelectCategoryDialogFragment.TAG);
if (dialogFragment != null) { if (dialogFragment != null) {
dialogFragment.setSelectionListener(new SelectCategoryDialogFragment.CategorySelectionListener() { dialogFragment.setSelectionListener(new SelectFavoriteCategoryBottomSheet.CategorySelectionListener() {
@Override @Override
public void onCategorySelected(String category, int color) { public void onCategorySelected(String category, int color) {
@ -211,7 +212,7 @@ public class FavoriteAction extends QuickAction {
if (dialog != null) { if (dialog != null) {
dialogFragment.setSelectionListener(new SelectCategoryDialogFragment.CategorySelectionListener() { dialogFragment.setSelectionListener(new SelectFavoriteCategoryBottomSheet.CategorySelectionListener() {
@Override @Override
public void onCategorySelected(String category, int color) { 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.activities.MapActivity;
import net.osmand.plus.mapcontextmenu.editors.EditCategoryDialogFragment; import net.osmand.plus.mapcontextmenu.editors.EditCategoryDialogFragment;
import net.osmand.plus.mapcontextmenu.editors.SelectCategoryDialogFragment; 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.QuickAction;
import net.osmand.plus.quickaction.QuickActionType; import net.osmand.plus.quickaction.QuickActionType;
import net.osmand.plus.widgets.AutoCompleteTextViewEx; import net.osmand.plus.widgets.AutoCompleteTextViewEx;
@ -119,13 +120,13 @@ public class GPXAction extends QuickAction {
@Override @Override
public void onClick(final View view) { public void onClick(final View view) {
SelectCategoryDialogFragment dialogFragment = SelectCategoryDialogFragment.createInstance(""); SelectFavoriteCategoryBottomSheet dialogFragment = SelectFavoriteCategoryBottomSheet.createInstance("");
dialogFragment.show( dialogFragment.show(
activity.getSupportFragmentManager(), activity.getSupportFragmentManager(),
SelectCategoryDialogFragment.TAG); SelectFavoriteCategoryBottomSheet.TAG);
dialogFragment.setSelectionListener(new SelectCategoryDialogFragment.CategorySelectionListener() { dialogFragment.setSelectionListener(new SelectFavoriteCategoryBottomSheet.CategorySelectionListener() {
@Override @Override
public void onCategorySelected(String category, int color) { 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); activity.getSupportFragmentManager().findFragmentByTag(SelectCategoryDialogFragment.TAG);
if (dialogFragment != null) { if (dialogFragment != null) {
dialogFragment.setSelectionListener(new SelectCategoryDialogFragment.CategorySelectionListener() { dialogFragment.setSelectionListener(new SelectFavoriteCategoryBottomSheet.CategorySelectionListener() {
@Override @Override
public void onCategorySelected(String category, int color) { public void onCategorySelected(String category, int color) {
@ -155,7 +156,7 @@ public class GPXAction extends QuickAction {
if (dialog != null) { if (dialog != null) {
dialogFragment.setSelectionListener(new SelectCategoryDialogFragment.CategorySelectionListener() { dialogFragment.setSelectionListener(new SelectFavoriteCategoryBottomSheet.CategorySelectionListener() {
@Override @Override
public void onCategorySelected(String category, int color) { 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.RouteDetailsFragment.RouteDetailsFragmentListener;
import net.osmand.plus.routepreparationmenu.cards.PublicTransportCard; import net.osmand.plus.routepreparationmenu.cards.PublicTransportCard;
import net.osmand.plus.routing.RouteDirectionInfo; 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.RoutingHelper;
import net.osmand.plus.routing.TransportRoutingHelper; import net.osmand.plus.routing.TransportRoutingHelper;
import net.osmand.plus.settings.backend.OsmandSettings; 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.TrackEditCard;
import net.osmand.plus.routepreparationmenu.cards.TracksToFollowCard; import net.osmand.plus.routepreparationmenu.cards.TracksToFollowCard;
import net.osmand.plus.routing.IRouteInformationListener; import net.osmand.plus.routing.IRouteInformationListener;
import net.osmand.plus.routing.RouteProvider; import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder; import net.osmand.plus.routing.RouteService;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.track.TrackSelectSegmentBottomSheet; import net.osmand.plus.track.TrackSelectSegmentBottomSheet;
@ -224,7 +224,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
RoutingHelper routingHelper = app.getRoutingHelper(); RoutingHelper routingHelper = app.getRoutingHelper();
GPXRouteParamsBuilder rparams = routingHelper.getCurrentGPXRoute(); GPXRouteParamsBuilder rparams = routingHelper.getCurrentGPXRoute();
boolean osmandRouter = mode.getRouteService() == RouteProvider.RouteService.OSMAND; boolean osmandRouter = mode.getRouteService() == RouteService.OSMAND;
if (rparams != null && osmandRouter) { if (rparams != null && osmandRouter) {
cardsContainer.addView(buildDividerView(cardsContainer, false)); 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.routepreparationmenu.cards.TracksCard;
import net.osmand.plus.routing.IRouteInformationListener; import net.osmand.plus.routing.IRouteInformationListener;
import net.osmand.plus.routing.RouteCalculationResult; 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.RoutingHelper;
import net.osmand.plus.routing.RoutingHelperUtils; import net.osmand.plus.routing.RoutingHelperUtils;
import net.osmand.plus.routing.TransportRoutingHelper; 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.RouteSimulationItem;
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.ShowAlongTheRouteItem; import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.ShowAlongTheRouteItem;
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.TimeConditionalRoutingItem; 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.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.CommonPreference;
@ -501,7 +502,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
} }
private BaseBottomSheetItem createGpxRoutingItem(final LocalRoutingParameter optionsItem) { private BaseBottomSheetItem createGpxRoutingItem(final LocalRoutingParameter optionsItem) {
RouteProvider.GPXRouteParamsBuilder routeParamsBuilder = mapActivity.getRoutingHelper().getCurrentGPXRoute(); GPXRouteParamsBuilder routeParamsBuilder = mapActivity.getRoutingHelper().getCurrentGPXRoute();
String description = null; String description = null;
int descriptionColorId; int descriptionColorId;
if (routeParamsBuilder == null) { if (routeParamsBuilder == null) {
@ -661,11 +662,11 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
private List<LocalRoutingParameter> getRoutingParameters(ApplicationMode applicationMode) { private List<LocalRoutingParameter> getRoutingParameters(ApplicationMode applicationMode) {
List<String> routingParameters; List<String> routingParameters;
boolean osmandRouter = applicationMode.getRouteService() == RouteProvider.RouteService.OSMAND; boolean osmandRouter = applicationMode.getRouteService() == RouteService.OSMAND;
if (!osmandRouter) { if (!osmandRouter) {
if (applicationMode.getRouteService() == RouteProvider.RouteService.STRAIGHT) { if (applicationMode.getRouteService() == RouteService.STRAIGHT) {
routingParameters = AppModeOptions.STRAIGHT.routingParameters; routingParameters = AppModeOptions.STRAIGHT.routingParameters;
} else if (applicationMode.getRouteService() == RouteProvider.RouteService.DIRECT_TO) { } else if (applicationMode.getRouteService() == RouteService.DIRECT_TO) {
routingParameters = AppModeOptions.DIRECT_TO.routingParameters; routingParameters = AppModeOptions.DIRECT_TO.routingParameters;
} else { } else {
routingParameters = AppModeOptions.OTHER.routingParameters; 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.DownloadActivity;
import net.osmand.plus.download.DownloadActivityType; import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.helpers.FileNameTranslationHelper; import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.routing.RouteProvider; import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder; import net.osmand.plus.routing.RouteService;
import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.voice.JSMediaCommandPlayerImpl; import net.osmand.plus.voice.JSMediaCommandPlayerImpl;
@ -243,24 +242,25 @@ public class RoutingOptionsHelper {
TargetPointsHelper tg = app.getTargetPointsHelper(); TargetPointsHelper tg = app.getTargetPointsHelper();
List<Location> ps = rp.getPoints(app); List<Location> ps = rp.getPoints(app);
if (ps.size() > 0) { if (ps.size() > 0) {
TargetPoint pointToStart = tg.getPointToStart();
TargetPoint pointToNavigate = tg.getPointToNavigate();
if (rp.getFile().hasRoute()) { if (rp.getFile().hasRoute()) {
tg.clearStartPoint(false); tg.clearStartPoint(false);
Location finishLoc = ps.get(ps.size() - 1); Location finishLoc = ps.get(ps.size() - 1);
TargetPoint pn = tg.getPointToNavigate(); tg.navigateToPoint(new LatLon(finishLoc.getLatitude(), finishLoc.getLongitude()),
tg.navigateToPoint(new LatLon(finishLoc.getLatitude(), finishLoc.getLongitude()), false, -1, pn != null ? pn.getOriginalPointDescription() : null); false, -1, pointToNavigate != null ? pointToNavigate.getOriginalPointDescription() : null);
tg.updateRouteAndRefresh(true); tg.updateRouteAndRefresh(true);
} else { } else {
Location first = ps.get(0); Location first = ps.get(0);
Location end = ps.get(ps.size() - 1); Location end = ps.get(ps.size() - 1);
TargetPoint pn = tg.getPointToNavigate();
boolean update = false; boolean update = false;
if (pn == null if (pointToNavigate == null
|| MapUtils.getDistance(pn.point, new LatLon(first.getLatitude(), first.getLongitude())) < 10) { || MapUtils.getDistance(pointToNavigate.point, new LatLon(first.getLatitude(), first.getLongitude())) < 10) {
tg.navigateToPoint(new LatLon(end.getLatitude(), end.getLongitude()), false, -1); tg.navigateToPoint(new LatLon(end.getLatitude(), end.getLongitude()), false, -1);
update = true; update = true;
} }
if (tg.getPointToStart() == null if (pointToStart == null
|| MapUtils.getDistance(tg.getPointToStart().point, || MapUtils.getDistance(pointToStart.point,
new LatLon(end.getLatitude(), end.getLongitude())) < 10) { new LatLon(end.getLatitude(), end.getLongitude())) < 10) {
tg.setStartPoint(new LatLon(first.getLatitude(), first.getLongitude()), false, null); tg.setStartPoint(new LatLon(first.getLatitude(), first.getLongitude()), false, null);
update = true; update = true;
@ -458,7 +458,7 @@ public class RoutingOptionsHelper {
public List<LocalRoutingParameter> getOsmandRouterParameters(ApplicationMode am) { public List<LocalRoutingParameter> getOsmandRouterParameters(ApplicationMode am) {
OsmandSettings settings = app.getSettings(); OsmandSettings settings = app.getSettings();
List<LocalRoutingParameter> list = new ArrayList<LocalRoutingParameter>(); List<LocalRoutingParameter> list = new ArrayList<LocalRoutingParameter>();
boolean osmandRouter = am.getRouteService() == RouteProvider.RouteService.OSMAND; boolean osmandRouter = am.getRouteService() == RouteService.OSMAND;
if (!osmandRouter) { if (!osmandRouter) {
list.add(new OtherLocalRoutingParameter(R.string.calculate_osmand_route_without_internet, 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())); 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) { public List<LocalRoutingParameter> getRoutingParametersInner(ApplicationMode am) {
boolean osmandRouter = am.getRouteService() == RouteProvider.RouteService.OSMAND; boolean osmandRouter = am.getRouteService() == RouteService.OSMAND;
if (!osmandRouter) { if (!osmandRouter) {
return getOsmandRouterParameters(am); return getOsmandRouterParameters(am);
} }
@ -1061,7 +1061,7 @@ public class RoutingOptionsHelper {
private List<String> getRoutingParametersForProfileType(ApplicationMode appMode) { private List<String> getRoutingParametersForProfileType(ApplicationMode appMode) {
if (appMode != null) { if (appMode != null) {
boolean osmandRouter = appMode.getRouteService() == RouteProvider.RouteService.OSMAND; boolean osmandRouter = appMode.getRouteService() == RouteService.OSMAND;
if (!osmandRouter) { if (!osmandRouter) {
return PermanentAppModeOptions.OTHER.routingParameters; return PermanentAppModeOptions.OTHER.routingParameters;
} else if (appMode.isDerivedRoutingFrom(ApplicationMode.CAR)) { } 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;
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
import net.osmand.plus.helpers.TrackSelectSegmentAdapter; 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 net.osmand.util.Algorithms;
import java.io.File; 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.ResultMatcher;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.routing.RouteProvider.RoutingEnvironment;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.router.RouteCalculationProgress; import net.osmand.router.RouteCalculationProgress;
import net.osmand.router.RoutePlannerFrontEnd.GpxPoint; import net.osmand.router.RoutePlannerFrontEnd.GpxPoint;

View file

@ -4,7 +4,6 @@ import net.osmand.Location;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.routing.RouteProvider.GPXRouteParams;
import net.osmand.router.RouteCalculationProgress; import net.osmand.router.RouteCalculationProgress;
import java.util.List; import java.util.List;

View file

@ -15,7 +15,6 @@ import net.osmand.data.QuadRect;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.routing.AlarmInfo.AlarmInfoType; import net.osmand.plus.routing.AlarmInfo.AlarmInfoType;
import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.router.ExitInfo; import net.osmand.router.ExitInfo;
import net.osmand.router.RouteSegmentResult; import net.osmand.router.RouteSegmentResult;
@ -291,12 +290,16 @@ public class RouteCalculationResult {
} }
public List<RouteSegmentResult> getOriginalRoute(int startIndex) { public List<RouteSegmentResult> getOriginalRoute(int startIndex) {
return getOriginalRoute(startIndex, segments.size());
}
public List<RouteSegmentResult> getOriginalRoute(int startIndex, int endIndex) {
if (segments.size() == 0) { if (segments.size() == 0) {
return null; return null;
} }
List<RouteSegmentResult> list = new ArrayList<RouteSegmentResult>(); List<RouteSegmentResult> list = new ArrayList<>();
list.add(segments.get(startIndex++)); 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)) { if (segments.get(i - 1) != segments.get(i)) {
list.add(segments.get(i)); list.add(segments.get(i));
} }

View file

@ -1,7 +1,6 @@
package net.osmand.plus.routing; package net.osmand.plus.routing;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Base64; import android.util.Base64;
@ -16,8 +15,6 @@ import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher; import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.LocationPoint;
import net.osmand.data.WptLocationPoint;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper;
@ -25,6 +22,7 @@ import net.osmand.plus.TargetPointsHelper.TargetPoint;
import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse;
import net.osmand.plus.render.NativeOsmandLibrary; 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.ApplicationMode;
import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
@ -70,279 +68,14 @@ import javax.xml.parsers.ParserConfigurationException;
import btools.routingapp.IBRouterService; import btools.routingapp.IBRouterService;
import static net.osmand.router.RouteExporter.OSMAND_ROUTER_V2;
public class RouteProvider { public class RouteProvider {
private static final org.apache.commons.logging.Log log = PlatformUtil.getLog(RouteProvider.class); 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 MIN_DISTANCE_FOR_INSERTING_ROUTE_SEGMENT = 60;
private static final int ADDITIONAL_DISTANCE_FOR_START_POINT = 300; private static final int ADDITIONAL_DISTANCE_FOR_START_POINT = 300;
private static final int MIN_STRAIGHT_DIST = 50000; 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){ public static Location createLocation(WptPt pt){
Location loc = new Location("OsmandRouteProvider"); Location loc = new Location("OsmandRouteProvider");
loc.setLatitude(pt.lat); loc.setLatitude(pt.lat);
@ -420,8 +153,9 @@ public class RouteProvider {
GPXRouteParams gpxParams = routeParams.gpxRoute; GPXRouteParams gpxParams = routeParams.gpxRoute;
boolean calcWholeRoute = routeParams.gpxRoute.passWholeRoute && (routeParams.previousToRecalculate == null || !routeParams.onlyStartPointChanged); boolean calcWholeRoute = routeParams.gpxRoute.passWholeRoute && (routeParams.previousToRecalculate == null || !routeParams.onlyStartPointChanged);
boolean calculateOsmAndRouteParts = gpxParams.calculateOsmAndRouteParts; boolean calculateOsmAndRouteParts = gpxParams.calculateOsmAndRouteParts;
boolean reverseRoutePoints = gpxParams.reverse && gpxParams.routePoints.size() > 1;
List<RouteSegmentResult> gpxRouteResult = routeParams.gpxRoute.route; List<RouteSegmentResult> gpxRouteResult = routeParams.gpxRoute.route;
if (gpxParams.reverse && gpxParams.routePoints.size() > 1) { if (reverseRoutePoints) {
List<Location> gpxRouteLocations = new ArrayList<>(); List<Location> gpxRouteLocations = new ArrayList<>();
List<RouteSegmentResult> gpxRoute = new ArrayList<>(); List<RouteSegmentResult> gpxRoute = new ArrayList<>();
WptPt firstGpxPoint = gpxParams.routePoints.get(0); WptPt firstGpxPoint = gpxParams.routePoints.get(0);
@ -481,18 +215,25 @@ public class RouteProvider {
List<RouteSegmentResult> firstSegmentRoute = null; List<RouteSegmentResult> firstSegmentRoute = null;
List<RouteSegmentResult> lastSegmentRoute = null; List<RouteSegmentResult> lastSegmentRoute = null;
List<RouteSegmentResult> gpxRoute; List<RouteSegmentResult> gpxRoute;
if (nearestGpxPointInd > 0) { if (nearestGpxPointInd > 0) {
nearestGpxLocation = gpxRouteLocations.get(nearestGpxPointInd); nearestGpxLocation = gpxRouteLocations.get(nearestGpxPointInd);
gpxRoute = result.getOriginalRoute(nearestGpxPointInd); } else if (!gpxRouteLocations.isEmpty()) {
if (gpxRoute.size() > 0) { nearestGpxLocation = gpxRouteLocations.get(0);
gpxRoute.remove(0);
}
} else {
if (!gpxRouteLocations.isEmpty()) {
nearestGpxLocation = gpxRouteLocations.get(0);
}
gpxRoute = result.getOriginalRoute();
} }
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 if (calculateOsmAndRouteParts
&& routeParams.start != null && nearestGpxLocation != null && routeParams.start != null && nearestGpxLocation != null
&& nearestGpxLocation.distanceTo(routeParams.start) > MIN_DISTANCE_FOR_INSERTING_ROUTE_SEGMENT) { && nearestGpxLocation.distanceTo(routeParams.start) > MIN_DISTANCE_FOR_INSERTING_ROUTE_SEGMENT) {
@ -534,6 +275,7 @@ public class RouteProvider {
} }
final List<RouteDirectionInfo> inputDirections = gpxParams.directions; final List<RouteDirectionInfo> inputDirections = gpxParams.directions;
List<RouteDirectionInfo> gpxDirections = calcDirections(startI, endI, inputDirections); List<RouteDirectionInfo> gpxDirections = calcDirections(startI, endI, inputDirections);
insertIntermediateSegments(routeParams, gpxRoute, gpxDirections, gpxParams.segmentEndpoints, calculateOsmAndRouteParts);
insertInitialSegment(routeParams, gpxRoute, gpxDirections, calculateOsmAndRouteParts); insertInitialSegment(routeParams, gpxRoute, gpxDirections, calculateOsmAndRouteParts);
insertFinalSegment(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, private RouteCalculationResult findOfflineRouteSegment(RouteCalculationParams rParams, Location start,
LatLon end) { LatLon end) {
RouteCalculationParams newParams = new RouteCalculationParams(); RouteCalculationParams newParams = new RouteCalculationParams();
@ -771,13 +575,6 @@ public class RouteProvider {
return nearestPointIndex; 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 { public RoutingEnvironment getRoutingEnvironment(OsmandApplication ctx, ApplicationMode mode, LatLon start, LatLon end) throws IOException {
RouteCalculationParams params = new RouteCalculationParams(); RouteCalculationParams params = new RouteCalculationParams();
params.ctx = ctx; params.ctx = ctx;
@ -788,11 +585,11 @@ public class RouteProvider {
} }
public List<GpxPoint> generateGpxPoints(RoutingEnvironment env, GpxRouteApproximation gctx, LocationsHolder locationsHolder) { 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 { 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 { protected RoutingEnvironment calculateRoutingEnvironment(RouteCalculationParams params, boolean calcGPXRoute, boolean skipComplex) throws IOException {
@ -885,7 +682,7 @@ public class RouteProvider {
if (params.intermediates != null) { if (params.intermediates != null) {
inters = new ArrayList<LatLon>(params.intermediates); 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, private RoutingConfiguration initOsmAndRoutingConfig(Builder config, final RouteCalculationParams params, OsmandSettings settings,
@ -1012,7 +809,9 @@ public class RouteProvider {
return new RouteCalculationResult("Empty result"); 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); List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(false);
if (selectedSegment != -1 && segments.size() > selectedSegment) { if (selectedSegment != -1 && segments.size() > selectedSegment) {
TrkSegment segment = segments.get(selectedSegment); TrkSegment segment = segments.get(selectedSegment);
@ -1022,37 +821,51 @@ public class RouteProvider {
RouteImporter routeImporter = new RouteImporter(segment); RouteImporter routeImporter = new RouteImporter(segment);
return routeImporter.importRoute(); return routeImporter.importRoute();
} else { } else {
for (TrkSegment ts : segments) { collectPointsFromSegments(segments, points, segmentEndpoints);
for (WptPt p : ts.points) {
points.add(createLocation(p));
}
}
RouteImporter routeImporter = new RouteImporter(gpxFile); RouteImporter routeImporter = new RouteImporter(gpxFile);
return routeImporter.importRoute(); return routeImporter.importRoute();
} }
} }
private static List<RouteDirectionInfo> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile, boolean osmandRouter, protected static void collectSegmentPointsFromGpx(GPXFile gpxFile, List<Location> points,
boolean leftSide, float defSpeed, int selectedSegment) { 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; List<RouteDirectionInfo> directions = null;
if (!osmandRouter) { if (!osmandRouter) {
for (WptPt pt : gpxFile.getPoints()) { for (WptPt pt : gpxFile.getPoints()) {
points.add(createLocation(pt)); points.add(createLocation(pt));
} }
} else { } else {
List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(false); collectSegmentPointsFromGpx(gpxFile, points, segmentEndpoints, selectedSegment);
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));
}
}
}
} }
float[] distanceToEnd = new float[points.size()]; float[] distanceToEnd = new float[points.size()];
for (int i = points.size() - 2; i >= 0; i--) { for (int i = points.size() - 2; i >= 0; i--) {
@ -1317,9 +1130,10 @@ public class RouteProvider {
bpars.putString("turnInstructionFormat", "osmand"); bpars.putString("turnInstructionFormat", "osmand");
bpars.putString("acceptCompressedResult", "true"); bpars.putString("acceptCompressedResult", "true");
OsmandApplication ctx = (OsmandApplication) params.ctx; OsmandApplication ctx = params.ctx;
List<Location> res = new ArrayList<Location>(); List<Location> res = new ArrayList<Location>();
List<RouteDirectionInfo > dir = new ArrayList<>(); List<RouteDirectionInfo> dir = new ArrayList<>();
List<Location> segmentEndpoints = new ArrayList<>();
IBRouterService brouterService = ctx.getBRouterService(); IBRouterService brouterService = ctx.getBRouterService();
if (brouterService == null) { if (brouterService == null) {
@ -1332,22 +1146,22 @@ public class RouteProvider {
boolean isZ64Encoded = gpxMessage.startsWith("ejY0"); // base-64 version of "z64" boolean isZ64Encoded = gpxMessage.startsWith("ejY0"); // base-64 version of "z64"
if (!( isZ64Encoded || gpxMessage.startsWith("<") ) ) { if (!(isZ64Encoded || gpxMessage.startsWith("<"))) {
return new RouteCalculationResult(gpxMessage); return new RouteCalculationResult(gpxMessage);
} }
InputStream gpxStream; InputStream gpxStream;
if ( isZ64Encoded ) { if (isZ64Encoded) {
ByteArrayInputStream bais = new ByteArrayInputStream( Base64.decode(gpxMessage, Base64.DEFAULT) ); ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(gpxMessage, Base64.DEFAULT));
bais.read( new byte[3] ); // skip prefix bais.read(new byte[3]); // skip prefix
gpxStream = new GZIPInputStream( bais ); gpxStream = new GZIPInputStream(bais);
} else { } else {
gpxStream = new ByteArrayInputStream(gpxMessage.getBytes("UTF-8")); gpxStream = new ByteArrayInputStream(gpxMessage.getBytes("UTF-8"));
} }
GPXFile gpxFile = GPXUtilities.loadGPXFile(gpxStream); 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) { if (dir != null) {
addMissingTurns = false; addMissingTurns = false;
@ -1390,6 +1204,4 @@ public class RouteProvider {
} }
return new RouteCalculationResult(segments, computeDirections, params, null, false); 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.data.LatLon;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; 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.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.router.RouteCalculationProgress; import net.osmand.router.RouteCalculationProgress;
@ -179,7 +180,7 @@ class RouteRecalculationHelper {
} }
public void recalculateRouteInBackground(final Location start, final LatLon end, final List<LatLon> intermediates, 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) { if (start == null || end == null) {
return; return;
} }
@ -207,7 +208,7 @@ class RouteRecalculationHelper {
params.mode = mode; params.mode = mode;
params.ctx = app; params.ctx = app;
boolean updateProgress = false; boolean updateProgress = false;
if (params.mode.getRouteService() == RouteProvider.RouteService.OSMAND) { if (params.mode.getRouteService() == RouteService.OSMAND) {
params.calculationProgress = new RouteCalculationProgress(); params.calculationProgress = new RouteCalculationProgress();
updateProgress = true; updateProgress = true;
} else { } 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.helpers.enums.MetricsConstants;
import net.osmand.plus.notifications.OsmandNotification.NotificationType; import net.osmand.plus.notifications.OsmandNotification.NotificationType;
import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo;
import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder; import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.plus.routing.RouteProvider.RoutingEnvironment;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmAndAppCustomization.OsmAndAppCustomizationListener; import net.osmand.plus.settings.backend.OsmAndAppCustomization.OsmAndAppCustomizationListener;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
@ -670,9 +668,9 @@ public class RoutingHelper {
private static float getDefaultAllowedDeviation(OsmandSettings settings, ApplicationMode mode, float posTolerance) { private static float getDefaultAllowedDeviation(OsmandSettings settings, ApplicationMode mode, float posTolerance) {
if (settings.DISABLE_OFFROUTE_RECALC.getModeValue(mode)) { if (settings.DISABLE_OFFROUTE_RECALC.getModeValue(mode)) {
return -1.0f; return -1.0f;
} else if (mode.getRouteService() == RouteProvider.RouteService.DIRECT_TO) { } else if (mode.getRouteService() == RouteService.DIRECT_TO) {
return -1.0f; return -1.0f;
} else if (mode.getRouteService() == RouteProvider.RouteService.STRAIGHT) { } else if (mode.getRouteService() == RouteService.STRAIGHT) {
MetricsConstants mc = settings.METRIC_SYSTEM.getModeValue(mode); MetricsConstants mc = settings.METRIC_SYSTEM.getModeValue(mode);
if (mc == MetricsConstants.KILOMETERS_AND_METERS || mc == MetricsConstants.MILES_AND_METERS) { if (mc == MetricsConstants.KILOMETERS_AND_METERS || mc == MetricsConstants.MILES_AND_METERS) {
return 500.f; return 500.f;

View file

@ -18,7 +18,6 @@ import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.render.NativeOsmandLibrary; import net.osmand.plus.render.NativeOsmandLibrary;
import net.osmand.plus.routing.RouteCalculationParams.RouteCalculationResultListener; 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.ApplicationMode;
import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings; 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.LocationIcon;
import net.osmand.plus.profiles.NavigationIcon; import net.osmand.plus.profiles.NavigationIcon;
import net.osmand.plus.profiles.ProfileIconColors; import net.osmand.plus.profiles.ProfileIconColors;
import net.osmand.plus.routing.RouteProvider.RouteService; import net.osmand.plus.routing.RouteService;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.apache.commons.lang3.StringUtils; 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.profiles.ProfileIconColors;
import net.osmand.plus.rastermaps.LayerTransparencySeekbarMode; import net.osmand.plus.rastermaps.LayerTransparencySeekbarMode;
import net.osmand.plus.render.RendererRegistry; 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.srtmplugin.TerrainMode;
import net.osmand.plus.views.layers.RadiusRulerControlLayer.RadiusRulerMode; import net.osmand.plus.views.layers.RadiusRulerControlLayer.RadiusRulerMode;
import net.osmand.plus.voice.CommandPlayer; 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.profiles.ProfileDataUtils;
import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet; import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet;
import net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet.DialogMode; 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.settings.backend.ApplicationMode;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources; import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources;
import net.osmand.plus.profiles.SelectProfileBottomSheet; import net.osmand.plus.profiles.SelectProfileBottomSheet;
import net.osmand.plus.profiles.SelectProfileBottomSheet.OnSelectProfileCallback; import net.osmand.plus.profiles.SelectProfileBottomSheet.OnSelectProfileCallback;
import net.osmand.plus.routing.RouteProvider;
import net.osmand.plus.settings.preferences.SwitchPreferenceEx; import net.osmand.plus.settings.preferences.SwitchPreferenceEx;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -151,17 +150,17 @@ public class NavigationFragment extends BaseSettingsFragment implements OnSelect
navigationType.setIcon(getActiveIcon(selectedRoutingProfileDataObject.getIconRes())); navigationType.setIcon(getActiveIcon(selectedRoutingProfileDataObject.getIconRes()));
ApplicationMode appMode = getSelectedAppMode(); ApplicationMode appMode = getSelectedAppMode();
RouteProvider.RouteService routeService; RouteService routeService;
if (profileKey.equals(RoutingProfilesResources.STRAIGHT_LINE_MODE.name())) { if (profileKey.equals(RoutingProfilesResources.STRAIGHT_LINE_MODE.name())) {
routeService = RouteProvider.RouteService.STRAIGHT; routeService = RouteService.STRAIGHT;
} else if (profileKey.equals(RoutingProfilesResources.DIRECT_TO_MODE.name())) { } 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())) { } else if (profileKey.equals(RoutingProfilesResources.BROUTER_MODE.name())) {
routeService = RouteProvider.RouteService.BROUTER; routeService = RouteService.BROUTER;
} else if (profileKey.startsWith(ONLINE_ROUTING_ENGINE_PREFIX)) { } else if (profileKey.startsWith(ONLINE_ROUTING_ENGINE_PREFIX)) {
routeService = RouteService.ONLINE; routeService = RouteService.ONLINE;
} else { } else {
routeService = RouteProvider.RouteService.OSMAND; routeService = RouteService.OSMAND;
} }
appMode.setRouteService(routeService); appMode.setRouteService(routeService);
appMode.setRoutingProfile(profileKey); appMode.setRoutingProfile(profileKey);

View file

@ -26,6 +26,9 @@ import android.widget.TextView;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.PlatformUtil; 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.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.UiUtilities.DialogButtonType; import net.osmand.plus.UiUtilities.DialogButtonType;
@ -1003,7 +1006,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
Integer customColor = null; Integer customColor = null;
int iconRes; int iconRes;
String routingProfile; String routingProfile;
RouteProvider.RouteService routeService; RouteService routeService;
NavigationIcon navigationIcon; NavigationIcon navigationIcon;
LocationIcon locationIcon; LocationIcon locationIcon;

View file

@ -31,6 +31,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.routing.RouteService;
import net.osmand.plus.development.OsmandDevelopmentPlugin; import net.osmand.plus.development.OsmandDevelopmentPlugin;
import net.osmand.plus.routing.RouteProvider; import net.osmand.plus.routing.RouteProvider;
import net.osmand.plus.routing.RoutingHelper; 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.setSummaryOn(R.string.shared_string_on);
fastRoute.setSummaryOff(R.string.shared_string_off); fastRoute.setSummaryOff(R.string.shared_string_off);
if (am.getRouteService() == RouteProvider.RouteService.OSMAND) { if (am.getRouteService() == RouteService.OSMAND) {
GeneralRouter router = app.getRouter(am); GeneralRouter router = app.getRouter(am);
clearParameters(); clearParameters();
if (router != null) { if (router != null) {
@ -308,10 +309,10 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP
} }
} }
setupTimeConditionalRoutingPref(); setupTimeConditionalRoutingPref();
} else if (am.getRouteService() == RouteProvider.RouteService.BROUTER) { } else if (am.getRouteService() == RouteService.BROUTER) {
screen.addPreference(fastRoute); screen.addPreference(fastRoute);
setupTimeConditionalRoutingPref(); setupTimeConditionalRoutingPref();
} else if (am.getRouteService() == RouteProvider.RouteService.STRAIGHT) { } else if (am.getRouteService() == RouteService.STRAIGHT) {
Preference straightAngle = new Preference(app.getApplicationContext()); Preference straightAngle = new Preference(app.getApplicationContext());
straightAngle.setPersistent(false); straightAngle.setPersistent(false);
straightAngle.setKey(settings.ROUTE_STRAIGHT_ANGLE.getId()); 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.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.helpers.enums.SpeedConstants; import net.osmand.plus.helpers.enums.SpeedConstants;
import net.osmand.plus.routing.RouteProvider.RouteService; 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.ApplicationMode;
import net.osmand.plus.settings.backend.StringPreference; import net.osmand.plus.settings.backend.StringPreference;
import net.osmand.plus.settings.bottomsheets.VehicleParametersBottomSheet; 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.osmedit.OsmEditingPlugin;
import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.BaseCard;
import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener; 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.SaveGpxAsyncTask.SaveGpxListener;
import net.osmand.plus.track.TrackSelectSegmentBottomSheet.OnSegmentSelectedListener; import net.osmand.plus.track.TrackSelectSegmentBottomSheet.OnSegmentSelectedListener;
import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint; import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint;
@ -1156,7 +1156,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (mapActivity != null) { if (mapActivity != null) {
startNavigationForGPX(gpxFile, mapActivity.getMapActions()); startNavigationForGPX(gpxFile, mapActivity.getMapActions());
RouteProvider.GPXRouteParamsBuilder paramsBuilder = app.getRoutingHelper().getCurrentGPXRoute(); GPXRouteParamsBuilder paramsBuilder = app.getRoutingHelper().getCurrentGPXRoute();
if (paramsBuilder != null) { if (paramsBuilder != null) {
paramsBuilder.setSelectedSegment(selectedSegment); paramsBuilder.setSelectedSegment(selectedSegment);
app.getRoutingHelper().onSettingsChanged(true); 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.profiles.LocationIcon;
import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteCalculationResult;
import net.osmand.plus.routing.RouteDirectionInfo; 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.RoutingHelper;
import net.osmand.plus.routing.TransportRoutingHelper; import net.osmand.plus.routing.TransportRoutingHelper;
import net.osmand.plus.views.OsmandMapLayer; import net.osmand.plus.views.OsmandMapLayer;
@ -360,8 +360,8 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont
} }
} else { } else {
RouteCalculationResult route = helper.getRoute(); RouteCalculationResult route = helper.getRoute();
boolean directTo = route.getRouteService() == RouteProvider.RouteService.DIRECT_TO; boolean directTo = route.getRouteService() == RouteService.DIRECT_TO;
boolean straight = route.getRouteService() == RouteProvider.RouteService.STRAIGHT; boolean straight = route.getRouteService() == RouteService.STRAIGHT;
publicTransportRouteGeometry.clearRoute(); publicTransportRouteGeometry.clearRoute();
routeGeometry.updateRoute(tb, route); routeGeometry.updateRoute(tb, route);
if (directTo) { if (directTo) {