Merge pull request #10586 from osmandapp/OnlineRoutingBackend

Implement Online routing backend p.2
This commit is contained in:
Vitaliy 2021-01-18 11:36:35 +02:00 committed by GitHub
commit 1cc116fe49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 1148 additions and 726 deletions

View file

@ -27,6 +27,8 @@
android:layout_weight="1" android:layout_weight="1"
android:layout_marginLeft="@dimen/content_padding" android:layout_marginLeft="@dimen/content_padding"
android:layout_marginStart="@dimen/content_padding" android:layout_marginStart="@dimen/content_padding"
android:paddingTop="@dimen/content_padding_small"
android:paddingBottom="@dimen/content_padding_small"
android:orientation="vertical"> android:orientation="vertical">
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
@ -34,7 +36,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorPrimary" android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size" android:textSize="@dimen/default_list_text_size"
app:typeface="@string/font_roboto_regular" app:typeface="@string/font_roboto_regular"

View file

@ -129,6 +129,19 @@
tools:visibility="visible" tools:visibility="visible"
android:visibility="gone" /> android:visibility="gone" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/error_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:letterSpacing="@dimen/description_letter_spacing"
android:paddingTop="@dimen/content_padding_half"
android:textColor="@color/color_invalid"
android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_regular"
tools:text="Error text"
tools:visibility="visible"
android:visibility="gone" />
</LinearLayout> </LinearLayout>
<View <View

View file

@ -4023,7 +4023,6 @@
<string name="routing_engine_vehicle_type_foot">قدم</string> <string name="routing_engine_vehicle_type_foot">قدم</string>
<string name="routing_engine_vehicle_type_bike">دراجة هوائية</string> <string name="routing_engine_vehicle_type_bike">دراجة هوائية</string>
<string name="routing_engine_vehicle_type_car">سيارة</string> <string name="routing_engine_vehicle_type_car">سيارة</string>
<string name="message_error_recheck_parameters">خطأ، أعد التحقق من المعايير</string>
<string name="copy_address">نسخ العنوان</string> <string name="copy_address">نسخ العنوان</string>
<string name="online_routing_engine">محرك التوجيه عبر الإنترنت</string> <string name="online_routing_engine">محرك التوجيه عبر الإنترنت</string>
<string name="online_routing_engines">محركات التوجيه عبر الإنترنت</string> <string name="online_routing_engines">محركات التوجيه عبر الإنترنت</string>

View file

@ -3960,7 +3960,6 @@
<string name="routing_engine_vehicle_type_foot">Chůze</string> <string name="routing_engine_vehicle_type_foot">Chůze</string>
<string name="routing_engine_vehicle_type_bike">Kolo</string> <string name="routing_engine_vehicle_type_bike">Kolo</string>
<string name="routing_engine_vehicle_type_car">Auto</string> <string name="routing_engine_vehicle_type_car">Auto</string>
<string name="message_error_recheck_parameters">Chyba, zkontrolujte parametry</string>
<string name="copy_address">Kopírovat adresu</string> <string name="copy_address">Kopírovat adresu</string>
<string name="online_routing_engine">Online navigační služba</string> <string name="online_routing_engine">Online navigační služba</string>
<string name="online_routing_engines">Online navigační služby</string> <string name="online_routing_engines">Online navigační služby</string>

View file

@ -3962,7 +3962,6 @@
<string name="routing_engine_vehicle_type_foot">Zu Fuß</string> <string name="routing_engine_vehicle_type_foot">Zu Fuß</string>
<string name="routing_engine_vehicle_type_bike">Fahrrad</string> <string name="routing_engine_vehicle_type_bike">Fahrrad</string>
<string name="routing_engine_vehicle_type_car">Auto</string> <string name="routing_engine_vehicle_type_car">Auto</string>
<string name="message_error_recheck_parameters">Fehler, Parameter erneut prüfen</string>
<string name="shared_string_subtype">Subtyp</string> <string name="shared_string_subtype">Subtyp</string>
<string name="keep_it_empty_if_not">Leer lassen, wenn kein API-Schlüssel vorhanden</string> <string name="keep_it_empty_if_not">Leer lassen, wenn kein API-Schlüssel vorhanden</string>
<string name="copy_address">Adresse kopieren</string> <string name="copy_address">Adresse kopieren</string>

View file

@ -3960,7 +3960,6 @@
<string name="routing_engine_vehicle_type_foot">Piediranto</string> <string name="routing_engine_vehicle_type_foot">Piediranto</string>
<string name="routing_engine_vehicle_type_bike">Biciklo</string> <string name="routing_engine_vehicle_type_bike">Biciklo</string>
<string name="routing_engine_vehicle_type_car">Aŭtomobilo</string> <string name="routing_engine_vehicle_type_car">Aŭtomobilo</string>
<string name="message_error_recheck_parameters">Eraro, rekontrolu parametrojn</string>
<string name="copy_address">Kopii adreson</string> <string name="copy_address">Kopii adreson</string>
<string name="online_routing_engine">Enreta navigilo</string> <string name="online_routing_engine">Enreta navigilo</string>
<string name="online_routing_engines">Enretaj navigiloj</string> <string name="online_routing_engines">Enretaj navigiloj</string>

View file

@ -3963,7 +3963,6 @@
<string name="routing_engine_vehicle_type_foot">Peatón</string> <string name="routing_engine_vehicle_type_foot">Peatón</string>
<string name="routing_engine_vehicle_type_bike">Bicicleta</string> <string name="routing_engine_vehicle_type_bike">Bicicleta</string>
<string name="routing_engine_vehicle_type_car">Automóvil</string> <string name="routing_engine_vehicle_type_car">Automóvil</string>
<string name="message_error_recheck_parameters">Error, vuelve a comprobar los parámetros</string>
<string name="copy_address">Copiar dirección</string> <string name="copy_address">Copiar dirección</string>
<string name="online_routing_engine">Motor de navegación en línea</string> <string name="online_routing_engine">Motor de navegación en línea</string>
<string name="online_routing_engines">Motores de navegación en línea</string> <string name="online_routing_engines">Motores de navegación en línea</string>

View file

@ -3933,6 +3933,5 @@ Area honi dagokio: %1$s x %2$s</string>
<string name="routing_engine_vehicle_type_foot">Oinez</string> <string name="routing_engine_vehicle_type_foot">Oinez</string>
<string name="routing_engine_vehicle_type_bike">Bizikleta</string> <string name="routing_engine_vehicle_type_bike">Bizikleta</string>
<string name="routing_engine_vehicle_type_car">Kotxea</string> <string name="routing_engine_vehicle_type_car">Kotxea</string>
<string name="message_error_recheck_parameters">Errorea, egiaztatu parametroak berriro</string>
<string name="copy_address">Kopiatu helbidea</string> <string name="copy_address">Kopiatu helbidea</string>
</resources> </resources>

View file

@ -3953,5 +3953,4 @@
<string name="routing_engine_vehicle_type_foot">پا</string> <string name="routing_engine_vehicle_type_foot">پا</string>
<string name="routing_engine_vehicle_type_bike">دوچرخه</string> <string name="routing_engine_vehicle_type_bike">دوچرخه</string>
<string name="routing_engine_vehicle_type_car">خودرو</string> <string name="routing_engine_vehicle_type_car">خودرو</string>
<string name="message_error_recheck_parameters">خطا، پارامترها را بازبینی کنید</string>
</resources> </resources>

View file

@ -3947,7 +3947,6 @@
<string name="routing_engine_vehicle_type_foot">A pieds</string> <string name="routing_engine_vehicle_type_foot">A pieds</string>
<string name="routing_engine_vehicle_type_bike">Vélo</string> <string name="routing_engine_vehicle_type_bike">Vélo</string>
<string name="routing_engine_vehicle_type_car">Automobile</string> <string name="routing_engine_vehicle_type_car">Automobile</string>
<string name="message_error_recheck_parameters">Erreur, vérifiez les paramètres</string>
<string name="add_online_routing_engine">Ajouter un moteur de routage en ligne</string> <string name="add_online_routing_engine">Ajouter un moteur de routage en ligne</string>
<string name="edit_online_routing_engine">Modifier le moteur de routage en ligne</string> <string name="edit_online_routing_engine">Modifier le moteur de routage en ligne</string>
<string name="online_routing_example_hint">L\'URL avec tous les paramètres sera de la forme :</string> <string name="online_routing_example_hint">L\'URL avec tous les paramètres sera de la forme :</string>

View file

@ -3968,7 +3968,6 @@ Lon %2$s</string>
<string name="routing_engine_vehicle_type_foot"></string> <string name="routing_engine_vehicle_type_foot"></string>
<string name="routing_engine_vehicle_type_bike">Bicicleta</string> <string name="routing_engine_vehicle_type_bike">Bicicleta</string>
<string name="routing_engine_vehicle_type_car">Coche</string> <string name="routing_engine_vehicle_type_car">Coche</string>
<string name="message_error_recheck_parameters">Erro, verifica novamente os parámetros</string>
<string name="copy_address">Copiar enderezo</string> <string name="copy_address">Copiar enderezo</string>
<string name="voice_prompts_timetable">Horarios dos avisos por voz</string> <string name="voice_prompts_timetable">Horarios dos avisos por voz</string>
<string name="online_routing_engine">Motor de navegación en liña</string> <string name="online_routing_engine">Motor de navegación en liña</string>

View file

@ -3954,7 +3954,6 @@
<string name="keep_it_empty_if_not">Hagyja üresen, ha nem</string> <string name="keep_it_empty_if_not">Hagyja üresen, ha nem</string>
<string name="online_routing_example_hint">Az összes paraméterrel rendelkező URL így néz ki:</string> <string name="online_routing_example_hint">Az összes paraméterrel rendelkező URL így néz ki:</string>
<string name="test_route_calculation">Útvonaltervezés kipróbálása</string> <string name="test_route_calculation">Útvonaltervezés kipróbálása</string>
<string name="message_error_recheck_parameters">Hiba, ellenőrizze újra a paramétereket</string>
<string name="copy_address">Cím másolása</string> <string name="copy_address">Cím másolása</string>
<string name="online_routing_engine">Online útvonaltervező</string> <string name="online_routing_engine">Online útvonaltervező</string>
<string name="online_routing_engines">Online útvonaltervezők</string> <string name="online_routing_engines">Online útvonaltervezők</string>

View file

@ -3965,6 +3965,5 @@
<string name="routing_engine_vehicle_type_foot">Gangandi</string> <string name="routing_engine_vehicle_type_foot">Gangandi</string>
<string name="routing_engine_vehicle_type_bike">Hjólandi</string> <string name="routing_engine_vehicle_type_bike">Hjólandi</string>
<string name="routing_engine_vehicle_type_car">Bíll</string> <string name="routing_engine_vehicle_type_car">Bíll</string>
<string name="message_error_recheck_parameters">Villa, yfirfarðu breytur</string>
<string name="copy_address">Afrita heimilisfang</string> <string name="copy_address">Afrita heimilisfang</string>
</resources> </resources>

View file

@ -3963,7 +3963,6 @@
<string name="routing_engine_vehicle_type_foot">ברגל</string> <string name="routing_engine_vehicle_type_foot">ברגל</string>
<string name="routing_engine_vehicle_type_bike">אופנוע</string> <string name="routing_engine_vehicle_type_bike">אופנוע</string>
<string name="routing_engine_vehicle_type_car">מכונית</string> <string name="routing_engine_vehicle_type_car">מכונית</string>
<string name="message_error_recheck_parameters">שגיאה, נא לבדוק את המשתנים מחדש</string>
<string name="copy_address">העתקת כתובת</string> <string name="copy_address">העתקת כתובת</string>
<string name="online_routing_engine">מנוע ניווט מקוון</string> <string name="online_routing_engine">מנוע ניווט מקוון</string>
<string name="online_routing_engines">מנועי ניווט מקוונים</string> <string name="online_routing_engines">מנועי ניווט מקוונים</string>

View file

@ -2449,7 +2449,6 @@
<string name="subscription_paused_title">OsmAndის გამოწერა დაპაუზებულია</string> <string name="subscription_paused_title">OsmAndის გამოწერა დაპაუზებულია</string>
<string name="subscription_on_hold_title">OsmAndის გამოწერა შეჩერებულია</string> <string name="subscription_on_hold_title">OsmAndის გამოწერა შეჩერებულია</string>
<string name="online_routing_example_hint">URL ყველა პარამეტრით აი ასეთი იქნება:</string> <string name="online_routing_example_hint">URL ყველა პარამეტრით აი ასეთი იქნება:</string>
<string name="message_error_recheck_parameters">შეცდომა, გადაამოწმეთ პარამეტრები</string>
<string name="mapillary_image">Mapillary-ის გამოსახულება</string> <string name="mapillary_image">Mapillary-ის გამოსახულება</string>
<string name="mapillary_widget">Mapillary-ის ღილაკი</string> <string name="mapillary_widget">Mapillary-ის ღილაკი</string>
<string name="srtm_color_scheme">ფერთა გამა</string> <string name="srtm_color_scheme">ფერთა გამა</string>

View file

@ -2770,7 +2770,6 @@ Tai yra puikus būdas paremti OsmAnd ir OSM, jei jie jums patinka.</string>
<string name="test_route_calculation">Patikrinti maršruto apskaičiavimą</string> <string name="test_route_calculation">Patikrinti maršruto apskaičiavimą</string>
<string name="routing_engine_vehicle_type_bike">Dviratis</string> <string name="routing_engine_vehicle_type_bike">Dviratis</string>
<string name="routing_engine_vehicle_type_car">Automobilis</string> <string name="routing_engine_vehicle_type_car">Automobilis</string>
<string name="message_error_recheck_parameters">Įvyko klaida, patikrinkite paametrus</string>
<string name="copy_address">Kopijuoti adresą</string> <string name="copy_address">Kopijuoti adresą</string>
<string name="shared_string_folders">Folderiai</string> <string name="shared_string_folders">Folderiai</string>
<string name="select_folder">Pasirinkite folderį</string> <string name="select_folder">Pasirinkite folderį</string>

View file

@ -3916,7 +3916,6 @@
<string name="routing_engine_vehicle_type_foot">Te voet</string> <string name="routing_engine_vehicle_type_foot">Te voet</string>
<string name="routing_engine_vehicle_type_bike">Fiets</string> <string name="routing_engine_vehicle_type_bike">Fiets</string>
<string name="routing_engine_vehicle_type_car">Auto</string> <string name="routing_engine_vehicle_type_car">Auto</string>
<string name="message_error_recheck_parameters">Fout, controleer parameters opnieuw</string>
<string name="copy_address">Kopieer adres</string> <string name="copy_address">Kopieer adres</string>
<string name="online_routing_engine">Online routeplanningssysteem</string> <string name="online_routing_engine">Online routeplanningssysteem</string>
<string name="online_routing_engines">Online routeplanningssystemen</string> <string name="online_routing_engines">Online routeplanningssystemen</string>

View file

@ -3956,7 +3956,6 @@
<string name="test_route_calculation">Obliczanie trasy testowej</string> <string name="test_route_calculation">Obliczanie trasy testowej</string>
<string name="routing_engine_vehicle_type_bike">Rower</string> <string name="routing_engine_vehicle_type_bike">Rower</string>
<string name="routing_engine_vehicle_type_car">Samochód</string> <string name="routing_engine_vehicle_type_car">Samochód</string>
<string name="message_error_recheck_parameters">Błąd, ponownie sprawdź parametry</string>
<string name="copy_address">Skopiuj adres</string> <string name="copy_address">Skopiuj adres</string>
<string name="routing_engine_vehicle_type_driving">Jazda</string> <string name="routing_engine_vehicle_type_driving">Jazda</string>
<string name="routing_engine_vehicle_type_foot">Stopa</string> <string name="routing_engine_vehicle_type_foot">Stopa</string>

View file

@ -3955,7 +3955,6 @@
<string name="routing_engine_vehicle_type_foot"></string> <string name="routing_engine_vehicle_type_foot"></string>
<string name="routing_engine_vehicle_type_bike">Bicicleta</string> <string name="routing_engine_vehicle_type_bike">Bicicleta</string>
<string name="routing_engine_vehicle_type_car">Carro</string> <string name="routing_engine_vehicle_type_car">Carro</string>
<string name="message_error_recheck_parameters">Erro, verifique novamente os parâmetros</string>
<string name="copy_address">Copiar endereço</string> <string name="copy_address">Copiar endereço</string>
<string name="online_routing_engine">Motor de encaminhamento online</string> <string name="online_routing_engine">Motor de encaminhamento online</string>
<string name="online_routing_engines">Mecanismos de roteamento online</string> <string name="online_routing_engines">Mecanismos de roteamento online</string>

View file

@ -3957,7 +3957,6 @@
<string name="routing_engine_vehicle_type_foot">A pee</string> <string name="routing_engine_vehicle_type_foot">A pee</string>
<string name="routing_engine_vehicle_type_bike">Bitzicleta</string> <string name="routing_engine_vehicle_type_bike">Bitzicleta</string>
<string name="routing_engine_vehicle_type_car">Màchina</string> <string name="routing_engine_vehicle_type_car">Màchina</string>
<string name="message_error_recheck_parameters">Errore, torra a verificare sos paràmetros</string>
<string name="copy_address">Còpia s\'indiritzu</string> <string name="copy_address">Còpia s\'indiritzu</string>
<string name="online_routing_engine">Motore de càrculu in lìnia</string> <string name="online_routing_engine">Motore de càrculu in lìnia</string>
<string name="online_routing_engines">Motores de càrculu in lìnia</string> <string name="online_routing_engines">Motores de càrculu in lìnia</string>

View file

@ -3955,7 +3955,6 @@
<string name="routing_engine_vehicle_type_foot">Chôdza</string> <string name="routing_engine_vehicle_type_foot">Chôdza</string>
<string name="routing_engine_vehicle_type_bike">Bicykel</string> <string name="routing_engine_vehicle_type_bike">Bicykel</string>
<string name="routing_engine_vehicle_type_car">Auto</string> <string name="routing_engine_vehicle_type_car">Auto</string>
<string name="message_error_recheck_parameters">Chyba, skontrolujte parametre</string>
<string name="copy_address">Kopírovať adresu</string> <string name="copy_address">Kopírovať adresu</string>
<string name="online_routing_engine">Online navigačná služba</string> <string name="online_routing_engine">Online navigačná služba</string>
<string name="online_routing_engines">Online navigačné služby</string> <string name="online_routing_engines">Online navigačné služby</string>

View file

@ -3961,7 +3961,6 @@
<string name="routing_engine_vehicle_type_foot">Yürüme</string> <string name="routing_engine_vehicle_type_foot">Yürüme</string>
<string name="routing_engine_vehicle_type_bike">Bisiklet</string> <string name="routing_engine_vehicle_type_bike">Bisiklet</string>
<string name="routing_engine_vehicle_type_car">Araba</string> <string name="routing_engine_vehicle_type_car">Araba</string>
<string name="message_error_recheck_parameters">Hata, parametreleri tekrar gözden geçirin</string>
<string name="copy_address">Adresi kopyala</string> <string name="copy_address">Adresi kopyala</string>
<string name="online_routing_engine">Çevrim içi yönlendirme motoru</string> <string name="online_routing_engine">Çevrim içi yönlendirme motoru</string>
<string name="online_routing_engines">Çevrim içi yönlendirme motorları</string> <string name="online_routing_engines">Çevrim içi yönlendirme motorları</string>

View file

@ -3959,7 +3959,6 @@
<string name="routing_engine_vehicle_type_foot">Пішки</string> <string name="routing_engine_vehicle_type_foot">Пішки</string>
<string name="routing_engine_vehicle_type_bike">Велосипед</string> <string name="routing_engine_vehicle_type_bike">Велосипед</string>
<string name="routing_engine_vehicle_type_car">Автомобіль</string> <string name="routing_engine_vehicle_type_car">Автомобіль</string>
<string name="message_error_recheck_parameters">Помилка, повторно перевірте параметри</string>
<string name="copy_address">Копіювати адресу</string> <string name="copy_address">Копіювати адресу</string>
<string name="online_routing_engine">Мережний рушій маршрутизації</string> <string name="online_routing_engine">Мережний рушій маршрутизації</string>
<string name="online_routing_engines">Мережні рушії маршрутизації</string> <string name="online_routing_engines">Мережні рушії маршрутизації</string>

View file

@ -3953,7 +3953,6 @@
<string name="routing_engine_vehicle_type_foot">步行</string> <string name="routing_engine_vehicle_type_foot">步行</string>
<string name="routing_engine_vehicle_type_bike">自行車</string> <string name="routing_engine_vehicle_type_bike">自行車</string>
<string name="routing_engine_vehicle_type_car">汽車</string> <string name="routing_engine_vehicle_type_car">汽車</string>
<string name="message_error_recheck_parameters">錯誤,重新檢查參數</string>
<string name="copy_address">複製地址</string> <string name="copy_address">複製地址</string>
<string name="online_routing_engine">線上路線計算引擎</string> <string name="online_routing_engine">線上路線計算引擎</string>
<string name="online_routing_engines">線上路線計算引擎</string> <string name="online_routing_engines">線上路線計算引擎</string>

View file

@ -12,6 +12,21 @@
--> -->
<string name="message_name_is_already_exists">The name is already exists</string>
<string name="message_server_error">Server error: %1$s</string>
<string name="routing_engine_vehicle_type_mtb">MTB</string>
<string name="routing_engine_vehicle_type_racingbike">Racing bike</string>
<string name="routing_engine_vehicle_type_scooter">Scooter</string>
<string name="routing_engine_vehicle_type_truck">Truck</string>
<string name="routing_engine_vehicle_type_small_truck">Small truck</string>
<string name="routing_engine_vehicle_type_hgv">HGV</string>
<string name="routing_engine_vehicle_type_cycling_regular">Regular cycling</string>
<string name="routing_engine_vehicle_type_cycling_road">Road cycling</string>
<string name="routing_engine_vehicle_type_cycling_mountain">Mountain cycling</string>
<string name="routing_engine_vehicle_type_cycling_electric">Electric cycling</string>
<string name="routing_engine_vehicle_type_walking">Walking</string>
<string name="routing_engine_vehicle_type_hiking">Hiking</string>
<string name="routing_engine_vehicle_type_wheelchair">Wheelchair</string>
<string name="show_track_on_map">Show track on map</string> <string name="show_track_on_map">Show track on map</string>
<string name="start_recording">Start recording</string> <string name="start_recording">Start recording</string>
<string name="announcement_time_title">Announcement time</string> <string name="announcement_time_title">Announcement time</string>
@ -37,7 +52,6 @@
<string name="online_routing_engines">Online routing engines</string> <string name="online_routing_engines">Online routing engines</string>
<string name="online_routing_engine">Online routing engine</string> <string name="online_routing_engine">Online routing engine</string>
<string name="copy_address">Copy address</string> <string name="copy_address">Copy address</string>
<string name="message_error_recheck_parameters">Error, recheck parameters</string>
<string name="routing_engine_vehicle_type_car">Car</string> <string name="routing_engine_vehicle_type_car">Car</string>
<string name="routing_engine_vehicle_type_bike">Bike</string> <string name="routing_engine_vehicle_type_bike">Bike</string>
<string name="routing_engine_vehicle_type_foot">Foot</string> <string name="routing_engine_vehicle_type_foot">Foot</string>

View file

@ -0,0 +1,10 @@
package net.osmand.plus.onlinerouting;
public enum EngineParameter {
KEY,
VEHICLE_KEY,
CUSTOM_NAME,
NAME_INDEX,
CUSTOM_URL,
API_KEY
}

View file

@ -1,24 +0,0 @@
package net.osmand.plus.onlinerouting;
public enum EngineType {
GRAPHHOPPER("Graphhopper", "https://graphhopper.com/api/1/route"),
OSRM("OSRM", "https://router.project-osrm.org/route/v1/"),
ORS("Openroute Service", "https://api.openrouteservice.org/v2/directions/");
private String title;
private String standardUrl;
EngineType(String title, String standardUrl) {
this.title = title;
this.standardUrl = standardUrl;
}
public String getTitle() {
return title;
}
public String getStandardUrl() {
return standardUrl;
}
}

View file

@ -1,109 +0,0 @@
package net.osmand.plus.onlinerouting;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.plus.R;
import net.osmand.util.Algorithms;
import java.util.HashMap;
import java.util.Map;
public class OnlineRoutingEngine {
public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_";
public enum EngineParameter {
CUSTOM_NAME,
CUSTOM_URL,
API_KEY
}
private String stringKey;
private EngineType type;
private String vehicleKey;
private Map<String, String> params = new HashMap<>();
public OnlineRoutingEngine(@NonNull String stringKey,
@NonNull EngineType type,
@NonNull String vehicleKey,
@Nullable Map<String, String> params) {
this(stringKey, type, vehicleKey);
if (!Algorithms.isEmpty(params)) {
this.params.putAll(params);
}
}
public OnlineRoutingEngine(@NonNull String stringKey,
@NonNull EngineType type,
@NonNull String vehicleKey) {
this.stringKey = stringKey;
this.type = type;
this.vehicleKey = vehicleKey;
}
public String getStringKey() {
return stringKey;
}
public EngineType getType() {
return type;
}
public String getBaseUrl() {
String customUrl = getParameter(EngineParameter.CUSTOM_URL);
if (Algorithms.isEmpty(customUrl)) {
return type.getStandardUrl();
}
return customUrl;
}
public String getVehicleKey() {
return vehicleKey;
}
public Map<String, String> getParams() {
return params;
}
public String getParameter(EngineParameter paramKey) {
return params.get(paramKey.name());
}
public void putParameter(EngineParameter paramKey, String paramValue) {
params.put(paramKey.name(), paramValue);
}
public String getName(@NonNull Context ctx) {
String customName = getParameter(EngineParameter.CUSTOM_NAME);
if (customName != null) {
return customName;
} else {
return getStandardName(ctx);
}
}
private String getStandardName(@NonNull Context ctx) {
return getStandardName(ctx, type, vehicleKey);
}
public static String getStandardName(@NonNull Context ctx,
@NonNull EngineType type,
@NonNull String vehicleKey) {
String vehicleTitle = VehicleType.toHumanString(ctx, vehicleKey);
String pattern = ctx.getString(R.string.ltr_or_rtl_combine_via_dash);
return String.format(pattern, type.getTitle(), vehicleTitle);
}
public static OnlineRoutingEngine createNewEngine(@NonNull EngineType type,
@NonNull String vehicleKey,
@Nullable Map<String, String> params) {
return new OnlineRoutingEngine(generateKey(), type, vehicleKey, params);
}
private static String generateKey() {
return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis();
}
}

View file

@ -0,0 +1,36 @@
package net.osmand.plus.onlinerouting;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.plus.onlinerouting.engine.EngineType;
import net.osmand.plus.onlinerouting.engine.GraphhopperEngine;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.onlinerouting.engine.OrsEngine;
import net.osmand.plus.onlinerouting.engine.OsrmEngine;
import java.util.Map;
public class OnlineRoutingFactory {
public static OnlineRoutingEngine createEngine(@NonNull EngineType type) {
return createEngine(type, null);
}
@NonNull
public static OnlineRoutingEngine createEngine(@NonNull EngineType type,
@Nullable Map<String, String> params) {
switch (type) {
case GRAPHHOPPER:
return new GraphhopperEngine(params);
case OSRM:
return new OsrmEngine(params);
case ORS:
return new OrsEngine(params);
default:
throw new IllegalArgumentException(
"Online routing type {" + type.name() + "} not supported");
}
}
}

View file

@ -1,6 +1,7 @@
package net.osmand.plus.onlinerouting; package net.osmand.plus.onlinerouting;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
@ -10,10 +11,10 @@ import net.osmand.data.LatLon;
import net.osmand.osm.io.NetworkUtils; import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter; import net.osmand.plus.onlinerouting.engine.EngineType;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.GeoPolylineParserUtil;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.json.JSONArray; import org.json.JSONArray;
@ -24,7 +25,7 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.net.URLConnection; import java.net.HttpURLConnection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -35,14 +36,18 @@ public class OnlineRoutingHelper {
private static final Log LOG = PlatformUtil.getLog(OnlineRoutingHelper.class); private static final Log LOG = PlatformUtil.getLog(OnlineRoutingHelper.class);
private static final String ITEMS = "items";
private static final String TYPE = "type";
private static final String PARAMS = "params";
private OsmandApplication app; private OsmandApplication app;
private OsmandSettings settings; private OsmandSettings settings;
private Map<String, OnlineRoutingEngine> cachedEngines; private Map<String, OnlineRoutingEngine> cachedEngines;
public OnlineRoutingHelper(OsmandApplication app) { public OnlineRoutingHelper(@NonNull OsmandApplication app) {
this.app = app; this.app = app;
this.settings = app.getSettings(); this.settings = app.getSettings();
loadFromSettings(); this.cachedEngines = loadSavedEngines();
} }
@NonNull @NonNull
@ -50,104 +55,42 @@ public class OnlineRoutingHelper {
return new ArrayList<>(cachedEngines.values()); return new ArrayList<>(cachedEngines.values());
} }
public OnlineRoutingEngine getEngineByKey(String stringKey) { @NonNull
public List<OnlineRoutingEngine> getEnginesExceptMentioned(@Nullable String ... excludeKeys) {
List<OnlineRoutingEngine> engines = getEngines();
if (excludeKeys != null) {
for (String key : excludeKeys) {
OnlineRoutingEngine engine = getEngineByKey(key);
engines.remove(engine);
}
}
return engines;
}
@Nullable
public OnlineRoutingEngine getEngineByKey(@Nullable String stringKey) {
return cachedEngines.get(stringKey); return cachedEngines.get(stringKey);
} }
@NonNull
public List<LatLon> calculateRouteOnline(@NonNull OnlineRoutingEngine engine, public List<LatLon> calculateRouteOnline(@NonNull OnlineRoutingEngine engine,
@NonNull List<LatLon> path) throws IOException, JSONException { @NonNull List<LatLon> path) throws IOException, JSONException {
String fullUrl = createFullUrl(engine, path); String url = engine.getFullUrl(path);
String content = makeRequest(fullUrl); String content = makeRequest(url);
return parseResponse(engine, content); return engine.parseServerResponse(content);
} }
public String createFullUrl(OnlineRoutingEngine engine, List<LatLon> path) { @NonNull
StringBuilder sb = new StringBuilder(engine.getBaseUrl()); public String makeRequest(@NonNull String url) throws IOException {
String vehicle = engine.getVehicleKey(); HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url);
String apiKey = engine.getParameter(EngineParameter.API_KEY);
switch (engine.getType()) {
case GRAPHHOPPER:
sb.append("?");
for (LatLon point : path) {
sb.append("point=")
.append(point.getLatitude())
.append(',')
.append(point.getLongitude())
.append('&');
}
sb.append("vehicle=").append(vehicle);
if (!Algorithms.isEmpty(apiKey)) {
sb.append('&').append("key=").append(apiKey);
}
break;
case OSRM:
sb.append(vehicle).append('/');
for (int i = 0; i < path.size(); i++) {
LatLon point = path.get(i);
sb.append(point.getLongitude()).append(',').append(point.getLatitude());
if (i < path.size() - 1) {
sb.append(';');
}
}
break;
case ORS:
if (path.size() > 1) {
sb.append("driving-car").append('?'); // todo only for testing
if (!Algorithms.isEmpty(apiKey)) {
sb.append("api_key=").append(apiKey);
}
LatLon start = path.get(0);
LatLon end = path.get(path.size() - 1);
sb.append('&').append("start=")
.append(start.getLatitude()).append(',').append(start.getLongitude());
sb.append('&').append("end=")
.append(end.getLatitude()).append(',').append(end.getLongitude());
}
break;
}
return sb.toString();
}
private List<LatLon> parseResponse(OnlineRoutingEngine engine, String content) throws JSONException {
JSONObject obj = new JSONObject(content);
switch (engine.getType()) {
case GRAPHHOPPER:
return GeoPolylineParserUtil.parse(
obj.getJSONArray("paths").getJSONObject(0).getString("points"),
GeoPolylineParserUtil.PRECISION_5);
case OSRM:
return GeoPolylineParserUtil.parse(
obj.getJSONArray("routes").getJSONObject(0).getString("geometry"),
GeoPolylineParserUtil.PRECISION_5);
case ORS:
JSONArray array = obj.getJSONArray("features").getJSONObject(0)
.getJSONObject("geometry").getJSONArray("coordinates");
List<LatLon> track = new ArrayList<>();
for (int i = 0; i < array.length(); i++) {
JSONArray point = array.getJSONArray(i);
double lat = Double.parseDouble(point.getString(0));
double lon = Double.parseDouble(point.getString(1));
track.add(new LatLon(lat, lon));
}
return track;
}
return new ArrayList<>();
}
private String makeRequest(String url) throws IOException {
URLConnection connection = NetworkUtils.getHttpURLConnection(url);
connection.setRequestProperty("User-Agent", Version.getFullVersion(app)); connection.setRequestProperty("User-Agent", Version.getFullVersion(app));
StringBuilder content = new StringBuilder(); StringBuilder content = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); BufferedReader reader;
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} else {
reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
}
String s; String s;
while ((s = reader.readLine()) != null) { while ((s = reader.readLine()) != null) {
content.append(s); content.append(s);
@ -160,32 +103,49 @@ public class OnlineRoutingHelper {
} }
public void saveEngine(@NonNull OnlineRoutingEngine engine) { public void saveEngine(@NonNull OnlineRoutingEngine engine) {
String stringKey = engine.getStringKey(); deleteInaccessibleParameters(engine);
cachedEngines.put(stringKey, engine); String key = createEngineKeyIfNeeded(engine);
saveToSettings(); cachedEngines.put(key, engine);
} saveCacheToSettings();
public void deleteEngine(@NonNull String stringKey) {
OnlineRoutingEngine engine = getEngineByKey(stringKey);
if (engine != null) {
deleteEngine(engine);
}
} }
public void deleteEngine(@NonNull OnlineRoutingEngine engine) { public void deleteEngine(@NonNull OnlineRoutingEngine engine) {
String stringKey = engine.getStringKey(); String stringKey = engine.getStringKey();
if (cachedEngines.containsKey(stringKey)) { deleteEngine(stringKey);
}
public void deleteEngine(@Nullable String stringKey) {
if (stringKey != null) {
cachedEngines.remove(stringKey); cachedEngines.remove(stringKey);
saveToSettings(); saveCacheToSettings();
} }
} }
private void loadFromSettings() { private void deleteInaccessibleParameters(@NonNull OnlineRoutingEngine engine) {
for (EngineParameter key : EngineParameter.values()) {
if (!engine.isParameterAllowed(key)) {
engine.remove(key);
}
}
}
@NonNull
private String createEngineKeyIfNeeded(@NonNull OnlineRoutingEngine engine) {
String key = engine.get(EngineParameter.KEY);
if (Algorithms.isEmpty(key)) {
key = OnlineRoutingEngine.generateKey();
engine.put(EngineParameter.KEY, key);
}
return key;
}
@NonNull
private Map<String, OnlineRoutingEngine> loadSavedEngines() {
Map<String, OnlineRoutingEngine> cachedEngines = new LinkedHashMap<>(); Map<String, OnlineRoutingEngine> cachedEngines = new LinkedHashMap<>();
for (OnlineRoutingEngine engine : readFromSettings()) { for (OnlineRoutingEngine engine : readFromSettings()) {
cachedEngines.put(engine.getStringKey(), engine); cachedEngines.put(engine.getStringKey(), engine);
} }
this.cachedEngines = cachedEngines; return cachedEngines;
} }
@NonNull @NonNull
@ -196,14 +156,14 @@ public class OnlineRoutingHelper {
try { try {
JSONObject json = new JSONObject(jsonString); JSONObject json = new JSONObject(jsonString);
readFromJson(json, engines); readFromJson(json, engines);
} catch (JSONException e) { } catch (JSONException | IllegalArgumentException e) {
LOG.debug("Error when reading engines from JSON ", e); LOG.debug("Error when reading engines from JSON ", e);
} }
} }
return engines; return engines;
} }
private void saveToSettings() { private void saveCacheToSettings() {
if (!Algorithms.isEmpty(cachedEngines)) { if (!Algorithms.isEmpty(cachedEngines)) {
try { try {
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
@ -217,38 +177,44 @@ public class OnlineRoutingHelper {
} }
} }
public static void readFromJson(JSONObject json, List<OnlineRoutingEngine> engines) throws JSONException { public static void readFromJson(@NonNull JSONObject json,
@NonNull List<OnlineRoutingEngine> engines) throws JSONException {
if (!json.has("items")) { if (!json.has("items")) {
return; return;
} }
Gson gson = new Gson(); Gson gson = new Gson();
Type type = new TypeToken<HashMap<String, String>>() { Type typeToken = new TypeToken<HashMap<String, String>>() {
}.getType(); }.getType();
JSONArray itemsJson = json.getJSONArray("items"); JSONArray itemsJson = json.getJSONArray(ITEMS);
for (int i = 0; i < itemsJson.length(); i++) { for (int i = 0; i < itemsJson.length(); i++) {
JSONObject object = itemsJson.getJSONObject(i); JSONObject object = itemsJson.getJSONObject(i);
String key = object.getString("key"); if (object.has(TYPE) && object.has(PARAMS)) {
String vehicleKey = object.getString("vehicle"); EngineType type = EngineType.getTypeByName(object.getString(TYPE));
EngineType engineType = EngineType.valueOf(object.getString("type")); String paramsString = object.getString(PARAMS);
String paramsString = object.getString("params"); HashMap<String, String> params = gson.fromJson(paramsString, typeToken);
HashMap<String, String> params = gson.fromJson(paramsString, type); OnlineRoutingEngine engine = OnlineRoutingFactory.createEngine(type, params);
engines.add(new OnlineRoutingEngine(key, engineType, vehicleKey, params)); if (!Algorithms.isEmpty(engine.getStringKey())) {
engines.add(engine);
}
}
} }
} }
public static void writeToJson(JSONObject json, List<OnlineRoutingEngine> engines) throws JSONException { public static void writeToJson(@NonNull JSONObject json,
@NonNull List<OnlineRoutingEngine> engines) throws JSONException {
JSONArray jsonArray = new JSONArray(); JSONArray jsonArray = new JSONArray();
Gson gson = new Gson(); Gson gson = new Gson();
Type type = new TypeToken<HashMap<String, String>>() { Type type = new TypeToken<HashMap<String, String>>() {
}.getType(); }.getType();
for (OnlineRoutingEngine engine : engines) { for (OnlineRoutingEngine engine : engines) {
if (Algorithms.isEmpty(engine.getStringKey())) {
continue;
}
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
jsonObject.put("key", engine.getStringKey()); jsonObject.put(TYPE, engine.getType().name());
jsonObject.put("type", engine.getType().name()); jsonObject.put(PARAMS, gson.toJson(engine.getParams(), type));
jsonObject.put("vehicle", engine.getVehicleKey());
jsonObject.put("params", gson.toJson(engine.getParams(), type));
jsonArray.put(jsonObject); jsonArray.put(jsonObject);
} }
json.put("items", jsonArray); json.put(ITEMS, jsonArray);
} }
} }

View file

@ -3,48 +3,26 @@ package net.osmand.plus.onlinerouting;
import android.content.Context; import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import net.osmand.plus.R; public class VehicleType {
import net.osmand.util.Algorithms; private final String key;
@StringRes
private final int titleId;
public enum VehicleType { public VehicleType(@NonNull String key,
CAR("car", R.string.routing_engine_vehicle_type_car), @StringRes int titleId) {
BIKE("bike", R.string.routing_engine_vehicle_type_bike),
FOOT("foot", R.string.routing_engine_vehicle_type_foot),
DRIVING("driving", R.string.routing_engine_vehicle_type_driving),
CUSTOM("", R.string.shared_string_custom);
VehicleType(String key, int titleId) {
this.key = key; this.key = key;
this.titleId = titleId; this.titleId = titleId;
} }
private String key; @NonNull
private int titleId;
public String getKey() { public String getKey() {
return key; return key;
} }
public String getTitle(Context ctx) { @NonNull
public String getTitle(@NonNull Context ctx) {
return ctx.getString(titleId); return ctx.getString(titleId);
} }
public static String toHumanString(@NonNull Context ctx,
@NonNull String key) {
VehicleType vehicleType = getVehicleByKey(key);
if (vehicleType == CUSTOM) {
return Algorithms.capitalizeFirstLetter(key);
}
return vehicleType.getTitle(ctx);
}
public static VehicleType getVehicleByKey(String key) {
for (VehicleType v : values()) {
if (Algorithms.objectEquals(v.getKey(), key)) {
return v;
}
}
return CUSTOM;
}
} }

View file

@ -0,0 +1,34 @@
package net.osmand.plus.onlinerouting.engine;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.util.Algorithms;
public enum EngineType {
GRAPHHOPPER("Graphhopper"),
OSRM("OSRM"),
ORS("Openroute Service");
private final String title;
EngineType(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
@NonNull
public static EngineType getTypeByName(@Nullable String name) {
if (!Algorithms.isEmpty(name)) {
for (EngineType type : values()) {
if (type.name().equals(name)) {
return type;
}
}
}
return values()[0];
}
}

View file

@ -0,0 +1,95 @@
package net.osmand.plus.onlinerouting.engine;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.data.LatLon;
import net.osmand.plus.R;
import net.osmand.plus.onlinerouting.EngineParameter;
import net.osmand.plus.onlinerouting.VehicleType;
import net.osmand.util.GeoPolylineParserUtil;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;
import java.util.Map;
import static net.osmand.util.Algorithms.isEmpty;
public class GraphhopperEngine extends OnlineRoutingEngine {
public GraphhopperEngine(@Nullable Map<String, String> params) {
super(params);
}
@Override
public @NonNull EngineType getType() {
return EngineType.GRAPHHOPPER;
}
@NonNull
@Override
public String getStandardUrl() {
return "https://graphhopper.com/api/1/route";
}
@Override
protected void collectAllowedParameters() {
allowParameters(EngineParameter.API_KEY);
}
@Override
protected void collectAllowedVehicles(@NonNull List<VehicleType> vehicles) {
vehicles.add(new VehicleType("car", R.string.routing_engine_vehicle_type_car));
vehicles.add(new VehicleType("bike", R.string.routing_engine_vehicle_type_bike));
vehicles.add(new VehicleType("foot", R.string.routing_engine_vehicle_type_foot));
vehicles.add(new VehicleType("hike", R.string.routing_engine_vehicle_type_hiking));
vehicles.add(new VehicleType("mtb", R.string.routing_engine_vehicle_type_mtb));
vehicles.add(new VehicleType("racingbike", R.string.routing_engine_vehicle_type_racingbike));
vehicles.add(new VehicleType("scooter", R.string.routing_engine_vehicle_type_scooter));
vehicles.add(new VehicleType("truck", R.string.routing_engine_vehicle_type_truck));
vehicles.add(new VehicleType("small_truck", R.string.routing_engine_vehicle_type_small_truck));
}
@Override
protected void makeFullUrl(@NonNull StringBuilder sb,
@NonNull List<LatLon> path) {
sb.append("?");
for (LatLon point : path) {
sb.append("point=")
.append(point.getLatitude())
.append(',')
.append(point.getLongitude())
.append('&');
}
String vehicle = get(EngineParameter.VEHICLE_KEY);
if (isEmpty(vehicle)) {
sb.append("vehicle=").append(vehicle);
}
String apiKey = get(EngineParameter.API_KEY);
if (isEmpty(apiKey)) {
sb.append('&').append("key=").append(apiKey);
}
}
@NonNull
@Override
public List<LatLon> parseServerResponse(@NonNull String content) throws JSONException {
JSONObject obj = new JSONObject(content);
return GeoPolylineParserUtil.parse(
obj.getJSONArray("paths").getJSONObject(0).getString("points"),
GeoPolylineParserUtil.PRECISION_5);
}
@Override
public boolean parseServerMessage(@NonNull StringBuilder sb,
@NonNull String content) throws JSONException {
JSONObject obj = new JSONObject(content);
if (obj.has("message")) {
String message = obj.getString("message");
sb.append(message);
}
return obj.has("paths");
}
}

View file

@ -0,0 +1,205 @@
package net.osmand.plus.onlinerouting.engine;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.data.LatLon;
import net.osmand.plus.R;
import net.osmand.plus.onlinerouting.EngineParameter;
import net.osmand.plus.onlinerouting.OnlineRoutingFactory;
import net.osmand.plus.onlinerouting.VehicleType;
import net.osmand.util.Algorithms;
import org.json.JSONException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static net.osmand.util.Algorithms.isEmpty;
public abstract class OnlineRoutingEngine implements Cloneable {
public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_";
public static final VehicleType CUSTOM_VEHICLE = new VehicleType("", R.string.shared_string_custom);
private final Map<String, String> params = new HashMap<>();
private final List<VehicleType> allowedVehicles = new ArrayList<>();
private final Set<EngineParameter> allowedParameters = new HashSet<>();
public OnlineRoutingEngine(@Nullable Map<String, String> params) {
if (!isEmpty(params)) {
this.params.putAll(params);
}
collectAllowedVehiclesInternal();
collectAllowedParametersInternal();
}
@NonNull
public abstract EngineType getType();
@Nullable
public String getStringKey() {
return get(EngineParameter.KEY);
}
@NonNull
public String getName(@NonNull Context ctx) {
String customName = get(EngineParameter.CUSTOM_NAME);
if (customName != null) {
return customName;
} else {
return getStandardName(ctx);
}
}
@NonNull
private String getStandardName(@NonNull Context ctx) {
String base = getBaseName(ctx);
String index = get(EngineParameter.NAME_INDEX);
return !isEmpty(index) ? base + " " + index : base;
}
@NonNull
public String getBaseName(@NonNull Context ctx) {
String vehicleTitle = getSelectedVehicleName(ctx);
if (isEmpty(vehicleTitle)) {
return getType().getTitle();
} else {
String pattern = ctx.getString(R.string.ltr_or_rtl_combine_via_dash);
return String.format(pattern, getType().getTitle(), vehicleTitle);
}
}
@NonNull
public String getBaseUrl() {
String customUrl = get(EngineParameter.CUSTOM_URL);
if (isEmpty(customUrl)) {
return getStandardUrl();
}
return customUrl;
}
@NonNull
public String getFullUrl(@NonNull List<LatLon> path) {
StringBuilder sb = new StringBuilder(getBaseUrl());
makeFullUrl(sb, path);
return sb.toString();
}
protected abstract void makeFullUrl(@NonNull StringBuilder sb,
@NonNull List<LatLon> path);
@NonNull
public abstract List<LatLon> parseServerResponse(@NonNull String content) throws JSONException;
@NonNull
public abstract String getStandardUrl();
@NonNull
public Map<String, String> getParams() {
return params;
}
@Nullable
public String get(@NonNull EngineParameter key) {
return params.get(key.name());
}
public void put(@NonNull EngineParameter key, @NonNull String value) {
params.put(key.name(), value);
}
public void remove(@NonNull EngineParameter key) {
params.remove(key.name());
}
private void collectAllowedVehiclesInternal() {
allowedVehicles.clear();
collectAllowedVehicles(allowedVehicles);
allowedVehicles.add(CUSTOM_VEHICLE);
}
protected abstract void collectAllowedVehicles(@NonNull List<VehicleType> vehicles);
@NonNull
public List<VehicleType> getAllowedVehicles() {
return Collections.unmodifiableList(allowedVehicles);
}
private void collectAllowedParametersInternal() {
allowedParameters.clear();
allowParameters(EngineParameter.KEY, EngineParameter.VEHICLE_KEY,
EngineParameter.CUSTOM_NAME, EngineParameter.NAME_INDEX, EngineParameter.CUSTOM_URL);
collectAllowedParameters();
}
protected abstract void collectAllowedParameters();
public boolean isParameterAllowed(EngineParameter key) {
return allowedParameters.contains(key);
}
protected void allowParameters(@NonNull EngineParameter ... allowedParams) {
allowedParameters.addAll(Arrays.asList(allowedParams));
}
@Nullable
private String getSelectedVehicleName(@NonNull Context ctx) {
String key = get(EngineParameter.VEHICLE_KEY);
VehicleType vt = getVehicleTypeByKey(key);
if (!vt.equals(CUSTOM_VEHICLE)) {
return vt.getTitle(ctx);
}
return key != null ? Algorithms.capitalizeFirstLetter(key) : null;
}
@NonNull
public VehicleType getSelectedVehicleType() {
String key = get(EngineParameter.VEHICLE_KEY);
return getVehicleTypeByKey(key);
}
@NonNull
public VehicleType getVehicleTypeByKey(@Nullable String vehicleKey) {
if (!isEmpty(vehicleKey)) {
for (VehicleType vt : allowedVehicles) {
if (Algorithms.objectEquals(vt.getKey(), vehicleKey)) {
return vt;
}
}
}
return CUSTOM_VEHICLE;
}
public abstract boolean parseServerMessage(@NonNull StringBuilder sb,
@NonNull String content) throws JSONException;
@NonNull
@Override
public Object clone() {
return OnlineRoutingFactory.createEngine(getType(), getParams());
}
@NonNull
public static String generateKey() {
return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof OnlineRoutingEngine)) return false;
OnlineRoutingEngine engine = (OnlineRoutingEngine) o;
if (getType() != engine.getType()) return false;
return Algorithms.objectEquals(getParams(), engine.getParams());
}
}

View file

@ -0,0 +1,104 @@
package net.osmand.plus.onlinerouting.engine;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.data.LatLon;
import net.osmand.plus.R;
import net.osmand.plus.onlinerouting.EngineParameter;
import net.osmand.plus.onlinerouting.VehicleType;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static net.osmand.util.Algorithms.isEmpty;
public class OrsEngine extends OnlineRoutingEngine {
public OrsEngine(@Nullable Map<String, String> params) {
super(params);
}
@Override
public @NonNull EngineType getType() {
return EngineType.ORS;
}
@NonNull
@Override
public String getStandardUrl() {
return "https://api.openrouteservice.org/v2/directions/";
}
@Override
protected void collectAllowedParameters() {
allowParameters(EngineParameter.API_KEY);
}
@Override
protected void collectAllowedVehicles(@NonNull List<VehicleType> vehicles) {
vehicles.add(new VehicleType("driving-car", R.string.routing_engine_vehicle_type_car));
vehicles.add(new VehicleType("driving-hgv", R.string.routing_engine_vehicle_type_hgv));
vehicles.add(new VehicleType("cycling-regular", R.string.routing_engine_vehicle_type_cycling_regular));
vehicles.add(new VehicleType("cycling-road", R.string.routing_engine_vehicle_type_cycling_road));
vehicles.add(new VehicleType("cycling-mountain", R.string.routing_engine_vehicle_type_cycling_mountain));
vehicles.add(new VehicleType("cycling-electric", R.string.routing_engine_vehicle_type_cycling_electric));
vehicles.add(new VehicleType("foot-walking", R.string.routing_engine_vehicle_type_walking));
vehicles.add(new VehicleType("foot-hiking", R.string.routing_engine_vehicle_type_hiking));
vehicles.add(new VehicleType("wheelchair", R.string.routing_engine_vehicle_type_wheelchair));
}
@Override
protected void makeFullUrl(@NonNull StringBuilder sb,
@NonNull List<LatLon> path) {
if (path.size() > 1) {
String vehicleKey = get(EngineParameter.VEHICLE_KEY);
if (!isEmpty(vehicleKey)) {
sb.append(vehicleKey);
}
sb.append('?');
String apiKey = get(EngineParameter.API_KEY);
if (!isEmpty(apiKey)) {
sb.append("api_key=").append(apiKey);
}
LatLon start = path.get(0);
LatLon end = path.get(path.size() - 1);
sb.append('&').append("start=")
.append(start.getLatitude()).append(',').append(start.getLongitude());
sb.append('&').append("end=")
.append(end.getLatitude()).append(',').append(end.getLongitude());
}
}
@NonNull
@Override
public List<LatLon> parseServerResponse(@NonNull String content) throws JSONException {
JSONObject obj = new JSONObject(content);
JSONArray array = obj.getJSONArray("features").getJSONObject(0)
.getJSONObject("geometry").getJSONArray("coordinates");
List<LatLon> track = new ArrayList<>();
for (int i = 0; i < array.length(); i++) {
JSONArray point = array.getJSONArray(i);
double lat = Double.parseDouble(point.getString(0));
double lon = Double.parseDouble(point.getString(1));
track.add(new LatLon(lat, lon));
}
return track;
}
@Override
public boolean parseServerMessage(@NonNull StringBuilder sb,
@NonNull String content) throws JSONException {
JSONObject obj = new JSONObject(content);
if (obj.has("error")) {
String message = obj.getString("error");
sb.append(message);
}
return obj.has("features");
}
}

View file

@ -0,0 +1,84 @@
package net.osmand.plus.onlinerouting.engine;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.data.LatLon;
import net.osmand.plus.R;
import net.osmand.plus.onlinerouting.EngineParameter;
import net.osmand.plus.onlinerouting.VehicleType;
import net.osmand.util.GeoPolylineParserUtil;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;
import java.util.Map;
import static net.osmand.util.Algorithms.isEmpty;
public class OsrmEngine extends OnlineRoutingEngine {
public OsrmEngine(@Nullable Map<String, String> params) {
super(params);
}
@Override
public @NonNull EngineType getType() {
return EngineType.OSRM;
}
@NonNull
@Override
public String getStandardUrl() {
return "https://router.project-osrm.org/route/v1/";
}
@Override
protected void collectAllowedParameters() { }
@Override
protected void collectAllowedVehicles(@NonNull List<VehicleType> vehicles) {
vehicles.add(new VehicleType("car", R.string.routing_engine_vehicle_type_car));
vehicles.add(new VehicleType("bike", R.string.routing_engine_vehicle_type_bike));
vehicles.add(new VehicleType("foot", R.string.routing_engine_vehicle_type_foot));
}
@Override
protected void makeFullUrl(@NonNull StringBuilder sb,
@NonNull List<LatLon> path) {
String vehicleKey = get(EngineParameter.VEHICLE_KEY);
if (!isEmpty(vehicleKey)) {
sb.append(vehicleKey).append('/');
}
for (int i = 0; i < path.size(); i++) {
LatLon point = path.get(i);
sb.append(point.getLongitude()).append(',').append(point.getLatitude());
if (i < path.size() - 1) {
sb.append(';');
}
}
sb.append('?');
sb.append("overview=full");
}
@NonNull
@Override
public List<LatLon> parseServerResponse(@NonNull String content) throws JSONException {
JSONObject obj = new JSONObject(content);
return GeoPolylineParserUtil.parse(
obj.getJSONArray("routes").getJSONObject(0).getString("geometry"),
GeoPolylineParserUtil.PRECISION_5);
}
@Override
public boolean parseServerMessage(@NonNull StringBuilder sb,
@NonNull String content) throws JSONException {
JSONObject obj = new JSONObject(content);
if (obj.has("message")) {
String message = obj.getString("message");
sb.append(message);
}
return obj.has("routes");
}
}

View file

@ -0,0 +1,52 @@
package net.osmand.plus.onlinerouting.ui;
import androidx.annotation.NonNull;
import net.osmand.data.LatLon;
public enum ExampleLocation {
AMSTERDAM("Amsterdam",
new LatLon(52.379189, 4.899431),
new LatLon(52.308056, 4.764167)),
BERLIN("Berlin",
new LatLon(52.520008, 13.404954),
new LatLon(52.3666652, 13.501997992)),
NEW_YORK("New York",
new LatLon(43.000000, -75.000000),
new LatLon(40.641766, -73.780968)),
PARIS("Paris",
new LatLon(48.864716, 2.349014),
new LatLon(48.948437, 2.434931));
ExampleLocation(@NonNull String name,
@NonNull LatLon cityCenterLatLon,
@NonNull LatLon cityAirportLatLon) {
this.name = name;
this.cityCenterLatLon = cityCenterLatLon;
this.cityAirportLatLon = cityAirportLatLon;
}
private String name;
private LatLon cityCenterLatLon;
private LatLon cityAirportLatLon;
@NonNull
public String getName() {
return name;
}
@NonNull
public LatLon getCityCenterLatLon() {
return cityCenterLatLon;
}
@NonNull
public LatLon getCityAirportLatLon() {
return cityAirportLatLon;
}
}

View file

@ -1,4 +1,4 @@
package net.osmand.plus.onlinerouting; package net.osmand.plus.onlinerouting.ui;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -10,6 +10,7 @@ import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -42,9 +43,12 @@ public class OnlineRoutingCard extends BaseCard {
private OsmandTextFieldBoxes textFieldBoxes; private OsmandTextFieldBoxes textFieldBoxes;
private EditText editText; private EditText editText;
private TextView tvHelperText; private TextView tvHelperText;
private TextView tvErrorText;
private View bottomDivider; private View bottomDivider;
private View button; private View button;
private OnTextChangedListener onTextChangedListener; private OnTextChangedListener onTextChangedListener;
private boolean fieldBoxHelperTextShowed;
private ApplicationMode appMode; private ApplicationMode appMode;
public OnlineRoutingCard(@NonNull MapActivity mapActivity, boolean nightMode, ApplicationMode appMode) { public OnlineRoutingCard(@NonNull MapActivity mapActivity, boolean nightMode, ApplicationMode appMode) {
@ -69,6 +73,7 @@ public class OnlineRoutingCard extends BaseCard {
textFieldBoxes = view.findViewById(R.id.field_box); textFieldBoxes = view.findViewById(R.id.field_box);
editText = view.findViewById(R.id.edit_text); editText = view.findViewById(R.id.edit_text);
tvHelperText = view.findViewById(R.id.helper_text); tvHelperText = view.findViewById(R.id.helper_text);
tvErrorText = view.findViewById(R.id.error_text);
bottomDivider = view.findViewById(R.id.bottom_divider); bottomDivider = view.findViewById(R.id.bottom_divider);
button = view.findViewById(R.id.button); button = view.findViewById(R.id.button);
@ -88,7 +93,7 @@ public class OnlineRoutingCard extends BaseCard {
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s) {
if (onTextChangedListener != null) { if (onTextChangedListener != null) {
boolean editedByUser = editText.getTag() == null; boolean editedByUser = editText.getTag() == null;
String text = editText.getText().toString(); String text = editText.getText().toString().trim();
onTextChangedListener.onTextChanged(editedByUser, text); onTextChangedListener.onTextChanged(editedByUser, text);
} }
} }
@ -115,9 +120,9 @@ public class OnlineRoutingCard extends BaseCard {
tvHeaderSubtitle.setText(subtitle); tvHeaderSubtitle.setText(subtitle);
} }
public void setSelectionMenu(List<HorizontalSelectionItem> items, public void setSelectionMenu(@NonNull List<HorizontalSelectionItem> items,
String selectedItemTitle, @NonNull String selectedItemTitle,
final CallbackWithObject<HorizontalSelectionItem> callback) { @NonNull final CallbackWithObject<HorizontalSelectionItem> callback) {
showElements(rvSelectionMenu); showElements(rvSelectionMenu);
rvSelectionMenu.setLayoutManager( rvSelectionMenu.setLayoutManager(
new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false)); new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false));
@ -152,15 +157,31 @@ public class OnlineRoutingCard extends BaseCard {
public void setFieldBoxHelperText(@NonNull String helperText) { public void setFieldBoxHelperText(@NonNull String helperText) {
showElements(fieldBoxContainer, tvHelperText); showElements(fieldBoxContainer, tvHelperText);
fieldBoxHelperTextShowed = true;
tvHelperText.setText(helperText); tvHelperText.setText(helperText);
} }
public void showFieldBoxError(@NonNull String errorText) {
showElements(fieldBoxContainer, tvErrorText);
hideElements(tvHelperText);
tvErrorText.setText(errorText);
}
public void hideFieldBoxError() {
hideElements(tvErrorText);
if (fieldBoxHelperTextShowed) {
showElements(tvHelperText);
}
}
public void setEditedText(@NonNull String text) { public void setEditedText(@NonNull String text) {
editText.setTag(""); // needed to indicate that the text was edited programmatically showElements(fieldBoxContainer);
editText.setTag(""); // indicate that the text was edited programmatically
editText.setText(text); editText.setText(text);
editText.setTag(null); editText.setTag(null);
} }
@NonNull
public String getEditedText() { public String getEditedText() {
return editText.getText().toString(); return editText.getText().toString();
} }
@ -169,7 +190,8 @@ public class OnlineRoutingCard extends BaseCard {
showElements(bottomDivider); showElements(bottomDivider);
} }
public void setButton(String title, OnClickListener listener) { public void setButton(@NonNull String title,
@NonNull OnClickListener listener) {
showElements(button); showElements(button);
button.setOnClickListener(listener); button.setOnClickListener(listener);
UiUtilities.setupDialogButton(nightMode, button, DialogButtonType.PRIMARY, title); UiUtilities.setupDialogButton(nightMode, button, DialogButtonType.PRIMARY, title);
@ -199,11 +221,11 @@ public class OnlineRoutingCard extends BaseCard {
AndroidUiHelper.setVisibility(View.GONE, views); AndroidUiHelper.setVisibility(View.GONE, views);
} }
public void setOnTextChangedListener(OnTextChangedListener onTextChangedListener) { public void setOnTextChangedListener(@Nullable OnTextChangedListener onTextChangedListener) {
this.onTextChangedListener = onTextChangedListener; this.onTextChangedListener = onTextChangedListener;
} }
public interface OnTextChangedListener { public interface OnTextChangedListener {
void onTextChanged(boolean editedByUser, String text); void onTextChanged(boolean editedByUser, @NonNull String text);
} }
} }

View file

@ -1,4 +1,4 @@
package net.osmand.plus.onlinerouting; package net.osmand.plus.onlinerouting.ui;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
@ -27,8 +27,6 @@ import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidNetworkUtils;
import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.CallbackWithObject; import net.osmand.CallbackWithObject;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
@ -39,39 +37,37 @@ import net.osmand.plus.UiUtilities.DialogButtonType;
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.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem;
import net.osmand.plus.onlinerouting.OnlineRoutingCard.OnTextChangedListener; import net.osmand.plus.onlinerouting.EngineParameter;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingFactory;
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
import net.osmand.plus.onlinerouting.VehicleType;
import net.osmand.plus.onlinerouting.ui.OnlineRoutingCard.OnTextChangedListener;
import net.osmand.plus.onlinerouting.engine.EngineType;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.BaseCard;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.CUSTOM_VEHICLE;
public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
public static final String TAG = OnlineRoutingEngineFragment.class.getSimpleName(); public static final String TAG = OnlineRoutingEngineFragment.class.getSimpleName();
private static final String ENGINE_NAME_KEY = "engine_name"; private static final String ENGINE_TYPE_KEY = "engine_type";
private static final String ENGINE_SERVER_KEY = "engine_server";
private static final String ENGINE_SERVER_URL_KEY = "engine_server_url";
private static final String ENGINE_VEHICLE_TYPE_KEY = "engine_vehicle_type";
private static final String ENGINE_CUSTOM_VEHICLE_KEY = "engine_custom_vehicle"; private static final String ENGINE_CUSTOM_VEHICLE_KEY = "engine_custom_vehicle";
private static final String ENGINE_API_KEY_KEY = "engine_api_key";
private static final String INIT_ENGINE_NAME_KEY = "init_engine_name";
private static final String INIT_ENGINE_SERVER_KEY = "init_engine_server";
private static final String INIT_ENGINE_SERVER_URL_KEY = "init_engine_server_url";
private static final String INIT_ENGINE_VEHICLE_TYPE_KEY = "init_engine_vehicle_type";
private static final String INIT_ENGINE_CUSTOM_VEHICLE_KEY = "init_engine_custom_vehicle";
private static final String INIT_ENGINE_API_KEY_KEY = "init_engine_api_key";
private static final String EXAMPLE_LOCATION_KEY = "example_location"; private static final String EXAMPLE_LOCATION_KEY = "example_location";
private static final String APP_MODE_KEY = "app_mode"; private static final String APP_MODE_KEY = "app_mode";
private static final String EDITED_ENGINE_KEY = "edited_engine_key"; private static final String EDITED_ENGINE_KEY = "edited_engine_key";
private OsmandApplication app; private OsmandApplication app;
private ApplicationMode appMode;
private MapActivity mapActivity; private MapActivity mapActivity;
private OnlineRoutingHelper helper; private OnlineRoutingHelper helper;
@ -83,66 +79,23 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
private OnlineRoutingCard apiKeyCard; private OnlineRoutingCard apiKeyCard;
private OnlineRoutingCard exampleCard; private OnlineRoutingCard exampleCard;
private View testResultsContainer; private View testResultsContainer;
private View saveButton;
private ScrollView scrollView; private ScrollView scrollView;
private OnGlobalLayoutListener onGlobalLayout; private OnGlobalLayoutListener onGlobalLayout;
private boolean isKeyboardShown = false; private boolean isKeyboardShown = false;
private ApplicationMode appMode; private OnlineRoutingEngine engine;
private OnlineRoutingEngine initEngine;
private OnlineRoutingEngineObject engine; private String customVehicleKey;
private OnlineRoutingEngineObject initEngine;
private ExampleLocation selectedLocation; private ExampleLocation selectedLocation;
private String editedEngineKey; private String editedEngineKey;
private enum ExampleLocation {
AMSTERDAM("Amsterdam",
new LatLon(52.379189, 4.899431),
new LatLon(52.308056, 4.764167)),
BERLIN("Berlin",
new LatLon(52.520008, 13.404954),
new LatLon(52.3666652, 13.501997992)),
NEW_YORK("New York",
new LatLon(43.000000, -75.000000),
new LatLon(40.641766, -73.780968)),
PARIS("Paris",
new LatLon(48.864716, 2.349014),
new LatLon(48.948437, 2.434931));
ExampleLocation(String name, LatLon cityCenterLatLon, LatLon cityAirportLatLon) {
this.name = name;
this.cityCenterLatLon = cityCenterLatLon;
this.cityAirportLatLon = cityAirportLatLon;
}
private String name;
private LatLon cityCenterLatLon;
private LatLon cityAirportLatLon;
public String getName() {
return name;
}
public LatLon getCityCenterLatLon() {
return cityCenterLatLon;
}
public LatLon getCityAirportLatLon() {
return cityAirportLatLon;
}
}
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
app = requireMyApplication(); app = requireMyApplication();
mapActivity = getMapActivity(); mapActivity = getMapActivity();
helper = app.getOnlineRoutingHelper(); helper = app.getOnlineRoutingHelper();
engine = new OnlineRoutingEngineObject();
initEngine = new OnlineRoutingEngineObject();
if (savedInstanceState != null) { if (savedInstanceState != null) {
restoreState(savedInstanceState); restoreState(savedInstanceState);
} else { } else {
@ -179,10 +132,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
setupApiKeyCard(); setupApiKeyCard();
setupExampleCard(); setupExampleCard();
setupResultsContainer(); setupResultsContainer();
addSpaceSegment();
setupButtons(); setupButtons();
generateUniqueNameIfNeeded();
updateCardViews(nameCard, typeCard, vehicleCard, exampleCard); updateCardViews(nameCard, typeCard, vehicleCard, exampleCard);
scrollView.setOnTouchListener(new View.OnTouchListener() { scrollView.setOnTouchListener(new View.OnTouchListener() {
@ -250,13 +202,33 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
return view; return view;
} }
private void setupToolbar(Toolbar toolbar) {
ImageView navigationIcon = toolbar.findViewById(R.id.close_button);
navigationIcon.setImageResource(R.drawable.ic_action_close);
navigationIcon.setOnClickListener(new OnClickListener() {
@Override @Override
public void onDestroyView() { public void onClick(View v) {
super.onDestroyView(); showExitDialog();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { }
view.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayout); });
TextView title = toolbar.findViewById(R.id.toolbar_title);
toolbar.findViewById(R.id.toolbar_subtitle).setVisibility(View.GONE);
View actionBtn = toolbar.findViewById(R.id.action_button);
if (isEditingMode()) {
title.setText(getString(R.string.edit_online_routing_engine));
ImageView ivBtn = toolbar.findViewById(R.id.action_button_icon);
ivBtn.setImageDrawable(
getIcon(R.drawable.ic_action_delete_dark, R.color.color_osm_edit_delete));
actionBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onDeleteEngine();
dismiss();
}
});
} else { } else {
view.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayout); title.setText(getString(R.string.add_online_routing_engine));
actionBtn.setVisibility(View.GONE);
} }
} }
@ -268,9 +240,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
nameCard.setFieldBoxLabelText(getString(R.string.shared_string_name)); nameCard.setFieldBoxLabelText(getString(R.string.shared_string_name));
nameCard.setOnTextChangedListener(new OnTextChangedListener() { nameCard.setOnTextChangedListener(new OnTextChangedListener() {
@Override @Override
public void onTextChanged(boolean changedByUser, String text) { public void onTextChanged(boolean changedByUser, @NonNull String text) {
if (changedByUser) { if (changedByUser) {
engine.customName = text; engine.put(EngineParameter.CUSTOM_NAME, text);
checkCustomNameUnique(engine);
} }
} }
}); });
@ -286,14 +259,13 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
for (EngineType server : EngineType.values()) { for (EngineType server : EngineType.values()) {
serverItems.add(new HorizontalSelectionItem(server.getTitle(), server)); serverItems.add(new HorizontalSelectionItem(server.getTitle(), server));
} }
typeCard.setSelectionMenu(serverItems, engine.type.getTitle(), typeCard.setSelectionMenu(serverItems, engine.getType().getTitle(),
new CallbackWithObject<HorizontalSelectionItem>() { new CallbackWithObject<HorizontalSelectionItem>() {
@Override @Override
public boolean processResult(HorizontalSelectionItem result) { public boolean processResult(HorizontalSelectionItem result) {
EngineType type = (EngineType) result.getObject(); EngineType type = (EngineType) result.getObject();
if (engine.type != type) { if (engine.getType() != type) {
engine.type = type; changeEngineType(type);
updateCardViews(nameCard, typeCard, exampleCard);
return true; return true;
} }
return false; return false;
@ -301,9 +273,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
}); });
typeCard.setOnTextChangedListener(new OnTextChangedListener() { typeCard.setOnTextChangedListener(new OnTextChangedListener() {
@Override @Override
public void onTextChanged(boolean editedByUser, String text) { public void onTextChanged(boolean editedByUser, @NonNull String text) {
if (editedByUser) { if (editedByUser) {
engine.customServerUrl = text; engine.put(EngineParameter.CUSTOM_URL, text);
updateCardViews(exampleCard); updateCardViews(exampleCard);
} }
} }
@ -317,37 +289,44 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
vehicleCard = new OnlineRoutingCard(mapActivity, isNightMode(), appMode); vehicleCard = new OnlineRoutingCard(mapActivity, isNightMode(), appMode);
vehicleCard.build(mapActivity); vehicleCard.build(mapActivity);
vehicleCard.setHeaderTitle(getString(R.string.shared_string_vehicle)); vehicleCard.setHeaderTitle(getString(R.string.shared_string_vehicle));
vehicleCard.setFieldBoxLabelText(getString(R.string.shared_string_custom));
vehicleCard.setOnTextChangedListener(new OnTextChangedListener() {
@Override
public void onTextChanged(boolean editedByUser, @NonNull String text) {
if (editedByUser) {
customVehicleKey = text;
engine.put(EngineParameter.VEHICLE_KEY, customVehicleKey);
updateCardViews(nameCard, exampleCard);
}
}
});
vehicleCard.setEditedText(customVehicleKey);
vehicleCard.setFieldBoxHelperText(getString(R.string.shared_string_enter_param));
vehicleCard.showDivider();
segmentsContainer.addView(vehicleCard.getView());
setupVehicleTypes();
}
private void setupVehicleTypes() {
List<HorizontalSelectionItem> vehicleItems = new ArrayList<>(); List<HorizontalSelectionItem> vehicleItems = new ArrayList<>();
for (VehicleType vehicle : VehicleType.values()) { for (VehicleType vehicle : engine.getAllowedVehicles()) {
vehicleItems.add(new HorizontalSelectionItem(vehicle.getTitle(app), vehicle)); vehicleItems.add(new HorizontalSelectionItem(vehicle.getTitle(app), vehicle));
} }
vehicleCard.setSelectionMenu(vehicleItems, engine.vehicleType.getTitle(app), vehicleCard.setSelectionMenu(vehicleItems, engine.getSelectedVehicleType().getTitle(app),
new CallbackWithObject<HorizontalSelectionItem>() { new CallbackWithObject<HorizontalSelectionItem>() {
@Override @Override
public boolean processResult(HorizontalSelectionItem result) { public boolean processResult(HorizontalSelectionItem result) {
VehicleType vehicle = (VehicleType) result.getObject(); VehicleType vehicle = (VehicleType) result.getObject();
if (engine.vehicleType != vehicle) { if (!Algorithms.objectEquals(engine.getSelectedVehicleType(), vehicle)) {
engine.vehicleType = vehicle; String vehicleKey = vehicle.equals(CUSTOM_VEHICLE) ? customVehicleKey : vehicle.getKey();
engine.put(EngineParameter.VEHICLE_KEY, vehicleKey);
generateUniqueNameIfNeeded();
updateCardViews(nameCard, vehicleCard, exampleCard); updateCardViews(nameCard, vehicleCard, exampleCard);
return true; return true;
} }
return false; return false;
} }
}); });
vehicleCard.setFieldBoxLabelText(getString(R.string.shared_string_custom));
vehicleCard.setOnTextChangedListener(new OnTextChangedListener() {
@Override
public void onTextChanged(boolean editedByUser, String text) {
if (editedByUser) {
engine.customVehicleKey = text;
updateCardViews(nameCard, exampleCard);
}
}
});
vehicleCard.setEditedText(engine.customVehicleKey);
vehicleCard.setFieldBoxHelperText(getString(R.string.shared_string_enter_param));
vehicleCard.showDivider();
segmentsContainer.addView(vehicleCard.getView());
} }
private void setupApiKeyCard() { private void setupApiKeyCard() {
@ -355,12 +334,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
apiKeyCard.build(mapActivity); apiKeyCard.build(mapActivity);
apiKeyCard.setHeaderTitle(getString(R.string.shared_string_api_key)); apiKeyCard.setHeaderTitle(getString(R.string.shared_string_api_key));
apiKeyCard.setFieldBoxLabelText(getString(R.string.keep_it_empty_if_not)); apiKeyCard.setFieldBoxLabelText(getString(R.string.keep_it_empty_if_not));
apiKeyCard.setEditedText(engine.apiKey); String apiKey = engine.get(EngineParameter.API_KEY);
if (apiKey != null) {
apiKeyCard.setEditedText(apiKey);
}
apiKeyCard.showDivider(); apiKeyCard.showDivider();
apiKeyCard.setOnTextChangedListener(new OnTextChangedListener() { apiKeyCard.setOnTextChangedListener(new OnTextChangedListener() {
@Override @Override
public void onTextChanged(boolean editedByUser, String text) { public void onTextChanged(boolean editedByUser, @NonNull String text) {
engine.apiKey = text; engine.put(EngineParameter.API_KEY, text);
updateCardViews(exampleCard); updateCardViews(exampleCard);
} }
}); });
@ -402,87 +384,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
private void setupResultsContainer() { private void setupResultsContainer() {
testResultsContainer = getInflater().inflate( testResultsContainer = getInflater().inflate(
R.layout.bottom_sheet_item_with_descr_64dp, segmentsContainer, false); R.layout.bottom_sheet_item_with_descr_64dp, segmentsContainer, false);
testResultsContainer.setVisibility(View.GONE); testResultsContainer.setVisibility(View.INVISIBLE);
segmentsContainer.addView(testResultsContainer); segmentsContainer.addView(testResultsContainer);
} }
private void addSpaceSegment() {
int space = (int) getResources().getDimension(R.dimen.empty_state_text_button_padding_top);
View bottomSpaceView = new View(app);
bottomSpaceView.setLayoutParams(
new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, space));
segmentsContainer.addView(bottomSpaceView);
}
private void setupToolbar(Toolbar toolbar) {
ImageView navigationIcon = toolbar.findViewById(R.id.close_button);
navigationIcon.setImageResource(R.drawable.ic_action_close);
navigationIcon.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
showExitDialog();
}
});
TextView title = toolbar.findViewById(R.id.toolbar_title);
toolbar.findViewById(R.id.toolbar_subtitle).setVisibility(View.GONE);
View actionBtn = toolbar.findViewById(R.id.action_button);
if (isEditingMode()) {
title.setText(getString(R.string.edit_online_routing_engine));
ImageView ivBtn = toolbar.findViewById(R.id.action_button_icon);
ivBtn.setImageDrawable(
getIcon(R.drawable.ic_action_delete_dark, R.color.color_osm_edit_delete));
actionBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
deleteEngine();
dismiss();
}
});
} else {
title.setText(getString(R.string.add_online_routing_engine));
actionBtn.setVisibility(View.GONE);
}
}
private void updateCardViews(BaseCard... cardsToUpdate) {
for (BaseCard card : cardsToUpdate) {
if (nameCard.equals(card)) {
if (Algorithms.isEmpty(engine.customName)) {
String name;
if (Algorithms.isEmpty(engine.getVehicleKey())) {
name = engine.type.getTitle();
} else {
name = OnlineRoutingEngine.getStandardName(app, engine.type, engine.getVehicleKey());
}
nameCard.setEditedText(name);
}
} else if (typeCard.equals(card)) {
typeCard.setHeaderSubtitle(engine.type.getTitle());
typeCard.setEditedText(engine.getBaseUrl());
if (engine.type == EngineType.GRAPHHOPPER || engine.type == EngineType.ORS) {
apiKeyCard.show();
} else {
apiKeyCard.hide();
}
} else if (vehicleCard.equals(card)) {
VehicleType vt = VehicleType.getVehicleByKey(engine.getVehicleKey());
vehicleCard.setHeaderSubtitle(vt.getTitle(app));
if (vt == VehicleType.CUSTOM) {
vehicleCard.showFieldBox();
vehicleCard.setEditedText(engine.getVehicleKey());
} else {
vehicleCard.hideFieldBox();
}
int contentPadding = getResources().getDimensionPixelSize(R.dimen.content_padding);
vehicleCard.updateBottomMarginSelectionMenu(engine.vehicleType != VehicleType.CUSTOM ? 0 : contentPadding);
} else if (exampleCard.equals(card)) {
exampleCard.setEditedText(getTestUrl());
}
}
}
private void setupButtons() { private void setupButtons() {
boolean nightMode = isNightMode(); boolean nightMode = isNightMode();
View cancelButton = view.findViewById(R.id.dismiss_button); View cancelButton = view.findViewById(R.id.dismiss_button);
@ -497,80 +402,123 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
view.findViewById(R.id.buttons_divider).setVisibility(View.VISIBLE); view.findViewById(R.id.buttons_divider).setVisibility(View.VISIBLE);
View saveButton = view.findViewById(R.id.right_bottom_button); saveButton = view.findViewById(R.id.right_bottom_button);
UiUtilities.setupDialogButton(nightMode, saveButton, UiUtilities.setupDialogButton(nightMode, saveButton,
UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_save); UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_save);
saveButton.setVisibility(View.VISIBLE); saveButton.setVisibility(View.VISIBLE);
saveButton.setOnClickListener(new OnClickListener() { saveButton.setOnClickListener(new OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
saveChanges(); onSaveEngine();
dismiss(); dismiss();
} }
}); });
} }
private void saveChanges() { private void changeEngineType(EngineType type) {
OnlineRoutingEngine engineToSave; OnlineRoutingEngine tmp = (OnlineRoutingEngine) engine.clone();
if (isEditingMode()) { engine = OnlineRoutingFactory.createEngine(type, tmp.getParams());
engineToSave = new OnlineRoutingEngine(editedEngineKey, engine.type, engine.getVehicleKey());
// after changing the type, select the vehicle
// with the same name that was selected before
VehicleType previous = tmp.getSelectedVehicleType();
VehicleType next = null;
for (VehicleType vt : engine.getAllowedVehicles()) {
if (Algorithms.objectEquals(previous.getTitle(app), vt.getTitle(app))) {
next = vt;
break;
}
}
String vehicleKey;
if (next != null) {
vehicleKey = next.equals(CUSTOM_VEHICLE) ? customVehicleKey : next.getKey();
} else { } else {
engineToSave = OnlineRoutingEngine.createNewEngine(engine.type, engine.getVehicleKey(), null); vehicleKey = engine.getAllowedVehicles().get(0).getKey();
}
engine.put(EngineParameter.VEHICLE_KEY, vehicleKey);
setupVehicleTypes();
generateUniqueNameIfNeeded();
updateCardViews(nameCard, typeCard, vehicleCard, exampleCard);
} }
engineToSave.putParameter(EngineParameter.CUSTOM_NAME, engine.customName); private void generateUniqueNameIfNeeded() {
engineToSave.putParameter(EngineParameter.CUSTOM_URL, engine.customServerUrl); if (engine.get(EngineParameter.CUSTOM_NAME) == null) {
if (engine.type == EngineType.GRAPHHOPPER || engine.type == EngineType.ORS) { engine.remove(EngineParameter.NAME_INDEX);
engineToSave.putParameter(EngineParameter.API_KEY, engine.apiKey); if (hasNameDuplicate(engine.getName(app))) {
int index = 0;
do {
engine.put(EngineParameter.NAME_INDEX, String.valueOf(++index));
} while (hasNameDuplicate(engine.getName(app)));
}
}
} }
helper.saveEngine(engineToSave); private void checkCustomNameUnique(@NonNull OnlineRoutingEngine engine) {
if (hasNameDuplicate(engine.getName(app))) {
nameCard.showFieldBoxError(getString(R.string.message_name_is_already_exists));
saveButton.setEnabled(false);
} else {
nameCard.hideFieldBoxError();
saveButton.setEnabled(true);
}
} }
private void deleteEngine() { private boolean hasNameDuplicate(@NonNull String name) {
helper.deleteEngine(editedEngineKey); for (OnlineRoutingEngine engine : helper.getEnginesExceptMentioned(editedEngineKey)) {
if (Algorithms.objectEquals(engine.getName(app), name)) {
return true;
}
}
return false;
}
private void onSaveEngine() {
if (engine != null) {
helper.saveEngine(engine);
}
}
private void onDeleteEngine() {
helper.deleteEngine(engine);
}
private boolean isEditingMode() {
return editedEngineKey != null;
} }
private String getTestUrl() { private String getTestUrl() {
List<LatLon> path = new ArrayList<>(); List<LatLon> path = new ArrayList<>();
path.add(selectedLocation.getCityCenterLatLon()); path.add(selectedLocation.getCityCenterLatLon());
path.add(selectedLocation.getCityAirportLatLon()); path.add(selectedLocation.getCityAirportLatLon());
OnlineRoutingEngine tmpEngine = return engine.getFullUrl(path);
OnlineRoutingEngine.createNewEngine(engine.type, engine.getVehicleKey(), null);
tmpEngine.putParameter(EngineParameter.CUSTOM_URL, engine.customServerUrl);
tmpEngine.putParameter(EngineParameter.API_KEY, engine.apiKey);
return helper.createFullUrl(tmpEngine, path);
} }
private void testEngineWork() { private void testEngineWork() {
final EngineType type = engine.type; final OnlineRoutingEngine requestedEngine = (OnlineRoutingEngine) engine.clone();
final ExampleLocation location = selectedLocation; final ExampleLocation location = selectedLocation;
AndroidNetworkUtils.sendRequestAsync(app, exampleCard.getEditedText(), null, new Thread(new Runnable() {
null, false, false, new OnRequestResultListener() {
@Override @Override
public void onResult(String response) { public void run() {
StringBuilder message = new StringBuilder();
boolean resultOk = false; boolean resultOk = false;
if (response != null) {
try { try {
JSONObject obj = new JSONObject(response); String response = helper.makeRequest(exampleCard.getEditedText());
resultOk = requestedEngine.parseServerMessage(message, response);
if (type == EngineType.GRAPHHOPPER) { } catch (IOException | JSONException e) {
resultOk = obj.has("paths"); message.append(e.toString());
} else if (type == EngineType.OSRM) {
resultOk = obj.has("routes");
} else if (type == EngineType.ORS) {
resultOk = obj.has("features");
} }
} catch (JSONException e) { showTestResults(resultOk, message.toString(), location);
} }
} }).start();
showTestResults(resultOk, location);
}
});
} }
private void showTestResults(boolean resultOk, ExampleLocation location) { private void showTestResults(final boolean resultOk,
final @NonNull String message,
final @NonNull ExampleLocation location) {
app.runInUIThread(new Runnable() {
@Override
public void run() {
testResultsContainer.setVisibility(View.VISIBLE); testResultsContainer.setVisibility(View.VISIBLE);
ImageView ivImage = testResultsContainer.findViewById(R.id.icon); ImageView ivImage = testResultsContainer.findViewById(R.id.icon);
TextView tvTitle = testResultsContainer.findViewById(R.id.title); TextView tvTitle = testResultsContainer.findViewById(R.id.title);
@ -580,89 +528,41 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
tvTitle.setText(getString(R.string.shared_string_ok)); tvTitle.setText(getString(R.string.shared_string_ok));
} else { } else {
ivImage.setImageDrawable(getContentIcon(R.drawable.ic_action_alert)); ivImage.setImageDrawable(getContentIcon(R.drawable.ic_action_alert));
tvTitle.setText(getString(R.string.message_error_recheck_parameters)); tvTitle.setText(String.format(getString(R.string.message_server_error), message));
} }
tvDescription.setText(location.getName()); tvDescription.setText(location.getName());
} }
});
private boolean isEditingMode() {
return editedEngineKey != null;
} }
@Override private void updateCardViews(@NonNull BaseCard... cardsToUpdate) {
public void onSaveInstanceState(@NonNull Bundle outState) { for (BaseCard card : cardsToUpdate) {
super.onSaveInstanceState(outState); if (nameCard.equals(card)) {
saveState(outState); if (Algorithms.isEmpty(engine.get(EngineParameter.CUSTOM_NAME))) {
nameCard.setEditedText(engine.getName(app));
} }
private void saveState(Bundle outState) { } else if (typeCard.equals(card)) {
outState.putString(ENGINE_NAME_KEY, engine.customName); typeCard.setHeaderSubtitle(engine.getType().getTitle());
outState.putString(ENGINE_SERVER_KEY, engine.type.name()); typeCard.setEditedText(engine.getBaseUrl());
outState.putString(ENGINE_SERVER_URL_KEY, engine.customServerUrl); if (engine.isParameterAllowed(EngineParameter.API_KEY)) {
outState.putString(ENGINE_VEHICLE_TYPE_KEY, engine.vehicleType.name()); apiKeyCard.show();
outState.putString(ENGINE_CUSTOM_VEHICLE_KEY, engine.customVehicleKey); } else {
outState.putString(ENGINE_API_KEY_KEY, engine.apiKey); apiKeyCard.hide();
outState.putString(INIT_ENGINE_NAME_KEY, initEngine.customName);
outState.putString(INIT_ENGINE_SERVER_KEY, initEngine.type.name());
outState.putString(INIT_ENGINE_SERVER_URL_KEY, initEngine.customServerUrl);
outState.putString(INIT_ENGINE_VEHICLE_TYPE_KEY, initEngine.vehicleType.name());
outState.putString(INIT_ENGINE_CUSTOM_VEHICLE_KEY, initEngine.customVehicleKey);
outState.putString(INIT_ENGINE_API_KEY_KEY, initEngine.apiKey);
outState.putString(EXAMPLE_LOCATION_KEY, selectedLocation.name());
if (appMode != null) {
outState.putString(APP_MODE_KEY, appMode.getStringKey());
}
outState.putString(EDITED_ENGINE_KEY, editedEngineKey);
} }
private void restoreState(Bundle savedState) { } else if (vehicleCard.equals(card)) {
engine.customName = savedState.getString(ENGINE_NAME_KEY); VehicleType vt = engine.getSelectedVehicleType();
engine.type = EngineType.valueOf(savedState.getString(ENGINE_SERVER_KEY)); vehicleCard.setHeaderSubtitle(vt.getTitle(app));
engine.customServerUrl = savedState.getString(ENGINE_SERVER_URL_KEY); if (vt.equals(CUSTOM_VEHICLE)) {
engine.vehicleType = VehicleType.valueOf(savedState.getString(ENGINE_VEHICLE_TYPE_KEY)); vehicleCard.showFieldBox();
engine.customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY); vehicleCard.setEditedText(customVehicleKey);
engine.apiKey = savedState.getString(ENGINE_API_KEY_KEY); } else {
initEngine.customName = savedState.getString(INIT_ENGINE_NAME_KEY); vehicleCard.hideFieldBox();
initEngine.type = EngineType.valueOf(savedState.getString(INIT_ENGINE_SERVER_KEY));
initEngine.customServerUrl = savedState.getString(INIT_ENGINE_SERVER_URL_KEY);
initEngine.vehicleType = VehicleType.valueOf(savedState.getString(INIT_ENGINE_VEHICLE_TYPE_KEY));
initEngine.customVehicleKey = savedState.getString(INIT_ENGINE_CUSTOM_VEHICLE_KEY);
initEngine.apiKey = savedState.getString(INIT_ENGINE_API_KEY_KEY);
selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY));
appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null);
editedEngineKey = savedState.getString(EDITED_ENGINE_KEY);
} }
private void initState() { } else if (exampleCard.equals(card)) {
engine.type = EngineType.values()[0]; exampleCard.setEditedText(getTestUrl());
engine.vehicleType = VehicleType.values()[0];
selectedLocation = ExampleLocation.values()[0];
if (isEditingMode()) {
OnlineRoutingEngine editedEngine = helper.getEngineByKey(editedEngineKey);
if (editedEngine != null) {
engine.customName = editedEngine.getParameter(EngineParameter.CUSTOM_NAME);
engine.type = editedEngine.getType();
String vehicleKey = editedEngine.getVehicleKey();
if (vehicleKey != null) {
VehicleType vehicleType = VehicleType.getVehicleByKey(vehicleKey);
if (vehicleType == VehicleType.CUSTOM) {
engine.customVehicleKey = vehicleKey;
}
engine.vehicleType = vehicleType;
}
engine.apiKey = editedEngine.getParameter(EngineParameter.API_KEY);
}
}
engine.cloneIn(initEngine);
}
private void dismiss() {
FragmentActivity activity = getActivity();
if (activity != null) {
FragmentManager fragmentManager = activity.getSupportFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack();
} }
} }
} }
@ -670,9 +570,6 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
public void showExitDialog() { public void showExitDialog() {
View focus = view.findFocus(); View focus = view.findFocus();
AndroidUtils.hideSoftKeyboard(mapActivity, focus); AndroidUtils.hideSoftKeyboard(mapActivity, focus);
if (engine.customName != null && initEngine.customName == null) {
initEngine.customName = initEngine.getName(app);
}
if (!engine.equals(initEngine)) { if (!engine.equals(initEngine)) {
AlertDialog.Builder dismissDialog = createWarningDialog(mapActivity, AlertDialog.Builder dismissDialog = createWarningDialog(mapActivity,
R.string.shared_string_dismiss, R.string.exit_without_saving, R.string.shared_string_cancel); R.string.shared_string_dismiss, R.string.exit_without_saving, R.string.shared_string_cancel);
@ -697,8 +594,23 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
return warningDialog; return warningDialog;
} }
private void dismiss() {
FragmentActivity activity = getActivity();
if (activity != null) {
FragmentManager fragmentManager = activity.getSupportFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack();
}
}
}
private boolean isNightMode() { private boolean isNightMode() {
return !app.getSettings().isLightContentForMode(appMode); return !app.getSettings().isLightContentForMode(getAppMode());
}
@NonNull
private ApplicationMode getAppMode() {
return appMode != null ? appMode : app.getSettings().getApplicationMode();
} }
@Nullable @Nullable
@ -715,9 +627,83 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
return UiUtilities.getInflater(mapActivity, isNightMode()); return UiUtilities.getInflater(mapActivity, isNightMode());
} }
@Override
public void onDestroyView() {
super.onDestroyView();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayout);
} else {
view.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayout);
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
saveState(outState);
}
private void saveState(@NonNull Bundle outState) {
outState.putString(ENGINE_TYPE_KEY, engine.getType().name());
for (EngineParameter key : EngineParameter.values()) {
String value = engine.get(key);
if (value != null) {
outState.putString(key.name(), value);
}
}
outState.putString(ENGINE_CUSTOM_VEHICLE_KEY, customVehicleKey);
outState.putString(EXAMPLE_LOCATION_KEY, selectedLocation.name());
outState.putString(APP_MODE_KEY, getAppMode().getStringKey());
outState.putString(EDITED_ENGINE_KEY, editedEngineKey);
}
private void restoreState(@NonNull Bundle savedState) {
initEngine = createInitStateEngine();
String typeKey = savedState.getString(ENGINE_TYPE_KEY);
EngineType type = EngineType.getTypeByName(typeKey);
engine = OnlineRoutingFactory.createEngine(type);
for (EngineParameter key : EngineParameter.values()) {
String value = savedState.getString(key.name());
if (value != null) {
engine.put(key, value);
}
}
customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY);
selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY));
appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null);
editedEngineKey = savedState.getString(EngineParameter.KEY.name());
}
private void initState() {
initEngine = createInitStateEngine();
selectedLocation = ExampleLocation.values()[0];
engine = (OnlineRoutingEngine) initEngine.clone();
if (Algorithms.objectEquals(engine.getSelectedVehicleType(), CUSTOM_VEHICLE)) {
customVehicleKey = engine.get(EngineParameter.VEHICLE_KEY);
} else {
customVehicleKey = "";
}
}
private OnlineRoutingEngine createInitStateEngine() {
OnlineRoutingEngine engine;
OnlineRoutingEngine editedEngine = helper.getEngineByKey(editedEngineKey);
if (editedEngine != null) {
engine = (OnlineRoutingEngine) editedEngine.clone();
} else {
engine = OnlineRoutingFactory.createEngine(EngineType.values()[0]);
String vehicle = engine.getAllowedVehicles().get(0).getKey();
engine.put(EngineParameter.VEHICLE_KEY, vehicle);
if (editedEngineKey != null) {
engine.put(EngineParameter.KEY, editedEngineKey);
}
}
return engine;
}
public static void showInstance(@NonNull FragmentActivity activity, public static void showInstance(@NonNull FragmentActivity activity,
@NonNull ApplicationMode appMode, @NonNull ApplicationMode appMode,
String editedEngineKey) { @Nullable String editedEngineKey) {
FragmentManager fm = activity.getSupportFragmentManager(); FragmentManager fm = activity.getSupportFragmentManager();
if (!fm.isStateSaved() && fm.findFragmentByTag(OnlineRoutingEngineFragment.TAG) == null) { if (!fm.isStateSaved() && fm.findFragmentByTag(OnlineRoutingEngineFragment.TAG) == null) {
OnlineRoutingEngineFragment fragment = new OnlineRoutingEngineFragment(); OnlineRoutingEngineFragment fragment = new OnlineRoutingEngineFragment();
@ -728,57 +714,4 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
.addToBackStack(TAG).commitAllowingStateLoss(); .addToBackStack(TAG).commitAllowingStateLoss();
} }
} }
private static class OnlineRoutingEngineObject {
private String customName;
private EngineType type;
private String customServerUrl;
private VehicleType vehicleType;
private String customVehicleKey;
private String apiKey;
public String getVehicleKey() {
if (vehicleType == VehicleType.CUSTOM) {
return customVehicleKey;
}
return vehicleType.getKey();
}
public String getName(Context ctx) {
if (customName != null) {
return customName;
}
return OnlineRoutingEngine.getStandardName(ctx, type, getVehicleKey());
}
public String getBaseUrl() {
if (Algorithms.isEmpty(customServerUrl)) {
return type.getStandardUrl();
}
return customServerUrl;
}
public void cloneIn(OnlineRoutingEngineObject clone) {
clone.customName = customName;
clone.type = type;
clone.customServerUrl = customServerUrl;
clone.vehicleType = vehicleType;
clone.customVehicleKey = customVehicleKey;
clone.apiKey = apiKey;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
OnlineRoutingEngineObject engine = (OnlineRoutingEngineObject) obj;
if (!Algorithms.stringsEqual(customName, engine.customName)) return false;
if (type != engine.type) return false;
if (!Algorithms.stringsEqual(getBaseUrl(), engine.getBaseUrl())) return false;
if (vehicleType != engine.vehicleType) return false;
if (!Algorithms.stringsEqual(getVehicleKey(), engine.getVehicleKey())) return false;
return Algorithms.isEmpty(apiKey) ? Algorithms.isEmpty(engine.apiKey) : Algorithms.stringsEqual(apiKey, engine.apiKey);
}
}
} }

View file

@ -1,12 +1,27 @@
package net.osmand.plus.profiles; package net.osmand.plus.profiles;
import androidx.annotation.NonNull;
import net.osmand.plus.R; import net.osmand.plus.R;
public class OnlineRoutingEngineDataObject extends ProfileDataObject { public class OnlineRoutingEngineDataObject extends ProfileDataObject {
private int order;
public OnlineRoutingEngineDataObject(String name, public OnlineRoutingEngineDataObject(String name,
String description, String description,
String stringKey) { String stringKey,
int order) {
super(name, description, stringKey, R.drawable.ic_world_globe_dark, false, null); super(name, description, stringKey, R.drawable.ic_world_globe_dark, false, null);
this.order = order;
}
@Override
public int compareTo(@NonNull ProfileDataObject profileDataObject) {
if (profileDataObject instanceof OnlineRoutingEngineDataObject) {
OnlineRoutingEngineDataObject another = (OnlineRoutingEngineDataObject) profileDataObject;
return (this.order < another.order) ? -1 : ((this.order == another.order) ? 0 : 1);
}
return 0;
} }
} }

View file

@ -5,7 +5,7 @@ import android.content.Context;
import net.osmand.plus.OsmandApplication; 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.onlinerouting.OnlineRoutingEngine; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources; import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter;
@ -56,7 +56,22 @@ public class ProfileDataUtils {
Collections.sort(fileNames, new Comparator<String>() { Collections.sort(fileNames, new Comparator<String>() {
@Override @Override
public int compare(String s, String t1) { public int compare(String s, String t1) {
return s.equals(OSMAND_NAVIGATION) ? -1 : t1.equals(OSMAND_NAVIGATION) ? 1 : s.compareToIgnoreCase(t1); // OsmAnd navigation should be at the top of the list
if (s.equals(OSMAND_NAVIGATION)) {
return -1;
} else if (t1.equals(OSMAND_NAVIGATION)) {
return 1;
// Online navigation should be at the bottom of the list
} else if (s.equals(ONLINE_NAVIGATION)) {
return 1;
} else if (t1.equals(ONLINE_NAVIGATION)) {
return -1;
// Other sorted by file names
} else {
return s.compareToIgnoreCase(t1);
}
} }
}); });
for (String fileName : fileNames) { for (String fileName : fileNames) {
@ -71,9 +86,11 @@ public class ProfileDataUtils {
public static List<OnlineRoutingEngineDataObject> getOnlineRoutingProfiles(OsmandApplication app) { public static List<OnlineRoutingEngineDataObject> getOnlineRoutingProfiles(OsmandApplication app) {
List<OnlineRoutingEngineDataObject> objects = new ArrayList<>(); List<OnlineRoutingEngineDataObject> objects = new ArrayList<>();
for (OnlineRoutingEngine engine : app.getOnlineRoutingHelper().getEngines()) { List<OnlineRoutingEngine> engines = app.getOnlineRoutingHelper().getEngines();
for (int i = 0; i < engines.size(); i++) {
OnlineRoutingEngine engine = engines.get(i);
objects.add(new OnlineRoutingEngineDataObject( objects.add(new OnlineRoutingEngineDataObject(
engine.getName(app), engine.getBaseUrl(), engine.getStringKey())); engine.getName(app), engine.getBaseUrl(), engine.getStringKey(), i));
} }
return objects; return objects;
} }

View file

@ -39,8 +39,9 @@ import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
import net.osmand.plus.helpers.FontCache; import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet; import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet;
import net.osmand.plus.onlinerouting.OnlineRoutingEngineFragment; import net.osmand.plus.onlinerouting.ui.OnlineRoutingEngineFragment;
import net.osmand.router.RoutingConfiguration; import net.osmand.router.RoutingConfiguration;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -250,7 +251,7 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet {
tvTitle.setText(profile.getName()); tvTitle.setText(profile.getName());
tvDescription.setText(profile.getDescription()); tvDescription.setText(profile.getDescription());
boolean isSelected = setupSelected && profile.getStringKey().equals(selectedItemKey); boolean isSelected = setupSelected && Algorithms.objectEquals(profile.getStringKey(), selectedItemKey);
int iconColor; int iconColor;
if (dialogMode == DialogMode.NAVIGATION_PROFILE) { if (dialogMode == DialogMode.NAVIGATION_PROFILE) {
iconColor = isSelected ? activeColorResId : iconDefaultColorResId; iconColor = isSelected ? activeColorResId : iconDefaultColorResId;

View file

@ -2,7 +2,6 @@ package net.osmand.plus.routing;
import android.content.Context; import android.content.Context;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.util.Base64; import android.util.Base64;
@ -20,16 +19,14 @@ import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.LocationPoint; import net.osmand.data.LocationPoint;
import net.osmand.data.WptLocationPoint; import net.osmand.data.WptLocationPoint;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper;
import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.TargetPointsHelper.TargetPoint;
import net.osmand.plus.Version;
import net.osmand.plus.render.NativeOsmandLibrary; import net.osmand.plus.render.NativeOsmandLibrary;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter;
@ -48,21 +45,16 @@ import net.osmand.router.RoutingConfiguration.Builder;
import net.osmand.router.RoutingContext; import net.osmand.router.RoutingContext;
import net.osmand.router.TurnType; import net.osmand.router.TurnType;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.GeoPolylineParserUtil;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URLConnection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -1210,8 +1202,12 @@ public class RouteProvider {
private RouteCalculationResult findOnlineRoute(RouteCalculationParams params) throws IOException, JSONException { private RouteCalculationResult findOnlineRoute(RouteCalculationParams params) throws IOException, JSONException {
OnlineRoutingHelper helper = params.ctx.getOnlineRoutingHelper(); OnlineRoutingHelper helper = params.ctx.getOnlineRoutingHelper();
String stringKey = params.mode.getRoutingProfile(); String stringKey = params.mode.getRoutingProfile();
List<LatLon> route = helper.calculateRouteOnline(helper.getEngineByKey(stringKey), getFullPathFromParams(params)); OnlineRoutingEngine engine = helper.getEngineByKey(stringKey);
if (!route.isEmpty()) { List<LatLon> route = null;
if (engine != null) {
route = helper.calculateRouteOnline(engine, getFullPathFromParams(params));
}
if (!Algorithms.isEmpty(route)) {
List<Location> res = new ArrayList<>(); List<Location> res = new ArrayList<>();
for (LatLon pt : route) { for (LatLon pt : route) {
WptPt wpt = new WptPt(); WptPt wpt = new WptPt();

View file

@ -7,8 +7,9 @@ import androidx.annotation.Nullable;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine; import net.osmand.plus.onlinerouting.EngineParameter;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingFactory;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
import org.json.JSONException; import org.json.JSONException;
@ -93,8 +94,8 @@ public class OnlineRoutingSettingsItem extends CollectionSettingsItem<OnlineRout
int number = 0; int number = 0;
while (true) { while (true) {
number++; number++;
OnlineRoutingEngine renamedItem = OnlineRoutingEngine.createNewEngine(item.getType(), item.getVehicleKey(), item.getParams()); OnlineRoutingEngine renamedItem = OnlineRoutingFactory.createEngine(item.getType(), item.getParams());
renamedItem.putParameter(EngineParameter.CUSTOM_NAME, renamedItem.getName(app) + "_" + number); renamedItem.put(EngineParameter.CUSTOM_NAME, renamedItem.getName(app) + "_" + number);
if (!isDuplicate(renamedItem)) { if (!isDuplicate(renamedItem)) {
return renamedItem; return renamedItem;
} }
@ -105,7 +106,7 @@ public class OnlineRoutingSettingsItem extends CollectionSettingsItem<OnlineRout
void readItemsFromJson(@NonNull JSONObject json) throws IllegalArgumentException { void readItemsFromJson(@NonNull JSONObject json) throws IllegalArgumentException {
try { try {
OnlineRoutingHelper.readFromJson(json, items); OnlineRoutingHelper.readFromJson(json, items);
} catch (JSONException e) { } catch (JSONException | IllegalArgumentException e) {
warnings.add(app.getString(R.string.settings_item_read_error, String.valueOf(getType()))); warnings.add(app.getString(R.string.settings_item_read_error, String.valueOf(getType())));
throw new IllegalArgumentException("Json parse error", e); throw new IllegalArgumentException("Json parse error", e);
} }

View file

@ -33,7 +33,7 @@ import net.osmand.plus.helpers.SearchHistoryHelper;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.osmedit.OpenstreetmapPoint; import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.osmedit.OsmNotesPoint; import net.osmand.plus.osmedit.OsmNotesPoint;

View file

@ -23,7 +23,7 @@ import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.profiles.ProfileIconColors; import net.osmand.plus.profiles.ProfileIconColors;
import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources; import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources;

View file

@ -40,7 +40,7 @@ import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.osmedit.OpenstreetmapPoint; import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.osmedit.OsmNotesPoint; import net.osmand.plus.osmedit.OsmNotesPoint;

View file

@ -34,7 +34,7 @@ import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.osmedit.OpenstreetmapPoint; import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OsmNotesPoint; import net.osmand.plus.osmedit.OsmNotesPoint;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;

View file

@ -36,7 +36,7 @@ import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.onlinerouting.OnlineRoutingEngine; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.osmedit.OpenstreetmapPoint; import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OsmNotesPoint; import net.osmand.plus.osmedit.OsmNotesPoint;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;

View file

@ -27,7 +27,7 @@ import net.osmand.util.Algorithms;
import java.util.Map; import java.util.Map;
import static net.osmand.plus.onlinerouting.OnlineRoutingEngine.ONLINE_ROUTING_ENGINE_PREFIX; import static net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.ONLINE_ROUTING_ENGINE_PREFIX;
import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILES_LIST_UPDATED_ARG; import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILES_LIST_UPDATED_ARG;
import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILE_KEY_ARG; import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILE_KEY_ARG;
import static net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet.DIALOG_MODE_KEY; import static net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet.DIALOG_MODE_KEY;