Merge pull request #10098 from osmandapp/master

update test branch
This commit is contained in:
Hardy 2020-10-29 18:16:00 +01:00 committed by GitHub
commit 3595a4910c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 1065 additions and 232 deletions

View file

@ -114,6 +114,8 @@ public abstract class Entity implements Serializable {
public static final int MODIFY_DELETED = -1; public static final int MODIFY_DELETED = -1;
public static final int MODIFY_MODIFIED = 1; public static final int MODIFY_MODIFIED = 1;
public static final int MODIFY_CREATED = 2; public static final int MODIFY_CREATED = 2;
public static final String POI_TYPE_TAG = "poi_type_tag";
public static final String REMOVE_TAG_PREFIX = "----";
public Entity(long id) { public Entity(long id) {
this.id = id; this.id = id;
@ -241,6 +243,11 @@ public abstract class Entity implements Serializable {
return Collections.unmodifiableMap(tags); return Collections.unmodifiableMap(tags);
} }
public boolean isNotValid(String tag) {
String val = getTag(tag);
return val == null || val.length() == 0 || tag.length() == 0
|| tag.startsWith(REMOVE_TAG_PREFIX) || tag.equals(POI_TYPE_TAG);
}
public Collection<String> getTagKeySet() { public Collection<String> getTagKeySet() {
if (tags == null) { if (tags == null) {

View file

@ -268,4 +268,8 @@
<string name="last_response_duration">Última respuesta: hace %1$s</string> <string name="last_response_duration">Última respuesta: hace %1$s</string>
<string name="duration_ago">hace %1$s</string> <string name="duration_ago">hace %1$s</string>
<string name="shared_string_error_short">ERR</string> <string name="shared_string_error_short">ERR</string>
<string name="shared_string_export">Exportar</string>
<string name="logcat_buffer">Búfer de Logcat</string>
<string name="logcat_buffer_descr">Selecciona y comparte logs detallados de la app</string>
<string name="send_report">Enviar informe</string>
</resources> </resources>

View file

@ -257,4 +257,8 @@
<string name="unit_of_length">Afstand eenheden</string> <string name="unit_of_length">Afstand eenheden</string>
<string name="unit_of_speed_system_descr">Definieer de eenheid voor snelheid.</string> <string name="unit_of_speed_system_descr">Definieer de eenheid voor snelheid.</string>
<string name="unit_of_speed_system">Eenheid van snelheid</string> <string name="unit_of_speed_system">Eenheid van snelheid</string>
<string name="send_report">Stuur rapport</string>
<string name="shared_string_export">Exporteer naar OSM</string>
<string name="logcat_buffer">Logcat buffer</string>
<string name="logcat_buffer_descr">Controleer en deel gedetailleerde logs van de app</string>
</resources> </resources>

View file

@ -55,6 +55,17 @@
android:textSize="@dimen/default_list_text_size" android:textSize="@dimen/default_list_text_size"
osmand:typeface="@string/font_roboto_medium" /> osmand:typeface="@string/font_roboto_medium" />
<ImageButton
android:id="@+id/sort_button"
android:layout_width="@dimen/wikipedia_options_button_width"
android:layout_height="@dimen/dialog_button_height"
android:layout_gravity="center"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:background="?attr/bg_dash_line"
android:tint="?attr/color_dialog_buttons"
osmand:srcCompat="@drawable/ic_sort_waypoint_dark" />
</LinearLayout> </LinearLayout>
</FrameLayout> </FrameLayout>

View file

@ -3933,4 +3933,6 @@
<string name="snowmobile_render_descr">Für das Schneemobilfahren mit speziellen Straßen und Tracks.</string> <string name="snowmobile_render_descr">Für das Schneemobilfahren mit speziellen Straßen und Tracks.</string>
<string name="perform_oauth_authorization_description">Durchführen eines OAuth-Logins zur Nutzung der osmedit-Funktionen</string> <string name="perform_oauth_authorization_description">Durchführen eines OAuth-Logins zur Nutzung der osmedit-Funktionen</string>
<string name="use_two_phase_routing">2-Phasen-A*-Routing-Algorithmus verwenden</string> <string name="use_two_phase_routing">2-Phasen-A*-Routing-Algorithmus verwenden</string>
<string name="message_need_calculate_route_before_show_graph">%1$s Daten sind nur auf den Straßen verfügbar, Sie müssen eine Route mit \"Route zwischen Punkten\" berechnen, um sie zu erhalten.</string>
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
</resources> </resources>

View file

@ -3932,4 +3932,6 @@
<string name="message_need_calculate_route_before_show_graph">Datumoj de %1$s estas disponeblaj nur por vojoj, vi devas kalkuli la kurson uzante “kalkuli kurson inter punktoj” por akiri ĝin.</string> <string name="message_need_calculate_route_before_show_graph">Datumoj de %1$s estas disponeblaj nur por vojoj, vi devas kalkuli la kurson uzante “kalkuli kurson inter punktoj” por akiri ĝin.</string>
<string name="message_graph_will_be_available_after_recalculation">Atendado ĝis la kurso estos rekalkulita. <string name="message_graph_will_be_available_after_recalculation">Atendado ĝis la kurso estos rekalkulita.
\nDiagramo estos videbla post rekalkulado.</string> \nDiagramo estos videbla post rekalkulado.</string>
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
<string name="app_mode_gap">Manko</string>
</resources> </resources>

View file

@ -3551,14 +3551,14 @@
<string name="saving_new_profile">Guardando el nuevo perfil</string> <string name="saving_new_profile">Guardando el nuevo perfil</string>
<string name="profile_backup_failed">No se pudo respaldar el perfil.</string> <string name="profile_backup_failed">No se pudo respaldar el perfil.</string>
<string name="clear_recorded_data_warning">¿Borrar los datos registrados\?</string> <string name="clear_recorded_data_warning">¿Borrar los datos registrados\?</string>
<string name="importing_from">Importación de datos de %1$s</string> <string name="importing_from">Importando de datos de «%1$s»</string>
<string name="shared_string_importing">Importación</string> <string name="shared_string_importing">Importando</string>
<string name="checking_for_duplicate_description">OsmAnd comprueba %1$s para ver si hay duplicados con los elementos existentes en la aplicación. <string name="checking_for_duplicate_description">OsmAnd comprueba %1$s para ver si hay duplicados con los elementos existentes en la aplicación.
\n \n
\nPuede llevar algún tiempo.</string> \nPuede llevar algún tiempo.</string>
<string name="items_added">Elementos añadidos</string> <string name="items_added">Elementos añadidos</string>
<string name="shared_string_import_complete">Importación completa</string> <string name="shared_string_import_complete">Importación completa</string>
<string name="import_complete_description">Todos los datos de %1$s son importados, puedes usar los botones de abajo para abrir la parte necesaria de la aplicación para manejarla.</string> <string name="import_complete_description">Todos los datos de «%1$s» fueron importados. Puedes usar los botones de abajo para gestionar la sección necesaria de la aplicación.</string>
<string name="shared_string_min">Min</string> <string name="shared_string_min">Min</string>
<string name="n_items_of_z">%1$s de %2$s</string> <string name="n_items_of_z">%1$s de %2$s</string>
<string name="shared_string_terrain">Terreno</string> <string name="shared_string_terrain">Terreno</string>

View file

@ -3801,7 +3801,7 @@
<string name="plan_route_select_track_file_for_open">Sélectionnez un fichier de trace à ouvrir.</string> <string name="plan_route_select_track_file_for_open">Sélectionnez un fichier de trace à ouvrir.</string>
<string name="shared_string_done">Terminé</string> <string name="shared_string_done">Terminé</string>
<string name="overwrite_track">Remplacer la trace</string> <string name="overwrite_track">Remplacer la trace</string>
<string name="route_between_points_desc">Sélectionnez comment relier les points : par une ligne droite ou en calculant un itinéraire reliant les points comme indiqué ci-dessous.</string> <string name="route_between_points_desc">Définissez comment relier les points : par une ligne droite ou en calculant un itinéraire avec le profil ci-dessous.</string>
<string name="route_between_points_whole_track_button_desc">Toute la trace sera recalculée en utilisant le profil sélectionné.</string> <string name="route_between_points_whole_track_button_desc">Toute la trace sera recalculée en utilisant le profil sélectionné.</string>
<string name="route_between_points_next_segment_button_desc">Seul le prochain segment sera recalculé en utilisant le profil sélectionné.</string> <string name="route_between_points_next_segment_button_desc">Seul le prochain segment sera recalculé en utilisant le profil sélectionné.</string>
<string name="route_between_points_warning_desc">Ensuite, sélectionnez le profil de navigation pour détecter les routes autorisées et le seuil de distance afin de déplacer votre trace.</string> <string name="route_between_points_warning_desc">Ensuite, sélectionnez le profil de navigation pour détecter les routes autorisées et le seuil de distance afin de déplacer votre trace.</string>

View file

@ -3802,7 +3802,7 @@
<string name="poi_seamark_water_level_submerged">Vatnsyfirborð: í kafi</string> <string name="poi_seamark_water_level_submerged">Vatnsyfirborð: í kafi</string>
<string name="poi_seamark_water_level_part_submerged">Vatnsyfirborð: að hluta í kafi</string> <string name="poi_seamark_water_level_part_submerged">Vatnsyfirborð: að hluta í kafi</string>
<string name="poi_tactile_paving_primitive">Gróft</string> <string name="poi_tactile_paving_primitive">Gróft</string>
<string name="poi_internet_access_fee_customers">Merki til að finna staurinn</string> <string name="poi_internet_access_fee_customers">Internetaðgangur: viðskiptavinir</string>
<string name="poi_pump_status_missing_beam">Staða dælu: vantar bita</string> <string name="poi_pump_status_missing_beam">Staða dælu: vantar bita</string>
<string name="poi_osmand_fire_hydrant_pressure_suction">Sog</string> <string name="poi_osmand_fire_hydrant_pressure_suction">Sog</string>
<string name="poi_osmand_fire_hydrant_pressure_pressurized">Undir þrýstingi</string> <string name="poi_osmand_fire_hydrant_pressure_pressurized">Undir þrýstingi</string>
@ -3830,4 +3830,8 @@
<string name="poi_fuel_lng">LNG</string> <string name="poi_fuel_lng">LNG</string>
<string name="poi_departures_board_no">Brottfaratafla: nei</string> <string name="poi_departures_board_no">Brottfaratafla: nei</string>
<string name="poi_departures_board">Brottfaratafla</string> <string name="poi_departures_board">Brottfaratafla</string>
<string name="poi_parking_layby">Meðfram götu</string>
<string name="poi_parking_sheds">Skýli</string>
<string name="poi_parking_rooftop">Á þaki</string>
<string name="poi_gpx_point">GPX-punktur</string>
</resources> </resources>

View file

@ -3777,7 +3777,7 @@
\n \n
\nVeldu %2$s: öllum gögnum sem tengjast hraðamyndavélum; t.d. aðvaranir, tilkynningar, staðsetningar o.fl. verður eytt þar til OsmAnd er sett inn aftur frá grunni.</string> \nVeldu %2$s: öllum gögnum sem tengjast hraðamyndavélum; t.d. aðvaranir, tilkynningar, staðsetningar o.fl. verður eytt þar til OsmAnd er sett inn aftur frá grunni.</string>
<string name="route_between_points_add_track_desc">Veldu ferilskrá þar sem nýjum bút verður bætt inn.</string> <string name="route_between_points_add_track_desc">Veldu ferilskrá þar sem nýjum bút verður bætt inn.</string>
<string name="route_between_points_desc">Veldu hvernig eigi að tengja punkta; með beinni línu eða reikna leið milli þeirra eins og tiltekið er hér að neðan.</string> <string name="route_between_points_desc">Veldu hvernig eigi að tengja punktana; með beinni línu eða reikna leið milli þeirra eins og tiltekið er hér að neðan.</string>
<string name="route_between_points_whole_track_button_desc">Allur ferillinn verður endurreiknaður með völdu sniði.</string> <string name="route_between_points_whole_track_button_desc">Allur ferillinn verður endurreiknaður með völdu sniði.</string>
<string name="osm_edit_closed_note">Lokaður OSM-minnispunktur</string> <string name="osm_edit_closed_note">Lokaður OSM-minnispunktur</string>
<string name="whole_track">Allur ferillinn</string> <string name="whole_track">Allur ferillinn</string>
@ -3914,4 +3914,35 @@
<string name="save_global_track_interval_descr">Veldu millibil skráninga í almenna leiðarskráningu (virkjað með viðmótshlutanum fyrir GPX-skráningu á kortinu).</string> <string name="save_global_track_interval_descr">Veldu millibil skráninga í almenna leiðarskráningu (virkjað með viðmótshlutanum fyrir GPX-skráningu á kortinu).</string>
<string name="gpx_monitoring_stop">Setja skráningu í bið</string> <string name="gpx_monitoring_stop">Setja skráningu í bið</string>
<string name="gpx_monitoring_start">Halda áfram með skráningu</string> <string name="gpx_monitoring_start">Halda áfram með skráningu</string>
<string name="release_3_8">• Uppfærðar aðgerðir í skipulagningu leiða: mismunandi leiðsögn á hverjum bút auk slóða
\n
\n • Ný útlitsvalmynd fyrir slóðir: val á lit, þykkt, birting stefnuörva, táknmynda við upphaf/endi
\n
\n • Bættur sýnileiki hjólreiðahnúta.
\n
\n • Hægt að ýta á slóðir, hafa samhengisvalmynd með grunnupplýsingum.
\n
\n • Bætt reiknirit leitar
\n
\n • Bættir valkostir fyrir \'Fylgja slóð\' í leiðsögn
\n
\n • Lagfærð vandamál við inn/útflutning á stillingum sniða
\n
\n</string>
<string name="message_graph_will_be_available_after_recalculation">Bíddu eftir endurútreikningi leiðar.
\nGrafið verður tiltækt eftir endurútreikning.</string>
<string name="snowmobile_render_descr">Fyrir akstur vélsleða á sérstökum vegum og slóðum.</string>
<string name="message_need_calculate_route_before_show_graph">%1$s gögn aðeins tiltæk á vegunum, þú þarft að reikna leið með “Leið milli punkta” til að fá hana.</string>
<string name="file_already_imported">Skrá hefur þegar verið flutt inn í OsmAnd</string>
<string name="app_mode_gap">Bil</string>
<string name="contour_lines_thanks">Takk fyrir að kaupa \'Hæðarlínur\'</string>
<string name="osm_live_payment_desc_hw">Áskriftargjaldið verður rukkað miðað við valið tímabil. Þú getur sagt áskriftinni upp hvenær sem er á AppGallery.</string>
<string name="use_two_phase_routing">Nota 2-umferða A* leiðararútreikning</string>
<string name="osm_live_payment_subscription_management_hw">Greiðsla verður gjaldfærð á AppGallery reikninginn þinn við staðfestingu á kaupunum.
\n
\n Áskrift endurnýjast sjálfkrafa nema hún sé felld niður fyrir endurnýjunardag. Reikningur þinn verður einungis gjaldfærður fyrir endurnýjunartímabil (mánuður / þrír mánuðir / ár) á endurnýjunardegi.
\n
\n Þú getur stýrt og aflýst áskriftunum þínum með því að fara í AppGallery stillingarnar þínar.</string>
<string name="shared_string_graph">Graf</string>
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
</resources> </resources>

View file

@ -3718,7 +3718,7 @@
<string name="hidden_items_descr">Questi elementi sono nascosti dal menu, ma le opzioni rappresentate o i plugins continueranno a funzionare.</string> <string name="hidden_items_descr">Questi elementi sono nascosti dal menu, ma le opzioni rappresentate o i plugins continueranno a funzionare.</string>
<string name="reset_items_descr">Nascondere le opzioni le reimposta al loro valore originale.</string> <string name="reset_items_descr">Nascondere le opzioni le reimposta al loro valore originale.</string>
<string name="main_actions">Azioni principali</string> <string name="main_actions">Azioni principali</string>
<string name="additional_actions_descr">Puoi accedere a queste azioni toccando il pulsante \"Azioni aggiuntive\".</string> <string name="additional_actions_descr">Puoi accedere a queste azioni toccando il pulsante “%1$s”.</string>
<string name="move_inside_category">Puoi spostare gli elementi solo all\'interno di questa categoria.</string> <string name="move_inside_category">Puoi spostare gli elementi solo all\'interno di questa categoria.</string>
<string name="select_wikipedia_article_langs">Seleziona i linguaggi in cui gli articoli di Wikipedia appariranno sulla mappa. Puoi cambiare fra tutte le lingue disponibili mentre leggi questo articolo.</string> <string name="select_wikipedia_article_langs">Seleziona i linguaggi in cui gli articoli di Wikipedia appariranno sulla mappa. Puoi cambiare fra tutte le lingue disponibili mentre leggi questo articolo.</string>
<string name="some_articles_may_not_available_in_lang">Alcuni articoli di Wikipedia potrebbero non essere disponibili nella tua lingua.</string> <string name="some_articles_may_not_available_in_lang">Alcuni articoli di Wikipedia potrebbero non essere disponibili nella tua lingua.</string>

View file

@ -1479,7 +1479,7 @@
<string name="poi_takeaway_no">持ち帰り不可</string> <string name="poi_takeaway_no">持ち帰り不可</string>
<string name="poi_takeaway_only">テイクアウト・持ち帰りのみ</string> <string name="poi_takeaway_only">テイクアウト・持ち帰りのみ</string>
<string name="poi_archaeological_site_type">遺跡の種類</string> <string name="poi_archaeological_site_type">遺跡の種類</string>
<string name="poi_health_specialty">医療機関</string> <string name="poi_health_specialty">専門分野</string>
<string name="poi_health_specialty_general_yes">総合診療医</string> <string name="poi_health_specialty_general_yes">総合診療医</string>
<string name="poi_health_specialty_ophthalmology_yes">眼科</string> <string name="poi_health_specialty_ophthalmology_yes">眼科</string>
<string name="poi_health_specialty_gynaecology_yes">婦人科</string> <string name="poi_health_specialty_gynaecology_yes">婦人科</string>
@ -1487,7 +1487,7 @@
<string name="poi_health_specialty_orthopaedics_yes">整形外科</string> <string name="poi_health_specialty_orthopaedics_yes">整形外科</string>
<string name="poi_health_specialty_otolaryngology_yes">耳鼻咽喉科</string> <string name="poi_health_specialty_otolaryngology_yes">耳鼻咽喉科</string>
<string name="poi_health_specialty_paediatrics_yes">小児科</string> <string name="poi_health_specialty_paediatrics_yes">小児科</string>
<string name="poi_health_specialty_paediatrics_no">医療機関:小児科:無し</string> <string name="poi_health_specialty_paediatrics_no">専門分野:小児科:無し</string>
<string name="poi_health_specialty_dermatology_yes">皮膚科</string> <string name="poi_health_specialty_dermatology_yes">皮膚科</string>
<string name="poi_health_specialty_urology_yes">泌尿器科</string> <string name="poi_health_specialty_urology_yes">泌尿器科</string>
<string name="poi_health_specialty_surgery_yes">一般外科</string> <string name="poi_health_specialty_surgery_yes">一般外科</string>

View file

@ -628,7 +628,7 @@
<string name="index_item_world_basemap">Oversiktskart (verden)</string> <string name="index_item_world_basemap">Oversiktskart (verden)</string>
<string name="index_item_world_ski">Skikart (verden)</string> <string name="index_item_world_ski">Skikart (verden)</string>
<string name="lang_hr">Kroatisk</string> <string name="lang_hr">Kroatisk</string>
<string name="calculate_osmand_route_without_internet">Nettfrakoblet beregning av OsmAnd-rutesegment</string> <string name="calculate_osmand_route_without_internet">Frakoblet beregning av OsmAnd-rutesegment</string>
<string name="gpx_option_calculate_first_last_segment">Beregn OsmAnd-rute for første og siste rutesegment</string> <string name="gpx_option_calculate_first_last_segment">Beregn OsmAnd-rute for første og siste rutesegment</string>
<string name="map_widget_top">Statuslinje</string> <string name="map_widget_top">Statuslinje</string>
<string name="map_preferred_locale_descr">Foretrukket språk for påskrifter på kartet (hvis utilgjengelig brukes engelsk eller lokale navn).</string> <string name="map_preferred_locale_descr">Foretrukket språk for påskrifter på kartet (hvis utilgjengelig brukes engelsk eller lokale navn).</string>
@ -3694,7 +3694,7 @@
<string name="shared_string_custom">Egendefinert</string> <string name="shared_string_custom">Egendefinert</string>
<string name="gpx_direction_arrows">Retningspiler</string> <string name="gpx_direction_arrows">Retningspiler</string>
<string name="shared_string_tones">tonn</string> <string name="shared_string_tones">tonn</string>
<string name="route_between_points">Rute mellom punkter</string> <string name="route_between_points">Rut mellom punkter</string>
<string name="app_mode_enduro_motorcycle">Enduro-motorsykkel</string> <string name="app_mode_enduro_motorcycle">Enduro-motorsykkel</string>
<string name="screen_control">Skjermkontroll</string> <string name="screen_control">Skjermkontroll</string>
<string name="system_screen_timeout">Bruk systemets skjermtidsavbrudd</string> <string name="system_screen_timeout">Bruk systemets skjermtidsavbrudd</string>
@ -3706,7 +3706,7 @@
<string name="reverse_route">Snu rute</string> <string name="reverse_route">Snu rute</string>
<string name="overwrite_track">Overskriv spor</string> <string name="overwrite_track">Overskriv spor</string>
<string name="route_between_points_whole_track_button_desc">Hele sporet blir beregnet på nytt med den valgte profilen.</string> <string name="route_between_points_whole_track_button_desc">Hele sporet blir beregnet på nytt med den valgte profilen.</string>
<string name="route_between_points_desc">Velg hvordan punkter skal forbindes; med en rett linje, eller beregn en rute mellom dem som spesifisert nedenfor.</string> <string name="route_between_points_desc">Velg hvordan punktene skal forbindes; med en rett linje, eller beregn en rute mellom dem som spesifisert nedenfor.</string>
<string name="route_between_points_next_segment_button_desc">Kun det neste segmentet blir beregnet på nytt med den valgte profilen.</string> <string name="route_between_points_next_segment_button_desc">Kun det neste segmentet blir beregnet på nytt med den valgte profilen.</string>
<string name="whole_track">Hele sporet</string> <string name="whole_track">Hele sporet</string>
<string name="next_segment">Neste segment</string> <string name="next_segment">Neste segment</string>
@ -3872,4 +3872,6 @@
\nGraf vil være tilgjengelig etter omberegning.</string> \nGraf vil være tilgjengelig etter omberegning.</string>
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string> <string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
<string name="shared_string_graph">Graf</string> <string name="shared_string_graph">Graf</string>
<string name="message_need_calculate_route_before_show_graph">%1$s-data er tilgjengelig kun på veiene, du må beregne en rute med “Rut mellom punkter”.</string>
<string name="shared_string_gpx_route">Spor rute</string>
</resources> </resources>

View file

@ -12,7 +12,7 @@
<string name="map_widget_view_direction">Kijkrichting</string> <string name="map_widget_view_direction">Kijkrichting</string>
<string name="map_widget_transparent">Transparante widgets</string> <string name="map_widget_transparent">Transparante widgets</string>
<string name="int_continuosly">continu</string> <string name="int_continuosly">continu</string>
<string name="vector_maps_may_display_faster_on_some_devices">Vectorkaarten worden vaak sneller weergegeven. Werkt niet op sommige apparaten.</string> <string name="vector_maps_may_display_faster_on_some_devices">Vectorkaarten worden vaak sneller weergegeven. Werkt niet op alle toestellen.</string>
<string name="play_commands_of_currently_selected_voice">Kies een stem en test door aankondigingen af te spelen:</string> <string name="play_commands_of_currently_selected_voice">Kies een stem en test door aankondigingen af te spelen:</string>
<string name="debugging_and_development">OsmAnd fout-opsporing en ontwikkeling</string> <string name="debugging_and_development">OsmAnd fout-opsporing en ontwikkeling</string>
<string name="native_rendering">Interne kaartgeneratie</string> <string name="native_rendering">Interne kaartgeneratie</string>
@ -218,7 +218,7 @@
<string name="tts_language_not_supported_title">Taal niet ondersteund</string> <string name="tts_language_not_supported_title">Taal niet ondersteund</string>
<string name="tts_language_not_supported">De gekozen taal wordt niet ondersteund door de geïnstalleerde Android TTS (tekst-naar-spraak) stemgenerator. De standaard TTS taal zal worden gebruikt. Zoek een andere TTS stemgenerator op de markt\?</string> <string name="tts_language_not_supported">De gekozen taal wordt niet ondersteund door de geïnstalleerde Android TTS (tekst-naar-spraak) stemgenerator. De standaard TTS taal zal worden gebruikt. Zoek een andere TTS stemgenerator op de markt\?</string>
<string name="tts_missing_language_data_title">Ontbrekende gegevens</string> <string name="tts_missing_language_data_title">Ontbrekende gegevens</string>
<string name="tts_missing_language_data">Geen gegevens voor de geselecteerde taal geïnstalleerd. Wil je naar de Play-store gaan om deze te installeren?</string> <string name="tts_missing_language_data">Geen gegevens voor de geselecteerde taal geïnstalleerd. Ga naar \"Play Store\" om deze te installeren\?</string>
<string name="gpx_option_reverse_route">Keer richting van GPX-track om</string> <string name="gpx_option_reverse_route">Keer richting van GPX-track om</string>
<string name="gpx_option_destination_point">Huidige bestemming gebruiken</string> <string name="gpx_option_destination_point">Huidige bestemming gebruiken</string>
<string name="gpx_option_from_start_point">Volg de gehele track</string> <string name="gpx_option_from_start_point">Volg de gehele track</string>
@ -251,7 +251,7 @@
<string name="error_doing_search">Fout bij offline zoeken.</string> <string name="error_doing_search">Fout bij offline zoeken.</string>
<string name="search_osm_offline">Zoek adres in de offline kaarten</string> <string name="search_osm_offline">Zoek adres in de offline kaarten</string>
<string name="system_locale">Systeem</string> <string name="system_locale">Systeem</string>
<string name="preferred_locale_descr">App toon talen (OsmAnd dient opnieuw gestart).</string> <string name="preferred_locale_descr">App \"Toon talen\" (OsmAnd dient opnieuw gestart).</string>
<string name="preferred_locale">Toon talen</string> <string name="preferred_locale">Toon talen</string>
<string name="unit_of_length_descr">Wijzig de eenheid van afstand voor metingen.</string> <string name="unit_of_length_descr">Wijzig de eenheid van afstand voor metingen.</string>
<string name="unit_of_length">Afstand eenheden</string> <string name="unit_of_length">Afstand eenheden</string>
@ -433,7 +433,7 @@
<string name="search_poi_location">Naar signaal zoeken…</string> <string name="search_poi_location">Naar signaal zoeken…</string>
<string name="search_near_map">Zoek bij het midden van de kaart</string> <string name="search_near_map">Zoek bij het midden van de kaart</string>
<string name="search_nearby">Zoek dichtbij</string> <string name="search_nearby">Zoek dichtbij</string>
<string name="map_orientation_default">Zelfde als apparaat-instelling</string> <string name="map_orientation_default">Zelfde als apparaatinstelling</string>
<string name="map_orientation_portrait">Portret</string> <string name="map_orientation_portrait">Portret</string>
<string name="map_orientation_landscape">Landschap</string> <string name="map_orientation_landscape">Landschap</string>
<string name="map_screen_orientation">Kaartscherm-oriëntatie</string> <string name="map_screen_orientation">Kaartscherm-oriëntatie</string>
@ -642,7 +642,7 @@
\n \n
\nRasterkaarten zijn direct via online bronnen verkrijgbaar of kunnen voor offline gebruik gereedgemaakt worden (en handmatig gekopieerd naar de OsmAnd gegevensmap) als SQLite database door diverse hulpprogramma\'s van derden.</string> \nRasterkaarten zijn direct via online bronnen verkrijgbaar of kunnen voor offline gebruik gereedgemaakt worden (en handmatig gekopieerd naar de OsmAnd gegevensmap) als SQLite database door diverse hulpprogramma\'s van derden.</string>
<string name="osmand_background_plugin_description">Instellingen om tracking en navigatie te kunnen gebruiken met het scherm uit (schakelt de GPS periodiek in).</string> <string name="osmand_background_plugin_description">Instellingen om tracking en navigatie te kunnen gebruiken met het scherm uit (schakelt de GPS periodiek in).</string>
<string name="osmand_accessibility_description">"Maakt de toegankelijkheidsopties van het toestel rechtstreeks beschikbaar in OsmAnd. Hiermee kan o.a. de spreeksnelheid van tekst-naar-spraak-stemmen aangepast worden, D-pad schermnavigatie geconfigureerd worden, een trackball gebruikt worden voor de zoomregeling, of het gebruiken van meldingen via tekst-naar-spraak, bijvoorbeeld het automatisch melden van de positie."</string> <string name="osmand_accessibility_description">Maakt de toegankelijkheidsopties van het toestel rechtstreeks beschikbaar in OsmAnd. Hiermee kan o.a. de spreeksnelheid van tekst-naar-spraak stemmen aangepast worden, D-pad schermnavigatie geconfigureerd worden, een trackball gebruikt worden voor de zoomregeling, of het gebruiken van meldingen via tekst-naar-spraak, bijvoorbeeld het automatisch melden van de positie.</string>
<string name="osmand_development_plugin_description">Deze plug-in toont de instellingen voor ontwikkel- en debug-opties, zoals routetest en -simulatie, schermweergave-prestaties, en spraaksturing. Deze instellingen zijn bedoeld voor programmeurs die OsmAnd willen verbeteren en zijn niet nodig voor normaal gebruik.</string> <string name="osmand_development_plugin_description">Deze plug-in toont de instellingen voor ontwikkel- en debug-opties, zoals routetest en -simulatie, schermweergave-prestaties, en spraaksturing. Deze instellingen zijn bedoeld voor programmeurs die OsmAnd willen verbeteren en zijn niet nodig voor normaal gebruik.</string>
<string name="plugins_screen">Plugins beheren</string> <string name="plugins_screen">Plugins beheren</string>
<string name="prefs_plugins_descr">Schakel plugins in voor speciale functies en extra instellingen.</string> <string name="prefs_plugins_descr">Schakel plugins in voor speciale functies en extra instellingen.</string>
@ -767,7 +767,7 @@
\n \n
\n Beperkingen van deze gratis versie van OsmAnd: \n Beperkingen van deze gratis versie van OsmAnd:
\n - Beperkt aantal kaartdownloads \n - Beperkt aantal kaartdownloads
\n - Geen toegang tot offline Wikipedia POI\'s. \n - Geen toegang tot offline Wikipedia POI\'s
\n \n
\nOsmAnd wordt actief ontwikkeld en ons project en de verdere vooruitgang ervan is afhankelijk van \nOsmAnd wordt actief ontwikkeld en ons project en de verdere vooruitgang ervan is afhankelijk van
\nfinanciële bijdragen om de ontwikkeling en testen van nieuwe functionaliteit te kunnen bekostigen. \nfinanciële bijdragen om de ontwikkeling en testen van nieuwe functionaliteit te kunnen bekostigen.
@ -1283,7 +1283,7 @@
<string name="map_widget_left">Widgets Linker Kolom</string> <string name="map_widget_left">Widgets Linker Kolom</string>
<string name="configure_map">Kaart instellen</string> <string name="configure_map">Kaart instellen</string>
<string name="search_radius_proximity">Binnen</string> <string name="search_radius_proximity">Binnen</string>
<string name="anonymous_user_hint">Anonieme gebruikesr kunnen geen <string name="anonymous_user_hint">Anonieme gebruikers kunnen geen
\n- groepen aanmaken; \n- groepen aanmaken;
\n- groepen en apparaten synchroniseren met de server; \n- groepen en apparaten synchroniseren met de server;
\n- groepen en apparaten beheren in een eigen omgeving op de website.</string> \n- groepen en apparaten beheren in een eigen omgeving op de website.</string>
@ -1437,7 +1437,7 @@
<string name="shared_string_control_start">Start</string> <string name="shared_string_control_start">Start</string>
<string name="shared_string_control_stop">Stop</string> <string name="shared_string_control_stop">Stop</string>
<string name="shared_string_import">Importeren</string> <string name="shared_string_import">Importeren</string>
<string name="shared_string_export">Export naar OSM</string> <string name="shared_string_export">Exporteer naar OSM</string>
<string name="shared_string_more">Meer…</string> <string name="shared_string_more">Meer…</string>
<string name="shared_string_more_actions">Meer acties</string> <string name="shared_string_more_actions">Meer acties</string>
<string name="shared_string_do_not_show_again">Toon niet meer</string> <string name="shared_string_do_not_show_again">Toon niet meer</string>
@ -2285,10 +2285,10 @@
\n • Toon POIs (Points Of Interest) in uw omgeving \n • Toon POIs (Points Of Interest) in uw omgeving
\n • Draai de kaart in uw bewegingsrichting (of kompasrichting) \n • Draai de kaart in uw bewegingsrichting (of kompasrichting)
\n • Toon uw positie en waar u naar kijkt \n • Toon uw positie en waar u naar kijkt
\n • Deel uw lokatie met vrienden \n • Deel uw locatie met vrienden
\n • Bewaar belangrijke plaatsen in Favorieten \n • Bewaar belangrijke plaatsen in Favorieten
\n • Toon namen in het Engels, de lokale taal, of fonetisch \n • Toon namen in het Engels, de lokale taal, of fonetisch
\n • Toon extra online tiles, zoals een satellietfoto (van Bing), verschillende extra lagen zoals GPX-tracks voor navigatie e.d. met instelbare transparantie \n • Toon extra online tegels, zoals een satellietfoto (van Bing), verschillende extra lagen zoals GPX-tracks voor navigatie e.d. met instelbare transparantie
\n</string> \n</string>
<string name="osmand_extended_description_part4">Skiën <string name="osmand_extended_description_part4">Skiën
\nMet de OsmAnd Ski plug-in ziet u pistes met hun moeilijkheidsgraad, en extra informatie zoals liften en andere faciliteiten.</string> \nMet de OsmAnd Ski plug-in ziet u pistes met hun moeilijkheidsgraad, en extra informatie zoals liften en andere faciliteiten.</string>
@ -2302,7 +2302,7 @@
\n • De kaart toont voetpaden en wandelpaden \n • De kaart toont voetpaden en wandelpaden
\n • Wikipedia kan je veel vertellen tijdens een stadswandeling, in je eigen taal \n • Wikipedia kan je veel vertellen tijdens een stadswandeling, in je eigen taal
\n • OV-haltes (tram, bus, trein, metro), inclusief lijnnummers, helpen je bij het reizen in een onbekende stad \n • OV-haltes (tram, bus, trein, metro), inclusief lijnnummers, helpen je bij het reizen in een onbekende stad
\n • GPS-navigatie in voetgangermodus gebruikt voor het berekenen van de route voet- en wandelpaden \n • GPS-navigatie in voetgangersmodus gebruikt voor het berekenen van de route voet- en wandelpaden
\n • Upload en volg een GPX-route of neem er zelf één op en deel deze. \n • Upload en volg een GPX-route of neem er zelf één op en deel deze.
\n</string> \n</string>
<string name="osmand_extended_description_part7">Draag bij aan OpenStreetMap (OSM) <string name="osmand_extended_description_part7">Draag bij aan OpenStreetMap (OSM)
@ -2384,7 +2384,7 @@
\n • Kaart draaien in kompas- of bewegingsrichting \n • Kaart draaien in kompas- of bewegingsrichting
\n • Bewaar belangrijke plaatsen in Favorieten. \n • Bewaar belangrijke plaatsen in Favorieten.
\n • Toon POIs (points of interest) in de buurt \n • Toon POIs (points of interest) in de buurt
\n • Toon specifieke online tiles, satellietbeelden (van Bing), en extra lagen zoals GPX-tracks met rit-/routeinformatie e.d., met instelbare transparantie \n • Toon specifieke online tegels, satellietbeelden (van Bing), en extra lagen zoals GPX-tracks met rit-/routeinformatie e.d., met instelbare transparantie
\n • Toon plaatsnamen in het Engels, de lokale taal of fonetisch weergegeven \n • Toon plaatsnamen in het Engels, de lokale taal of fonetisch weergegeven
\n</string> \n</string>
<string name="osmand_plus_extended_description_part4">Gebruik OSM- en Wikipedia-gegevens <string name="osmand_plus_extended_description_part4">Gebruik OSM- en Wikipedia-gegevens
@ -3235,7 +3235,7 @@
<string name="routing_attr_freeride_policy_description">\'Freeride\' en \'Off-piste\' zijn officieuze routes en passages. Meestal onverzorgd en niet onderhouden, en niet \'s avonds gecontroleerd. Betreden op eigen risico.</string> <string name="routing_attr_freeride_policy_description">\'Freeride\' en \'Off-piste\' zijn officieuze routes en passages. Meestal onverzorgd en niet onderhouden, en niet \'s avonds gecontroleerd. Betreden op eigen risico.</string>
<string name="collected_data">Verzamelde data</string> <string name="collected_data">Verzamelde data</string>
<string name="last_launch_crashed">Laatste OsmAnd uitvoering gecrasht. Help ons alstublieft OsmAnd te verbeteren door de foutmelding te delen.</string> <string name="last_launch_crashed">Laatste OsmAnd uitvoering gecrasht. Help ons alstublieft OsmAnd te verbeteren door de foutmelding te delen.</string>
<string name="app_mode_personal_transporter">Personal transporter</string> <string name="app_mode_personal_transporter">Persoonlijke transporteur</string>
<string name="app_mode_offroad">Offroad</string> <string name="app_mode_offroad">Offroad</string>
<string name="sett_wunderlinq_ext_input">WunderLINQ</string> <string name="sett_wunderlinq_ext_input">WunderLINQ</string>
<string name="routeInfo_roadClass_name">Wegtype</string> <string name="routeInfo_roadClass_name">Wegtype</string>
@ -3298,7 +3298,7 @@
<string name="shared_string_turn_off">Uitschakelen</string> <string name="shared_string_turn_off">Uitschakelen</string>
<string name="new_plugin_added">Nieuwe plug-in toegevoegd</string> <string name="new_plugin_added">Nieuwe plug-in toegevoegd</string>
<string name="join_segments">Segmenten samenvoegen</string> <string name="join_segments">Segmenten samenvoegen</string>
<string name="release_3_4">• App profiles: Create a custom profile for your own needs, with a custom icon and color <string name="release_3_4">• App-profielen: maak een eigen profiel, met een aangepast pictogram en kleur
\n \n
\n • Nu aan te passen standaard en min / max snelheden voor elk profiel \n • Nu aan te passen standaard en min / max snelheden voor elk profiel
\n \n
@ -3306,9 +3306,9 @@
\n \n
\n • Opties toegevoegd om het kompas en een straalliniaal op de kaart te tonen \n • Opties toegevoegd om het kompas en een straalliniaal op de kaart te tonen
\n \n
\n • Fix background track logging \n • Trackregistratie op de achtergrond herstellen
\n \n
\n • Improved background map downloads \n • Verbeterde downloads van achtergrondkaarten
\n \n
\n • \'Zet scherm aan\' optie is terug \n • \'Zet scherm aan\' optie is terug
\n \n
@ -3567,7 +3567,7 @@
<string name="replace_point_descr">Vervang een ander punt door dit punt.</string> <string name="replace_point_descr">Vervang een ander punt door dit punt.</string>
<string name="app_mode_ski_touring">Toerskiën</string> <string name="app_mode_ski_touring">Toerskiën</string>
<string name="app_mode_ski_snowmobile">Sneeuwscooter</string> <string name="app_mode_ski_snowmobile">Sneeuwscooter</string>
<string name="custom_osmand_plugin">Aangepaste OsmAnd-plug-in</string> <string name="custom_osmand_plugin">Aangepaste OsmAnd plug-in</string>
<string name="shared_string_items">Elementen</string> <string name="shared_string_items">Elementen</string>
<string name="changes_applied_to_profile">Wijzigingen toegepast op het \'%1$s\'-profiel.</string> <string name="changes_applied_to_profile">Wijzigingen toegepast op het \'%1$s\'-profiel.</string>
<string name="settings_item_read_error">Kon niet lezen van \'%1$s\'.</string> <string name="settings_item_read_error">Kon niet lezen van \'%1$s\'.</string>
@ -3579,7 +3579,7 @@
<string name="shared_string_all_languages">Alle talen</string> <string name="shared_string_all_languages">Alle talen</string>
<string name="wiki_menu_download_descr">Om Wikipedia-POIs op de kaart te tonen zijn extra kaarten nodig.</string> <string name="wiki_menu_download_descr">Om Wikipedia-POIs op de kaart te tonen zijn extra kaarten nodig.</string>
<string name="select_wikipedia_article_langs">Selecteer de talen voor Wikipedia-artikelen op de kaart. Tijdens het lezen van het artikel kan omgeschakeld worden naar een andere beschikbare taal.</string> <string name="select_wikipedia_article_langs">Selecteer de talen voor Wikipedia-artikelen op de kaart. Tijdens het lezen van het artikel kan omgeschakeld worden naar een andere beschikbare taal.</string>
<string name="some_articles_may_not_available_in_lang">Sommige Wikipedia-artikelen zijn mogelijk niet beschikbaar in de eigen taal.</string> <string name="some_articles_may_not_available_in_lang">Sommige Wikipedia-artikelen zijn mogelijk niet beschikbaar in je eigen taal.</string>
<string name="lang_zhyue">Kantonees</string> <string name="lang_zhyue">Kantonees</string>
<string name="lang_zhminnan">Minnanyu</string> <string name="lang_zhminnan">Minnanyu</string>
<string name="lang_yo">Yoruba</string> <string name="lang_yo">Yoruba</string>
@ -3624,8 +3624,8 @@
<string name="change_application_profile">App-profiel wijzigingen</string> <string name="change_application_profile">App-profiel wijzigingen</string>
<string name="index_item_world_basemap_detailed">Wereldoverzichtskaart (gedetailleerd)</string> <string name="index_item_world_basemap_detailed">Wereldoverzichtskaart (gedetailleerd)</string>
<string name="unsupported_type_error">Niet ondersteund type</string> <string name="unsupported_type_error">Niet ondersteund type</string>
<string name="width_limit_description">Geef de voertuigbreedte op, er zijn mogelijk routebeperkingen voor brede voertuigen.</string> <string name="width_limit_description">Geef de voertuigbreedte op, er zijn mogelijk routebeperkingen voor te brede voertuigen.</string>
<string name="height_limit_description">Geef de voertuighoogte op, er zijn mogelijk routebeperkingen voor hoge voertuigen.</string> <string name="height_limit_description">Geef de voertuighoogte op, er zijn mogelijk routebeperkingen voor te hoge voertuigen.</string>
<string name="weight_limit_description">Geef het voertuiggewicht op, er zijn mogelijk routebeperkingen voor zwaar verkeer.</string> <string name="weight_limit_description">Geef het voertuiggewicht op, er zijn mogelijk routebeperkingen voor zwaar verkeer.</string>
<string name="gpx_parse_error">OsmAnd GPX is corrupt, neem contact op met het support team voor verder onderzoek.</string> <string name="gpx_parse_error">OsmAnd GPX is corrupt, neem contact op met het support team voor verder onderzoek.</string>
<string name="shared_string_always">Altijd</string> <string name="shared_string_always">Altijd</string>
@ -3636,7 +3636,7 @@
<string name="turn_screen_on_navigation_instructions_descr">Scherm aanzetten bij elke routeaanwijzing.</string> <string name="turn_screen_on_navigation_instructions_descr">Scherm aanzetten bij elke routeaanwijzing.</string>
<string name="turn_screen_on_navigation_instructions">Routeaanwijzingen</string> <string name="turn_screen_on_navigation_instructions">Routeaanwijzingen</string>
<string name="turn_screen_on_power_button_disabled">Uitgeschakeld. De instelling Timeout na wakker worden moet ingesteld zijn op Scherm aanlaten.</string> <string name="turn_screen_on_power_button_disabled">Uitgeschakeld. De instelling Timeout na wakker worden moet ingesteld zijn op Scherm aanlaten.</string>
<string name="turn_screen_on_power_button_descr">Door op de aan/uit-knop te drukken gaat het scherm aan met OsmAnd op de voorgrond van het vergrendelscherm.</string> <string name="turn_screen_on_power_button_descr">Door op de aan/uit knop te drukken gaat het scherm aan met OsmAnd op de voorgrond van het vergrendelde scherm.</string>
<string name="turn_screen_on_power_button">Aan/uit-knop</string> <string name="turn_screen_on_power_button">Aan/uit-knop</string>
<string name="turn_screen_on_proximity_sensor">Nabijheidssensor</string> <string name="turn_screen_on_proximity_sensor">Nabijheidssensor</string>
<string name="turn_screen_on_wake_time_descr">Selecteer de schermtimeout na wakker worden. (Kies “%1$s” om geen timeout te gebruiken.)</string> <string name="turn_screen_on_wake_time_descr">Selecteer de schermtimeout na wakker worden. (Kies “%1$s” om geen timeout te gebruiken.)</string>
@ -3682,7 +3682,7 @@
<string name="tiles_storage_descr">Kies hoe gedownloade rasterkaartsegmenten worden opgeslagen.</string> <string name="tiles_storage_descr">Kies hoe gedownloade rasterkaartsegmenten worden opgeslagen.</string>
<string name="profiles_for_action_not_found">Geen overeenkomende profielen gevonden.</string> <string name="profiles_for_action_not_found">Geen overeenkomende profielen gevonden.</string>
<string name="screen_timeout">Time-out van het scherm</string> <string name="screen_timeout">Time-out van het scherm</string>
<string name="use_volume_buttons_as_zoom_descr">Inschakelen om het zoomniveau van de kaart in te stellen met de volumeknoppen.</string> <string name="use_volume_buttons_as_zoom_descr">Regel het zoomniveau, van de kaart, met de volumeknop op het apparaat.</string>
<string name="use_volume_buttons_as_zoom">Gebruik volumeknoppen om in en uit te zoomen</string> <string name="use_volume_buttons_as_zoom">Gebruik volumeknoppen om in en uit te zoomen</string>
<string name="plugin_wikipedia_description">Verkrijg informatie over POIs uit Wikipedia. Het is je offline reisgidsje - schakel de Wikipedia-plug-in in en geniet van artikelen over de bezienswaardigheden in je omgeving.</string> <string name="plugin_wikipedia_description">Verkrijg informatie over POIs uit Wikipedia. Het is je offline reisgidsje - schakel de Wikipedia-plug-in in en geniet van artikelen over de bezienswaardigheden in je omgeving.</string>
<string name="lenght_limit_description">Geef de voertuiglengte op, er zijn mogelijk routebeperkingen voor lange voertuigen.</string> <string name="lenght_limit_description">Geef de voertuiglengte op, er zijn mogelijk routebeperkingen voor lange voertuigen.</string>
@ -3707,7 +3707,7 @@
<string name="add_hidden_group_info">Het toegevoegde punt zal niet zichtbaar zijn op de kaart, aangezien de geselecteerde groep verborgen is, je kan het vinden in \"%s\".</string> <string name="add_hidden_group_info">Het toegevoegde punt zal niet zichtbaar zijn op de kaart, aangezien de geselecteerde groep verborgen is, je kan het vinden in \"%s\".</string>
<string name="system_default_theme">Standaard</string> <string name="system_default_theme">Standaard</string>
<string name="route_between_points">Route tussen punten</string> <string name="route_between_points">Route tussen punten</string>
<string name="route_between_points_warning_desc">"Vervolgens, zet uw track vast op de dichtstbijzijnde toegestane weg met een van uw navigatieprofielen om deze optie te gebruiken."</string> <string name="route_between_points_warning_desc">Vervolgens, zet uw track vast op de dichtstbijzijnde toegestane weg met een van uw navigatieprofielen om deze optie te gebruiken.</string>
<string name="message_need_calculate_route_before_show_graph">%1$s gegevens alleen beschikbaar op de wegen, u moet een route berekenen met behulp van \"Route tussen punten\" om deze te krijgen.</string> <string name="message_need_calculate_route_before_show_graph">%1$s gegevens alleen beschikbaar op de wegen, u moet een route berekenen met behulp van \"Route tussen punten\" om deze te krijgen.</string>
<string name="route_between_points_desc">Selecteer hoe de punten verbonden worden, via een rechte lijn, of een route berekenen tussen de punten zoals hieronder aangegeven.</string> <string name="route_between_points_desc">Selecteer hoe de punten verbonden worden, via een rechte lijn, of een route berekenen tussen de punten zoals hieronder aangegeven.</string>
<string name="route_between_points_next_segment_button_desc">Alleen het volgende segment wordt opnieuw berekend met het geselecteerde profiel.</string> <string name="route_between_points_next_segment_button_desc">Alleen het volgende segment wordt opnieuw berekend met het geselecteerde profiel.</string>
@ -3744,7 +3744,7 @@
<string name="simplified_track_description">Alleen de routelijn wordt opgeslagen, de waypoints worden verwijderd.</string> <string name="simplified_track_description">Alleen de routelijn wordt opgeslagen, de waypoints worden verwijderd.</string>
<string name="shared_string_done">Bewaar</string> <string name="shared_string_done">Bewaar</string>
<string name="reverse_route">Route omkeren</string> <string name="reverse_route">Route omkeren</string>
<string name="route_between_points_add_track_desc">"Selecteer een track waaraan je een nieuw segment wil toevoegen."</string> <string name="route_between_points_add_track_desc">Selecteer een track waaraan je een nieuw segment wil toevoegen.</string>
<string name="plan_route_select_track_file_for_open">Selecteer een trackbestand om te openen.</string> <string name="plan_route_select_track_file_for_open">Selecteer een trackbestand om te openen.</string>
<string name="plan_route_exit_dialog_descr">Weet u zeker dat u alle wijzigingen in de geplande route wilt annuleren door deze te sluiten\?</string> <string name="plan_route_exit_dialog_descr">Weet u zeker dat u alle wijzigingen in de geplande route wilt annuleren door deze te sluiten\?</string>
<string name="plan_route_trim_before">Opsmukken voor</string> <string name="plan_route_trim_before">Opsmukken voor</string>
@ -3771,4 +3771,12 @@
<string name="plan_route_create_new_route">Maak een nieuwe route</string> <string name="plan_route_create_new_route">Maak een nieuwe route</string>
<string name="plan_route_open_existing_track">Open een bestaande track</string> <string name="plan_route_open_existing_track">Open een bestaande track</string>
<string name="plan_a_route">Plan een route</string> <string name="plan_a_route">Plan een route</string>
<string name="use_two_phase_routing">Gebruik 2-fasen A* routeringsalgoritme</string>
<string name="shared_string_graph">Grafiek</string>
<string name="message_graph_will_be_available_after_recalculation">Wacht op de herberekening van de route.
\nDe grafiek is beschikbaar na herberekening.</string>
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
<string name="import_track_descr">Kies een trackbestand om te volgen of importeer het, vanaf uw apparaat.</string>
<string name="app_mode_gap">Kloof</string>
<string name="shared_string_custom">Op maat</string>
</resources> </resources>

View file

@ -3819,7 +3819,7 @@
<string name="reverse_route">Rota reversa</string> <string name="reverse_route">Rota reversa</string>
<string name="route_between_points_whole_track_button_desc">A trilha inteira será recalculada usando o perfil selecionado.</string> <string name="route_between_points_whole_track_button_desc">A trilha inteira será recalculada usando o perfil selecionado.</string>
<string name="route_between_points_next_segment_button_desc">Apenas o próximo segmento será recalculado usando o perfil selecionado.</string> <string name="route_between_points_next_segment_button_desc">Apenas o próximo segmento será recalculado usando o perfil selecionado.</string>
<string name="route_between_points_desc">Selecione como conectar pontos, por uma linha reta, ou calcular uma rota entre eles conforme especificado abaixo.</string> <string name="route_between_points_desc">Escolha como conectar os pontos, por uma linha reta, ou calcular uma rota entre eles conforme especificado abaixo.</string>
<string name="whole_track">Trilha inteira</string> <string name="whole_track">Trilha inteira</string>
<string name="next_segment">Próximo segmento</string> <string name="next_segment">Próximo segmento</string>
<string name="route_between_points_warning_desc">Para usar esta opção, OsmAnd precisa ajustar sua trilha para as estradas do mapa. <string name="route_between_points_warning_desc">Para usar esta opção, OsmAnd precisa ajustar sua trilha para as estradas do mapa.

View file

@ -3821,7 +3821,7 @@
<string name="reverse_route">反向路線</string> <string name="reverse_route">反向路線</string>
<string name="route_between_points_whole_track_button_desc">整個軌跡都會使用選定的設定檔重新計算。</string> <string name="route_between_points_whole_track_button_desc">整個軌跡都會使用選定的設定檔重新計算。</string>
<string name="route_between_points_next_segment_button_desc">僅下一個片段會使用選定的設定檔重新計算。</string> <string name="route_between_points_next_segment_button_desc">僅下一個片段會使用選定的設定檔重新計算。</string>
<string name="route_between_points_desc">如何連接點,透過直線或以下面選定的方法計算其間的路徑。</string> <string name="route_between_points_desc">如何連接點,透過直線或以下面選定的方法計算其間的路徑。</string>
<string name="whole_track">整個軌道</string> <string name="whole_track">整個軌道</string>
<string name="next_segment">下一段</string> <string name="next_segment">下一段</string>
<string name="route_between_points_warning_desc">接下來,使用您其中一個導航設定檔來將路線貼齊到最近可用的道路上以使用此選項。</string> <string name="route_between_points_warning_desc">接下來,使用您其中一個導航設定檔來將路線貼齊到最近可用的道路上以使用此選項。</string>

View file

@ -21,6 +21,7 @@
<string name="icon_group_amenity">Amenity</string> <string name="icon_group_amenity">Amenity</string>
<string name="app_mode_gap">Gap</string> <string name="app_mode_gap">Gap</string>
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string> <string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
<string name="shared_string_local_maps">Local maps</string>
<string name="message_graph_will_be_available_after_recalculation">Wait for the route recalculation.\nGraph will be available after recalculation.</string> <string name="message_graph_will_be_available_after_recalculation">Wait for the route recalculation.\nGraph will be available after recalculation.</string>
<string name="message_need_calculate_route_before_show_graph">%1$s data available only on the roads, you need to calculate a route using “Route between points” to get it.</string> <string name="message_need_calculate_route_before_show_graph">%1$s data available only on the roads, you need to calculate a route using “Route between points” to get it.</string>
<string name="shared_string_graph">Graph</string> <string name="shared_string_graph">Graph</string>

View file

@ -509,26 +509,27 @@ public class SQLiteTileSource implements ITileSource {
if(db == null || coordinatesZoom > 25 ){ if(db == null || coordinatesZoom > 25 ){
return null; return null;
} }
SQLiteCursor q ; SQLiteCursor cursor ;
if (inversiveZoom) { if (inversiveZoom) {
int minZoom = (17 - minZ) + 1; int minZoom = (17 - minZ) + 1;
// 17 - z = zoom, x << (25 - zoom) = 25th x tile = 8 + z, // 17 - z = zoom, x << (25 - zoom) = 25th x tile = 8 + z,
q = db.rawQuery("SELECT max(x << (8+z)), min(x << (8+z)), max(y << (8+z)), min(y << (8+z))" + cursor = db.rawQuery("SELECT max(x << (8+z)), min(x << (8+z)), max(y << (8+z)), min(y << (8+z))" +
" from tiles where z < " " from tiles where z < "
+ minZoom, new String[0]); + minZoom, new String[0]);
} else { } else {
q = db.rawQuery("SELECT max(x << (25-z)), min(x << (25-z)), max(y << (25-z)), min(y << (25-z))" cursor = db.rawQuery("SELECT max(x << (25-z)), min(x << (25-z)), max(y << (25-z)), min(y << (25-z))"
+ " from tiles where z > " + minZ, + " from tiles where z > " + minZ,
new String[0]); new String[0]);
} }
q.moveToFirst(); cursor.moveToFirst();
int right = (int) (q.getInt(0) >> (25 - coordinatesZoom)); int right = (int) (cursor.getInt(0) >> (25 - coordinatesZoom));
int left = (int) (q.getInt(1) >> (25 - coordinatesZoom)); int left = (int) (cursor.getInt(1) >> (25 - coordinatesZoom));
int top = (int) (q.getInt(3) >> (25 - coordinatesZoom)); int top = (int) (cursor.getInt(3) >> (25 - coordinatesZoom));
int bottom = (int) (q.getInt(2) >> (25 - coordinatesZoom)); int bottom = (int) (cursor.getInt(2) >> (25 - coordinatesZoom));
cursor.close();
return new QuadRect(left, top, right, bottom); return new QuadRect(left, top, right, bottom);
} }
public void deleteImage(int x, int y, int zoom) { public void deleteImage(int x, int y, int zoom) {

View file

@ -44,6 +44,7 @@ import net.osmand.IProgress;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.StateChangedListener;
import net.osmand.data.DataTileManager; import net.osmand.data.DataTileManager;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
@ -158,7 +159,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
public static final int AV_CAMERA_FOCUS_CONTINUOUS = 5; public static final int AV_CAMERA_FOCUS_CONTINUOUS = 5;
// photo shot: // photo shot:
private static int shotId = 0; private static int shotId = 0;
private SoundPool sp = null; private SoundPool soundPool = null;
public static final int FULL_SCEEN_RESULT_DELAY_MS = 3000; public static final int FULL_SCEEN_RESULT_DELAY_MS = 3000;
public final CommonPreference<Integer> AV_CAMERA_PICTURE_SIZE; public final CommonPreference<Integer> AV_CAMERA_PICTURE_SIZE;
@ -596,6 +597,17 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
@Override @Override
public boolean init(@NonNull final OsmandApplication app, Activity activity) { public boolean init(@NonNull final OsmandApplication app, Activity activity) {
if (AV_PHOTO_PLAY_SOUND.get()) {
loadCameraSound();
}
AV_PHOTO_PLAY_SOUND.addListener(new StateChangedListener<Boolean>() {
@Override
public void stateChanged(Boolean change) {
if (AV_PHOTO_PLAY_SOUND.get() && soundPool == null) {
loadCameraSound();
}
}
});
// initializeRemoteControlRegistrationMethods(); // initializeRemoteControlRegistrationMethods();
// AudioManager am = (AudioManager) app.getSystemService(Context.AUDIO_SERVICE); // AudioManager am = (AudioManager) app.getSystemService(Context.AUDIO_SERVICE);
// if (am != null) { // if (am != null) {
@ -604,6 +616,21 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
return true; return true;
} }
private void loadCameraSound() {
if (soundPool == null) {
soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
}
if (shotId == 0) {
try {
AssetFileDescriptor assetFileDescriptor = app.getAssets().openFd("sounds/camera_click.ogg");
shotId = soundPool.load(assetFileDescriptor, 1);
assetFileDescriptor.close();
} catch (Exception e) {
log.error("cannot get shotId for sounds/camera_click.ogg");
}
}
}
@Override @Override
public void registerLayers(MapActivity activity) { public void registerLayers(MapActivity activity) {
this.mapActivity = activity; this.mapActivity = activity;
@ -1338,21 +1365,6 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
@Override @Override
public void surfaceCreated(SurfaceHolder holder) { public void surfaceCreated(SurfaceHolder holder) {
try { try {
// load sound befor shot
if (AV_PHOTO_PLAY_SOUND.get()) {
if (sp == null)
sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
if (shotId == 0) {
try {
AssetFileDescriptor assetFileDescriptor = app.getAssets().openFd("sounds/camera_click.ogg");
shotId = sp.load(assetFileDescriptor, 1);
assetFileDescriptor.close();
} catch (Exception e) {
log.error("cannot get shotId for sounds/camera_click.ogg");
}
}
}
Parameters parameters = cam.getParameters(); Parameters parameters = cam.getParameters();
parameters.setPictureSize(selectedCamPicSize.width, selectedCamPicSize.height); parameters.setPictureSize(selectedCamPicSize.width, selectedCamPicSize.height);
log.debug("takePhotoWithCamera() set Picture size: width=" + selectedCamPicSize.width log.debug("takePhotoWithCamera() set Picture size: width=" + selectedCamPicSize.width
@ -1734,6 +1746,11 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
@Override @Override
public void disable(OsmandApplication app) { public void disable(OsmandApplication app) {
if (soundPool != null) {
soundPool.release();
soundPool = null;
shotId = 0;
}
// AudioManager am = (AudioManager) app.getSystemService(Context.AUDIO_SERVICE); // AudioManager am = (AudioManager) app.getSystemService(Context.AUDIO_SERVICE);
// if (am != null) { // if (am != null) {
// unregisterMediaListener(am); // unregisterMediaListener(am);
@ -2043,8 +2060,8 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
photoJpegData = data; photoJpegData = data;
if (AV_PHOTO_PLAY_SOUND.get()) { if (AV_PHOTO_PLAY_SOUND.get()) {
if (sp != null && shotId != 0) { if (soundPool != null && shotId != 0) {
sp.play(shotId, 0.7f, 0.7f, 0, 0, 1); soundPool.play(shotId, 0.7f, 0.7f, 0, 0, 1);
} }
} }

View file

@ -58,7 +58,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import static net.osmand.plus.osmedit.AdvancedEditPoiFragment.addPoiToStringSet; import static net.osmand.plus.osmedit.AdvancedEditPoiFragment.addPoiToStringSet;
import static net.osmand.plus.osmedit.EditPoiData.POI_TYPE_TAG; import static net.osmand.osm.edit.Entity.POI_TYPE_TAG;
public class AddPOIAction extends QuickAction { public class AddPOIAction extends QuickAction {
public static final QuickActionType TYPE = new QuickActionType(13, public static final QuickActionType TYPE = new QuickActionType(13,
@ -140,7 +140,7 @@ public class AddPOIAction extends QuickAction {
Node newNode = new Node(node.getLatitude(), node.getLongitude(), node.getId()); Node newNode = new Node(node.getLatitude(), node.getLongitude(), node.getId());
OsmPoint.Action action = newNode.getId() < 0 ? OsmPoint.Action.CREATE : OsmPoint.Action.MODIFY; OsmPoint.Action action = newNode.getId() < 0 ? OsmPoint.Action.CREATE : OsmPoint.Action.MODIFY;
for (Map.Entry<String, String> tag : editPoiData.getTagValues().entrySet()) { for (Map.Entry<String, String> tag : editPoiData.getTagValues().entrySet()) {
if (tag.getKey().equals(EditPoiData.POI_TYPE_TAG)) { if (tag.getKey().equals(POI_TYPE_TAG)) {
final PoiType poiType = editPoiData.getAllTranslatedSubTypes().get(tag.getValue().trim().toLowerCase()); final PoiType poiType = editPoiData.getAllTranslatedSubTypes().get(tag.getValue().trim().toLowerCase());
if (poiType != null) { if (poiType != null) {
newNode.putTagNoLC(poiType.getEditOsmTag(), poiType.getEditOsmValue()); newNode.putTagNoLC(poiType.getEditOsmTag(), poiType.getEditOsmValue());

View file

@ -28,6 +28,7 @@ import net.osmand.osm.MapPoiTypes;
import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiCategory;
import net.osmand.osm.PoiFilter; import net.osmand.osm.PoiFilter;
import net.osmand.osm.PoiType; import net.osmand.osm.PoiType;
import net.osmand.osm.edit.Entity;
import net.osmand.osm.edit.OSMSettings; import net.osmand.osm.edit.OSMSettings;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -112,7 +113,7 @@ public class AdvancedEditPoiFragment extends BaseOsmAndFragment
if (Algorithms.objectEquals(anyTag, OSMSettings.OSMTagKey.NAME.getValue())) { if (Algorithms.objectEquals(anyTag, OSMSettings.OSMTagKey.NAME.getValue())) {
updateName(); updateName();
} }
if (Algorithms.objectEquals(anyTag, EditPoiData.POI_TYPE_TAG)) { if (Algorithms.objectEquals(anyTag, Entity.POI_TYPE_TAG)) {
updatePoiType(); updatePoiType();
} }
} }
@ -197,9 +198,9 @@ public class AdvancedEditPoiFragment extends BaseOsmAndFragment
currentPoiTypeKey = pt.getEditOsmTag(); currentPoiTypeKey = pt.getEditOsmTag();
} }
for (Entry<String, String> tag : editPoiData.getTagValues().entrySet()) { for (Entry<String, String> tag : editPoiData.getTagValues().entrySet()) {
if (tag.getKey().equals(EditPoiData.POI_TYPE_TAG) if (tag.getKey().equals(Entity.POI_TYPE_TAG)
|| tag.getKey().equals(OSMSettings.OSMTagKey.NAME.getValue()) || tag.getKey().equals(OSMSettings.OSMTagKey.NAME.getValue())
|| tag.getKey().startsWith(EditPoiData.REMOVE_TAG_PREFIX) || tag.getKey().startsWith(Entity.REMOVE_TAG_PREFIX)
|| tag.getKey().equals(currentPoiTypeKey)) || tag.getKey().equals(currentPoiTypeKey))
continue; continue;
addTagView(tag.getKey(), tag.getValue()); addTagView(tag.getKey(), tag.getValue());

View file

@ -5,6 +5,7 @@ import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import net.osmand.osm.PoiType; import net.osmand.osm.PoiType;
import net.osmand.osm.edit.Entity;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapcontextmenu.MenuBuilder; import net.osmand.plus.mapcontextmenu.MenuBuilder;
@ -12,6 +13,8 @@ import net.osmand.plus.render.RenderingIcons;
import java.util.Map; import java.util.Map;
import static net.osmand.osm.edit.Entity.POI_TYPE_TAG;
public class EditPOIMenuBuilder extends MenuBuilder { public class EditPOIMenuBuilder extends MenuBuilder {
private final OsmPoint osmPoint; private final OsmPoint osmPoint;
@ -38,7 +41,7 @@ public class EditPOIMenuBuilder extends MenuBuilder {
OpenstreetmapPoint point = (OpenstreetmapPoint) osmPoint; OpenstreetmapPoint point = (OpenstreetmapPoint) osmPoint;
for (Map.Entry<String, String> e : point.getEntity().getTags().entrySet()) { for (Map.Entry<String, String> e : point.getEntity().getTags().entrySet()) {
if (EditPoiData.POI_TYPE_TAG.equals(e.getKey())) { if (POI_TYPE_TAG.equals(e.getKey())) {
String poiTranslation = e.getValue(); String poiTranslation = e.getValue();
Map<String, PoiType> poiTypeMap = app.getPoiTypes().getAllTranslatedNames(false); Map<String, PoiType> poiTypeMap = app.getPoiTypes().getAllTranslatedNames(false);
PoiType poiType = poiTypeMap.get(poiTranslation.toLowerCase()); PoiType poiType = poiTypeMap.get(poiTranslation.toLowerCase());
@ -63,8 +66,8 @@ public class EditPOIMenuBuilder extends MenuBuilder {
} }
for (Map.Entry<String, String> e : point.getEntity().getTags().entrySet()) { for (Map.Entry<String, String> e : point.getEntity().getTags().entrySet()) {
if (EditPoiData.POI_TYPE_TAG.equals(e.getKey()) || if (POI_TYPE_TAG.equals(e.getKey()) ||
e.getKey().startsWith(EditPoiData.REMOVE_TAG_PREFIX)) { e.getKey().startsWith(Entity.REMOVE_TAG_PREFIX)) {
continue; continue;
} }
String text = e.getKey() + "=" + e.getValue(); String text = e.getKey() + "=" + e.getValue();

View file

@ -18,6 +18,8 @@ import net.osmand.util.Algorithms;
import java.util.Map; import java.util.Map;
import static net.osmand.osm.edit.Entity.POI_TYPE_TAG;
public class EditPOIMenuController extends MenuController { public class EditPOIMenuController extends MenuController {
private OsmPoint osmPoint; private OsmPoint osmPoint;
@ -166,7 +168,7 @@ public class EditPOIMenuController extends MenuController {
if (osmPoint.getGroup() == OsmPoint.Group.POI) { if (osmPoint.getGroup() == OsmPoint.Group.POI) {
OpenstreetmapPoint osmP = (OpenstreetmapPoint) osmPoint; OpenstreetmapPoint osmP = (OpenstreetmapPoint) osmPoint;
int iconResId = 0; int iconResId = 0;
String poiTranslation = osmP.getEntity().getTag(EditPoiData.POI_TYPE_TAG); String poiTranslation = osmP.getEntity().getTag(POI_TYPE_TAG);
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (poiTranslation != null && mapActivity != null) { if (poiTranslation != null && mapActivity != null) {
Map<String, PoiType> poiTypeMap = mapActivity.getMyApplication().getPoiTypes().getAllTranslatedNames(false); Map<String, PoiType> poiTypeMap = mapActivity.getMyApplication().getPoiTypes().getAllTranslatedNames(false);

View file

@ -17,15 +17,15 @@ import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import static net.osmand.osm.edit.Entity.POI_TYPE_TAG;
public class EditPoiData { public class EditPoiData {
private static final Log LOG = PlatformUtil.getLog(EditPoiData.class); private static final Log LOG = PlatformUtil.getLog(EditPoiData.class);
private Set<TagsChangedListener> mListeners = new HashSet<>(); private Set<TagsChangedListener> mListeners = new HashSet<>();
private LinkedHashMap<String, String > tagValues = new LinkedHashMap<String, String>(); private final LinkedHashMap<String, String> tagValues = new LinkedHashMap<String, String>();
private boolean isInEdit = false; private boolean isInEdit = false;
private Entity entity; private Entity entity;
public static final String POI_TYPE_TAG = "poi_type_tag";
public static final String REMOVE_TAG_PREFIX = "----";
public static final String REMOVE_TAG_VALUE = "DELETE"; public static final String REMOVE_TAG_VALUE = "DELETE";
private boolean hasChangesBeenMade = false; private boolean hasChangesBeenMade = false;
private Map<String, PoiType> allTranslatedSubTypes; private Map<String, PoiType> allTranslatedSubTypes;
@ -123,7 +123,7 @@ public class EditPoiData {
checkNotInEdit(); checkNotInEdit();
try { try {
isInEdit = true; isInEdit = true;
tagValues.remove(REMOVE_TAG_PREFIX+tag); tagValues.remove(Entity.REMOVE_TAG_PREFIX + tag);
String oldValue = tagValues.get(tag); String oldValue = tagValues.get(tag);
if (oldValue == null || !oldValue.equals(value)) { if (oldValue == null || !oldValue.equals(value)) {
changedTags.add(tag); changedTags.add(tag);
@ -156,7 +156,7 @@ public class EditPoiData {
checkNotInEdit(); checkNotInEdit();
try { try {
isInEdit = true; isInEdit = true;
tagValues.put(REMOVE_TAG_PREFIX+tag, REMOVE_TAG_VALUE); tagValues.put(Entity.REMOVE_TAG_PREFIX + tag, REMOVE_TAG_VALUE);
tagValues.remove(tag); tagValues.remove(tag);
changedTags.remove(tag); changedTags.remove(tag);
notifyDatasetChanged(tag); notifyDatasetChanged(tag);
@ -216,7 +216,7 @@ public class EditPoiData {
PoiType pt = getPoiTypeDefined(); PoiType pt = getPoiTypeDefined();
String editOsmTag = pt != null ? pt.getEditOsmTag() : null; String editOsmTag = pt != null ? pt.getEditOsmTag() : null;
if (editOsmTag != null) { if (editOsmTag != null) {
removeTypeTagWithPrefix(!tagValues.containsKey(REMOVE_TAG_PREFIX + editOsmTag)); removeTypeTagWithPrefix(!tagValues.containsKey(Entity.REMOVE_TAG_PREFIX + editOsmTag));
currentPoiType = pt; currentPoiType = pt;
String tagVal = pt.getEditOsmValue() != null ? pt.getEditOsmValue() : ""; String tagVal = pt.getEditOsmValue() != null ? pt.getEditOsmValue() : "";
tagValues.put(editOsmTag, tagVal); tagValues.put(editOsmTag, tagVal);
@ -237,11 +237,11 @@ public class EditPoiData {
private void removeTypeTagWithPrefix(boolean needRemovePrefix) { private void removeTypeTagWithPrefix(boolean needRemovePrefix) {
if (currentPoiType != null) { if (currentPoiType != null) {
if (needRemovePrefix) { if (needRemovePrefix) {
tagValues.put(REMOVE_TAG_PREFIX + currentPoiType.getEditOsmTag(), REMOVE_TAG_VALUE); tagValues.put(Entity.REMOVE_TAG_PREFIX + currentPoiType.getEditOsmTag(), REMOVE_TAG_VALUE);
tagValues.put(REMOVE_TAG_PREFIX + currentPoiType.getOsmTag2(), REMOVE_TAG_VALUE); tagValues.put(Entity.REMOVE_TAG_PREFIX + currentPoiType.getOsmTag2(), REMOVE_TAG_VALUE);
} else { } else {
tagValues.remove(REMOVE_TAG_PREFIX + currentPoiType.getEditOsmTag()); tagValues.remove(Entity.REMOVE_TAG_PREFIX + currentPoiType.getEditOsmTag());
tagValues.remove(REMOVE_TAG_PREFIX + currentPoiType.getOsmTag2()); tagValues.remove(Entity.REMOVE_TAG_PREFIX + currentPoiType.getOsmTag2());
} }
removeCurrentTypeTag(); removeCurrentTypeTag();
} }

View file

@ -90,6 +90,8 @@ import java.util.Set;
import studio.carbonylgroup.textfieldboxes.ExtendedEditText; import studio.carbonylgroup.textfieldboxes.ExtendedEditText;
import static net.osmand.osm.edit.Entity.POI_TYPE_TAG;
public class EditPoiDialogFragment extends BaseOsmAndDialogFragment { public class EditPoiDialogFragment extends BaseOsmAndDialogFragment {
public static final String TAG = EditPoiDialogFragment.class.getSimpleName(); public static final String TAG = EditPoiDialogFragment.class.getSimpleName();
private static final Log LOG = PlatformUtil.getLog(EditPoiDialogFragment.class); private static final Log LOG = PlatformUtil.getLog(EditPoiDialogFragment.class);
@ -500,20 +502,20 @@ public class EditPoiDialogFragment extends BaseOsmAndDialogFragment {
Action action = entity.getId() < 0 ? Action.CREATE : Action.MODIFY; Action action = entity.getId() < 0 ? Action.CREATE : Action.MODIFY;
for (Map.Entry<String, String> tag : editPoiData.getTagValues().entrySet()) { for (Map.Entry<String, String> tag : editPoiData.getTagValues().entrySet()) {
if (!Algorithms.isEmpty(tag.getKey()) && !Algorithms.isEmpty(tag.getValue()) && if (!Algorithms.isEmpty(tag.getKey()) && !Algorithms.isEmpty(tag.getValue()) &&
!tag.getKey().equals(EditPoiData.POI_TYPE_TAG)) { !tag.getKey().equals(POI_TYPE_TAG)) {
entity.putTagNoLC(tag.getKey(), tag.getValue()); entity.putTagNoLC(tag.getKey(), tag.getValue());
} }
} }
String poiTypeTag = editPoiData.getTagValues().get(EditPoiData.POI_TYPE_TAG); String poiTypeTag = editPoiData.getTagValues().get(POI_TYPE_TAG);
String comment = ""; String comment = "";
if (poiTypeTag != null) { if (poiTypeTag != null) {
final PoiType poiType = editPoiData.getAllTranslatedSubTypes().get(poiTypeTag.trim().toLowerCase()); final PoiType poiType = editPoiData.getAllTranslatedSubTypes().get(poiTypeTag.trim().toLowerCase());
if (poiType != null) { if (poiType != null) {
entity.putTagNoLC(poiType.getEditOsmTag(), poiType.getEditOsmValue()); entity.putTagNoLC(poiType.getEditOsmTag(), poiType.getEditOsmValue());
entity.removeTag(EditPoiData.REMOVE_TAG_PREFIX + poiType.getEditOsmTag()); entity.removeTag(Entity.REMOVE_TAG_PREFIX + poiType.getEditOsmTag());
if (poiType.getOsmTag2() != null) { if (poiType.getOsmTag2() != null) {
entity.putTagNoLC(poiType.getOsmTag2(), poiType.getOsmValue2()); entity.putTagNoLC(poiType.getOsmTag2(), poiType.getOsmValue2());
entity.removeTag(EditPoiData.REMOVE_TAG_PREFIX + poiType.getOsmTag2()); entity.removeTag(Entity.REMOVE_TAG_PREFIX + poiType.getOsmTag2());
} }
} else if (!Algorithms.isEmpty(poiTypeTag)) { } else if (!Algorithms.isEmpty(poiTypeTag)) {
PoiCategory category = editPoiData.getPoiCategory(); PoiCategory category = editPoiData.getPoiCategory();
@ -522,7 +524,7 @@ public class EditPoiDialogFragment extends BaseOsmAndDialogFragment {
} }
} }
if (offlineEdit && !Algorithms.isEmpty(poiTypeTag)) { if (offlineEdit && !Algorithms.isEmpty(poiTypeTag)) {
entity.putTagNoLC(EditPoiData.POI_TYPE_TAG, poiTypeTag); entity.putTagNoLC(POI_TYPE_TAG, poiTypeTag);
} }
String actionString = action == Action.CREATE ? getString(R.string.default_changeset_add) : getString(R.string.default_changeset_edit); String actionString = action == Action.CREATE ? getString(R.string.default_changeset_add) : getString(R.string.default_changeset_edit);
comment = actionString + " " + poiTypeTag; comment = actionString + " " + poiTypeTag;

View file

@ -24,6 +24,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import static net.osmand.osm.edit.Entity.POI_TYPE_TAG;
public class OpenstreetmapLocalUtil implements OpenstreetmapUtil { public class OpenstreetmapLocalUtil implements OpenstreetmapUtil {
public final static Log LOG = PlatformUtil.getLog(OpenstreetmapLocalUtil.class); public final static Log LOG = PlatformUtil.getLog(OpenstreetmapLocalUtil.class);
@ -122,7 +124,7 @@ public class OpenstreetmapLocalUtil implements OpenstreetmapUtil {
entity = new Node(loc.getLatitude(), loc.getLongitude(), entityId); entity = new Node(loc.getLatitude(), loc.getLongitude(), entityId);
} }
if (poiType != null) { if (poiType != null) {
entity.putTagNoLC(EditPoiData.POI_TYPE_TAG, poiType.getTranslation()); entity.putTagNoLC(POI_TYPE_TAG, poiType.getTranslation());
if (poiType.getOsmTag2() != null) { if (poiType.getOsmTag2() != null) {
entity.putTagNoLC(poiType.getOsmTag2(), poiType.getOsmValue2()); entity.putTagNoLC(poiType.getOsmTag2(), poiType.getOsmValue2());
} }

View file

@ -28,7 +28,7 @@ public class OpenstreetmapPoint extends OsmPoint {
String type = "amenity"; String type = "amenity";
for (String k : entity.getTagKeySet()) { for (String k : entity.getTagKeySet()) {
if (!OSMTagKey.NAME.getValue().equals(k) && !OSMTagKey.OPENING_HOURS.getValue().equals(k) && if (!OSMTagKey.NAME.getValue().equals(k) && !OSMTagKey.OPENING_HOURS.getValue().equals(k) &&
!k.startsWith(EditPoiData.REMOVE_TAG_PREFIX)) { !k.startsWith(Entity.REMOVE_TAG_PREFIX)) {
type = k; type = k;
break; break;
} }
@ -75,6 +75,20 @@ public class OpenstreetmapPoint extends OsmPoint {
this.comment = comment; this.comment = comment;
} }
public String getTagsString() {
StringBuilder sb = new StringBuilder();
for (String tag : entity.getTagKeySet()) {
String val = entity.getTag(tag);
if (entity.isNotValid(tag)) {
continue;
}
sb.append(tag).append(" : ");
sb.append(val).append("; ");
}
return sb.toString();
}
@Override @Override
public String toString() { public String toString() {
return new StringBuffer("Openstreetmap Point ").append(this.getAction()).append(" ").append(this.getName()) return new StringBuffer("Openstreetmap Point ").append(this.getAction()).append(" ").append(this.getName())

View file

@ -39,7 +39,8 @@ import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutionException;
import static net.osmand.osm.edit.Entity.POI_TYPE_TAG;
public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil { public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
@ -273,8 +274,8 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
throws IllegalArgumentException, IllegalStateException, IOException { throws IllegalArgumentException, IllegalStateException, IOException {
for (String k : entity.getTagKeySet()) { for (String k : entity.getTagKeySet()) {
String val = entity.getTag(k); String val = entity.getTag(k);
if (val.length() == 0 || k.length() == 0 || EditPoiData.POI_TYPE_TAG.equals(k) || if (val.length() == 0 || k.length() == 0 || POI_TYPE_TAG.equals(k) ||
k.startsWith(EditPoiData.REMOVE_TAG_PREFIX) || k.contains(EditPoiData.REMOVE_TAG_PREFIX)) k.startsWith(Entity.REMOVE_TAG_PREFIX) || k.contains(Entity.REMOVE_TAG_PREFIX))
continue; continue;
ser.startTag(null, "tag"); //$NON-NLS-1$ ser.startTag(null, "tag"); //$NON-NLS-1$
ser.attribute(null, "k", k); //$NON-NLS-1$ ser.attribute(null, "k", k); //$NON-NLS-1$
@ -455,7 +456,7 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
} }
private boolean deletedTag(Entity entity, String tag) { private boolean deletedTag(Entity entity, String tag) {
return entity.getTagKeySet().contains(EditPoiData.REMOVE_TAG_PREFIX + tag); return entity.getTagKeySet().contains(Entity.REMOVE_TAG_PREFIX + tag);
} }
@Override @Override
@ -542,12 +543,12 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
PoiType poiType = type.getPoiTypeByKeyName(subType); PoiType poiType = type.getPoiTypeByKeyName(subType);
if (poiType != null && poiType.getEditOsmValue().equals(entity.getTag(poiType.getEditOsmTag()))) { if (poiType != null && poiType.getEditOsmValue().equals(entity.getTag(poiType.getEditOsmTag()))) {
entity.removeTag(poiType.getEditOsmTag()); entity.removeTag(poiType.getEditOsmTag());
entity.putTagNoLC(EditPoiData.POI_TYPE_TAG, poiType.getTranslation()); entity.putTagNoLC(POI_TYPE_TAG, poiType.getTranslation());
} else { } else {
for (PoiType pt : type.getPoiTypes()) { for (PoiType pt : type.getPoiTypes()) {
if (pt.getEditOsmValue().equals(entity.getTag(pt.getEditOsmTag()))) { if (pt.getEditOsmValue().equals(entity.getTag(pt.getEditOsmTag()))) {
entity.removeTag(pt.getEditOsmTag()); entity.removeTag(pt.getEditOsmTag());
entity.putTagNoLC(EditPoiData.POI_TYPE_TAG, pt.getTranslation()); entity.putTagNoLC(POI_TYPE_TAG, pt.getTranslation());
} }
} }
} }

View file

@ -5,8 +5,12 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnClickListener;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.StyleSpan;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
@ -57,6 +61,7 @@ import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_C
import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_OPEN_OSM_NOTE; import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_OPEN_OSM_NOTE;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.OSM_EDITS; import static net.osmand.aidlapi.OsmAndCustomizationConstants.OSM_EDITS;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.OSM_NOTES; import static net.osmand.aidlapi.OsmAndCustomizationConstants.OSM_NOTES;
import static net.osmand.osm.edit.Entity.POI_TYPE_TAG;
import static net.osmand.plus.ContextMenuAdapter.makeDeleteAction; import static net.osmand.plus.ContextMenuAdapter.makeDeleteAction;
@ -528,6 +533,15 @@ public class OsmEditingPlugin extends OsmandPlugin {
} }
} }
public static SpannableString getTitle(OsmPoint osmPoint, Context ctx) {
SpannableString title = new SpannableString(getName(osmPoint));
if (TextUtils.isEmpty(title)) {
title = SpannableString.valueOf(getCategory(osmPoint, ctx));
title.setSpan(new StyleSpan(Typeface.ITALIC), 0, title.length(), 0);
}
return title;
}
public static String getName(OsmPoint point) { public static String getName(OsmPoint point) {
if (point.getGroup() == OsmPoint.Group.POI) { if (point.getGroup() == OsmPoint.Group.POI) {
return ((OpenstreetmapPoint) point).getName(); return ((OpenstreetmapPoint) point).getName();
@ -541,7 +555,7 @@ public class OsmEditingPlugin extends OsmandPlugin {
public static String getCategory(OsmPoint osmPoint, Context context) { public static String getCategory(OsmPoint osmPoint, Context context) {
String category = ""; String category = "";
if (osmPoint.getGroup() == OsmPoint.Group.POI) { if (osmPoint.getGroup() == OsmPoint.Group.POI) {
category = ((OpenstreetmapPoint) osmPoint).getEntity().getTag(EditPoiData.POI_TYPE_TAG); category = ((OpenstreetmapPoint) osmPoint).getEntity().getTag(POI_TYPE_TAG);
if (Algorithms.isEmpty(category)) { if (Algorithms.isEmpty(category)) {
category = context.getString(R.string.shared_string_without_name); category = context.getString(R.string.shared_string_without_name);
} }

View file

@ -1,11 +1,7 @@
package net.osmand.plus.osmedit; package net.osmand.plus.osmedit;
import android.content.Context; import android.content.Context;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.StyleSpan;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -21,6 +17,7 @@ import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import net.osmand.osm.PoiType; import net.osmand.osm.PoiType;
import net.osmand.osm.edit.Entity;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
@ -182,7 +179,7 @@ public class OsmEditsAdapter extends ArrayAdapter<Object> {
private void bindOsmEditViewHolder(final OsmEditViewHolder holder, final OsmPoint osmEdit, final int position) { private void bindOsmEditViewHolder(final OsmEditViewHolder holder, final OsmPoint osmEdit, final int position) {
setupBackground(holder.mainView); setupBackground(holder.mainView);
holder.titleTextView.setText(getTitle(osmEdit)); holder.titleTextView.setText(OsmEditingPlugin.getTitle(osmEdit, getContext()));
holder.descriptionTextView.setText(getDescription(osmEdit)); holder.descriptionTextView.setText(getDescription(osmEdit));
Drawable icon = getIcon(osmEdit); Drawable icon = getIcon(osmEdit);
if (icon != null) { if (icon != null) {
@ -243,20 +240,12 @@ public class OsmEditsAdapter extends ArrayAdapter<Object> {
return items.size(); return items.size();
} }
private SpannableString getTitle(OsmPoint osmPoint) {
SpannableString title = new SpannableString(OsmEditingPlugin.getName(osmPoint));
if (TextUtils.isEmpty(title)) {
title = SpannableString.valueOf(getCategory(osmPoint));
title.setSpan(new StyleSpan(Typeface.ITALIC), 0, title.length(), 0);
}
return title;
}
private Drawable getIcon(OsmPoint point) { private Drawable getIcon(OsmPoint point) {
if (point.getGroup() == OsmPoint.Group.POI) { if (point.getGroup() == OsmPoint.Group.POI) {
OpenstreetmapPoint osmPoint = (OpenstreetmapPoint) point; OpenstreetmapPoint osmPoint = (OpenstreetmapPoint) point;
int iconResId = 0; int iconResId = 0;
String poiTranslation = osmPoint.getEntity().getTag(EditPoiData.POI_TYPE_TAG); String poiTranslation = osmPoint.getEntity().getTag(Entity.POI_TYPE_TAG);
if (poiTranslation != null) { if (poiTranslation != null) {
Map<String, PoiType> poiTypeMap = app.getPoiTypes().getAllTranslatedNames(false); Map<String, PoiType> poiTypeMap = app.getPoiTypes().getAllTranslatedNames(false);
PoiType poiType = poiTypeMap.get(poiTranslation.toLowerCase()); PoiType poiType = poiTypeMap.get(poiTranslation.toLowerCase());
@ -304,10 +293,6 @@ public class OsmEditsAdapter extends ArrayAdapter<Object> {
return true; return true;
} }
private String getCategory(OsmPoint point) {
return OsmEditingPlugin.getCategory(point, getContext());
}
private String getDescription(OsmPoint point) { private String getDescription(OsmPoint point) {
return OsmEditingPlugin.getDescription(point, getContext(), true); return OsmEditingPlugin.getDescription(point, getContext(), true);
} }

View file

@ -781,7 +781,7 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo
if (point.getGroup() == Group.POI) { if (point.getGroup() == Group.POI) {
OpenstreetmapPoint p = (OpenstreetmapPoint) point; OpenstreetmapPoint p = (OpenstreetmapPoint) point;
WptPt wpt = new WptPt(); WptPt wpt = new WptPt();
wpt.name = getTagsString(p); wpt.name = p.getTagsString();
wpt.lat = p.getLatitude(); wpt.lat = p.getLatitude();
wpt.lon = p.getLongitude(); wpt.lon = p.getLongitude();
wpt.desc = "id: " + String.valueOf(p.getId()) + wpt.desc = "id: " + String.valueOf(p.getId()) +
@ -817,24 +817,6 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo
return sb.toString(); return sb.toString();
} }
private String getTagsString(OpenstreetmapPoint point) {
StringBuilder sb = new StringBuilder();
for (String tag : point.getEntity().getTagKeySet()) {
String val = point.getEntity().getTag(tag);
if (isNotValid(tag, val)) {
continue;
}
sb.append(tag).append(" : ");
sb.append(val).append("; ");
}
return sb.toString();
}
private boolean isNotValid(String tag, String val) {
return val == null || val.length() == 0 || tag.length() == 0
|| tag.startsWith(EditPoiData.REMOVE_TAG_PREFIX) || tag.equals("poi_type_tag");
}
private void writeContent(XmlSerializer sz, OsmPoint[] points, OsmPoint.Action a) throws IllegalArgumentException, IllegalStateException, IOException { private void writeContent(XmlSerializer sz, OsmPoint[] points, OsmPoint.Action a) throws IllegalArgumentException, IllegalStateException, IOException {
for (OsmPoint point : points) { for (OsmPoint point : points) {
if (point.getGroup() == Group.POI) { if (point.getGroup() == Group.POI) {
@ -878,7 +860,7 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo
private void writeTags(XmlSerializer sz, Entity p) { private void writeTags(XmlSerializer sz, Entity p) {
for (String tag : p.getTagKeySet()) { for (String tag : p.getTagKeySet()) {
String val = p.getTag(tag); String val = p.getTag(tag);
if (isNotValid(tag, val)) { if (p.isNotValid(tag)) {
continue; continue;
} }
try { try {

View file

@ -101,7 +101,7 @@ public class OsmEditsLayer extends OsmandMapLayer implements ContextMenuLayer.IC
if (osmPoint.getGroup() == OsmPoint.Group.POI) { if (osmPoint.getGroup() == OsmPoint.Group.POI) {
OpenstreetmapPoint osmP = (OpenstreetmapPoint) osmPoint; OpenstreetmapPoint osmP = (OpenstreetmapPoint) osmPoint;
int iconResId = 0; int iconResId = 0;
String poiTranslation = osmP.getEntity().getTag(EditPoiData.POI_TYPE_TAG); String poiTranslation = osmP.getEntity().getTag(Entity.POI_TYPE_TAG);
if (poiTranslation != null && activity != null) { if (poiTranslation != null && activity != null) {
Map<String, PoiType> poiTypeMap = activity.getMyApplication().getPoiTypes().getAllTranslatedNames(false); Map<String, PoiType> poiTypeMap = activity.getMyApplication().getPoiTypes().getAllTranslatedNames(false);
PoiType poiType = poiTypeMap.get(poiTranslation.toLowerCase()); PoiType poiType = poiTypeMap.get(poiTranslation.toLowerCase());

View file

@ -16,13 +16,13 @@ import androidx.appcompat.widget.SwitchCompat;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import net.osmand.osm.PoiType; import net.osmand.osm.PoiType;
import net.osmand.osm.edit.Entity;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.dialogs.ProgressDialogFragment; import net.osmand.plus.dialogs.ProgressDialogFragment;
import net.osmand.plus.osmedit.EditPoiData;
import net.osmand.plus.osmedit.OpenstreetmapPoint; import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OsmBugsLayer; import net.osmand.plus.osmedit.OsmBugsLayer;
import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.osmedit.OsmEditingPlugin;
@ -152,7 +152,7 @@ public class SendPoiDialogFragment extends DialogFragment {
for (OsmPoint p : poi) { for (OsmPoint p : poi) {
if (p.getGroup() == OsmPoint.Group.POI) { if (p.getGroup() == OsmPoint.Group.POI) {
OsmPoint.Action action = p.getAction(); OsmPoint.Action action = p.getAction();
String type = ((OpenstreetmapPoint) p).getEntity().getTag(EditPoiData.POI_TYPE_TAG); String type = ((OpenstreetmapPoint) p).getEntity().getTag(Entity.POI_TYPE_TAG);
if (type == null) { if (type == null) {
continue; continue;
} }

View file

@ -1,11 +1,8 @@
package net.osmand.plus.routepreparationmenu; package net.osmand.plus.routepreparationmenu;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity; import android.app.Activity;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
@ -19,7 +16,6 @@ import android.view.ViewGroup.MarginLayoutParams;
import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.ViewTreeObserver.OnScrollChangedListener;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -37,6 +33,7 @@ import net.osmand.data.RotatedTileBox;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.SimplePopUpMenuItemAdapter.SimplePopUpMenuItem;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.UiUtilities.DialogButtonType; import net.osmand.plus.UiUtilities.DialogButtonType;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
@ -44,6 +41,7 @@ import net.osmand.plus.base.ContextMenuScrollFragment;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
import net.osmand.plus.helpers.enums.TracksSortByMode;
import net.osmand.plus.importfiles.ImportHelper; import net.osmand.plus.importfiles.ImportHelper;
import net.osmand.plus.importfiles.ImportHelper.OnGpxImportCompleteListener; import net.osmand.plus.importfiles.ImportHelper.OnGpxImportCompleteListener;
import net.osmand.plus.measurementtool.GpxData; import net.osmand.plus.measurementtool.GpxData;
@ -71,6 +69,7 @@ import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -89,6 +88,10 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
private GPXFile gpxFile; private GPXFile gpxFile;
private View buttonsShadow; private View buttonsShadow;
private ImageButton sortButton;
private TracksToFollowCard tracksCard;
private TracksSortByMode sortByMode = TracksSortByMode.BY_DATE;
private boolean editingTrack; private boolean editingTrack;
private boolean selectingTrack; private boolean selectingTrack;
@ -166,6 +169,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
} }
setupCards(); setupCards();
setupButtons(view); setupButtons(view);
setupSortButton(view);
setupScrollShadow(); setupScrollShadow();
if (!isPortrait()) { if (!isPortrait()) {
int widthNoShadow = getLandscapeNoShadowWidth(); int widthNoShadow = getLandscapeNoShadowWidth();
@ -202,10 +206,6 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
cardsContainer.removeAllViews(); cardsContainer.removeAllViews();
if (gpxFile == null || selectingTrack) { if (gpxFile == null || selectingTrack) {
ImportTrackCard importTrackCard = new ImportTrackCard(mapActivity);
importTrackCard.setListener(this);
cardsContainer.addView(importTrackCard.build(mapActivity));
setupTracksCard(); setupTracksCard();
} else { } else {
String fileName = null; String fileName = null;
@ -265,7 +265,7 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
List<GPXInfo> list = GpxUiHelper.getSortedGPXFilesInfo(dir, selectedTrackNames, false); List<GPXInfo> list = GpxUiHelper.getSortedGPXFilesInfo(dir, selectedTrackNames, false);
if (list.size() > 0) { if (list.size() > 0) {
String defaultCategory = app.getString(R.string.shared_string_all); String defaultCategory = app.getString(R.string.shared_string_all);
TracksToFollowCard tracksCard = new TracksToFollowCard(mapActivity, list, defaultCategory); tracksCard = new TracksToFollowCard(mapActivity, list, defaultCategory);
tracksCard.setListener(FollowTrackFragment.this); tracksCard.setListener(FollowTrackFragment.this);
getCardsContainer().addView(tracksCard.build(mapActivity)); getCardsContainer().addView(tracksCard.build(mapActivity));
} }
@ -601,6 +601,36 @@ public class FollowTrackFragment extends ContextMenuScrollFragment implements Ca
} }
} }
private void setupSortButton(View view) {
final ImageButton sortButton = view.findViewById(R.id.sort_button);
int colorId = isNightMode() ? R.color.inactive_buttons_and_links_bg_dark : R.color.inactive_buttons_and_links_bg_light;
Drawable background = app.getUIUtilities().getIcon(R.drawable.bg_dash_line_dark, colorId);
sortButton.setImageResource(sortByMode.getIconId());
AndroidUtils.setBackground(sortButton, background);
sortButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
List<SimplePopUpMenuItem> items = new ArrayList<>();
for (final TracksSortByMode mode : TracksSortByMode.values()) {
items.add(new SimplePopUpMenuItem(getString(mode.getNameId()),
app.getUIUtilities().getThemedIcon(mode.getIconId()),
new View.OnClickListener() {
@Override
public void onClick(View v) {
sortByMode = mode;
sortButton.setImageResource(mode.getIconId());
if (tracksCard != null) {
tracksCard.setSortByMode(mode);
}
}
}, sortByMode == mode
));
}
UiUtilities.showPopUpMenu(v, items);
}
});
}
private void setupButtons(View view) { private void setupButtons(View view) {
View buttonsContainer = view.findViewById(R.id.buttons_container); View buttonsContainer = view.findViewById(R.id.buttons_container);
buttonsContainer.setBackgroundColor(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.bg_color)); buttonsContainer.setBackgroundColor(AndroidUtils.getColorFromAttr(view.getContext(), R.attr.bg_color));

View file

@ -3,30 +3,36 @@ package net.osmand.plus.routepreparationmenu.cards;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import net.osmand.Collator;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.OsmAndCollator;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.GpxTrackAdapter; import net.osmand.plus.helpers.GpxTrackAdapter;
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
import net.osmand.plus.helpers.enums.TracksSortByMode;
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class TracksToFollowCard extends BaseCard { public class TracksToFollowCard extends BaseCard {
private List<GPXInfo> gpxInfoList;
private Map<String, List<GPXInfo>> gpxInfoCategories; private Map<String, List<GPXInfo>> gpxInfoCategories;
private List<GPXInfo> gpxInfoList; private GpxTrackAdapter tracksAdapter;
private String selectedCategory; private TracksSortByMode sortByMode = TracksSortByMode.BY_DATE;
private String defaultCategory; private String defaultCategory;
private String visibleCategory; private String visibleCategory;
private String selectedCategory;
private GpxTrackAdapter tracksAdapter;
public TracksToFollowCard(MapActivity mapActivity, List<GPXInfo> gpxInfoList, String selectedCategory) { public TracksToFollowCard(MapActivity mapActivity, List<GPXInfo> gpxInfoList, String selectedCategory) {
super(mapActivity); super(mapActivity);
@ -37,9 +43,10 @@ public class TracksToFollowCard extends BaseCard {
gpxInfoCategories = getGpxInfoCategories(); gpxInfoCategories = getGpxInfoCategories();
} }
public void setGpxInfoList(List<GPXInfo> gpxInfoList) { public void setSortByMode(TracksSortByMode sortByMode) {
this.gpxInfoList = gpxInfoList; this.sortByMode = sortByMode;
gpxInfoCategories = getGpxInfoCategories(); gpxInfoCategories = getGpxInfoCategories();
updateTracksAdapter();
} }
public List<GPXInfo> getGpxInfoList() { public List<GPXInfo> getGpxInfoList() {
@ -91,11 +98,8 @@ public class TracksToFollowCard extends BaseCard {
@Override @Override
public void onItemSelected(HorizontalSelectionAdapter.HorizontalSelectionItem item) { public void onItemSelected(HorizontalSelectionAdapter.HorizontalSelectionItem item) {
selectedCategory = item.getTitle(); selectedCategory = item.getTitle();
List<GPXInfo> items = gpxInfoCategories.get(selectedCategory);
tracksAdapter.setShowFolderName(showFoldersName()); tracksAdapter.setShowFolderName(showFoldersName());
tracksAdapter.setGpxInfoList(items != null ? items : new ArrayList<GPXInfo>()); updateTracksAdapter();
tracksAdapter.notifyDataSetChanged();
selectionAdapter.notifyDataSetChanged(); selectionAdapter.notifyDataSetChanged();
} }
}); });
@ -106,6 +110,12 @@ public class TracksToFollowCard extends BaseCard {
selectionAdapter.notifyDataSetChanged(); selectionAdapter.notifyDataSetChanged();
} }
private void updateTracksAdapter() {
List<GPXInfo> items = gpxInfoCategories.get(selectedCategory);
tracksAdapter.setGpxInfoList(items != null ? items : new ArrayList<GPXInfo>());
tracksAdapter.notifyDataSetChanged();
}
private boolean showFoldersName() { private boolean showFoldersName() {
return defaultCategory.equals(selectedCategory) || visibleCategory.equals(selectedCategory); return defaultCategory.equals(selectedCategory) || visibleCategory.equals(selectedCategory);
} }
@ -116,6 +126,7 @@ public class TracksToFollowCard extends BaseCard {
gpxInfoCategories.put(visibleCategory, new ArrayList<GPXInfo>()); gpxInfoCategories.put(visibleCategory, new ArrayList<GPXInfo>());
gpxInfoCategories.put(defaultCategory, new ArrayList<GPXInfo>()); gpxInfoCategories.put(defaultCategory, new ArrayList<GPXInfo>());
sortGPXInfoItems(gpxInfoList);
for (GPXInfo info : gpxInfoList) { for (GPXInfo info : gpxInfoList) {
if (info.isSelected()) { if (info.isSelected()) {
addGpxInfoCategory(gpxInfoCategories, info, visibleCategory); addGpxInfoCategory(gpxInfoCategories, info, visibleCategory);
@ -141,4 +152,25 @@ public class TracksToFollowCard extends BaseCard {
} }
items.add(info); items.add(info);
} }
public void sortGPXInfoItems(List<GPXInfo> gpxInfoList) {
final Collator collator = OsmAndCollator.primaryCollator();
Collections.sort(gpxInfoList, new Comparator<GPXInfo>() {
@Override
public int compare(GPXInfo i1, GPXInfo i2) {
if (sortByMode == TracksSortByMode.BY_NAME_ASCENDING) {
return collator.compare(i1.getFileName(), i2.getFileName());
} else if (sortByMode == TracksSortByMode.BY_NAME_DESCENDING) {
return -collator.compare(i1.getFileName(), i2.getFileName());
} else {
long time1 = i1.getLastModified();
long time2 = i2.getLastModified();
if (time1 == time2) {
return collator.compare(i1.getFileName(), i2.getFileName());
}
return -((time1 < time2) ? -1 : ((time1 == time2) ? 0 : 1));
}
}
});
}
} }

View file

@ -1,20 +1,22 @@
package net.osmand.plus.routing; package net.osmand.plus.routing;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.SoundPool; import android.media.SoundPool;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.StateChangedListener;
import net.osmand.binary.RouteDataObject; import net.osmand.binary.RouteDataObject;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmAndAppCustomization.OsmAndAppCustomizationListener;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.helpers.WaypointHelper.LocationPointWrapper; import net.osmand.plus.helpers.WaypointHelper.LocationPointWrapper;
import net.osmand.plus.routing.AlarmInfo.AlarmInfoType; import net.osmand.plus.routing.AlarmInfo.AlarmInfoType;
import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo;
import net.osmand.plus.routing.data.StreetName; import net.osmand.plus.routing.data.StreetName;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmAndAppCustomization.OsmAndAppCustomizationListener;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.voice.AbstractPrologCommandPlayer; import net.osmand.plus.voice.AbstractPrologCommandPlayer;
import net.osmand.plus.voice.CommandBuilder; import net.osmand.plus.voice.CommandBuilder;
import net.osmand.plus.voice.CommandPlayer; import net.osmand.plus.voice.CommandPlayer;
@ -81,6 +83,9 @@ public class VoiceRouter {
private int TURN_IN_DISTANCE_END; private int TURN_IN_DISTANCE_END;
private int TURN_NOW_DISTANCE; private int TURN_NOW_DISTANCE;
private SoundPool soundPool;
private int soundClick = -1;
private VoiceCommandPending pendingCommand = null; private VoiceCommandPending pendingCommand = null;
private RouteDirectionInfo nextRouteDirection; private RouteDirectionInfo nextRouteDirection;
@ -103,6 +108,34 @@ public class VoiceRouter {
} }
}; };
app.getAppCustomization().addListener(customizationListener); app.getAppCustomization().addListener(customizationListener);
if (!isMute()) {
loadCameraSound();
}
settings.VOICE_MUTE.addListener(new StateChangedListener<Boolean>() {
@Override
public void stateChanged(Boolean change) {
if (!isMute() && soundPool == null) {
loadCameraSound();
}
}
});
}
private void loadCameraSound() {
if (soundPool == null) {
soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
}
if (soundClick == -1) {
try {
// Taken unaltered from https://freesound.org/people/Corsica_S/sounds/91926/ under license http://creativecommons.org/licenses/by/3.0/ :
AssetFileDescriptor assetFileDescriptor = app.getAssets().openFd("sounds/ding.ogg");
soundClick = soundPool.load(assetFileDescriptor, 1);
assetFileDescriptor.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }
public void setPlayer(CommandPlayer player) { public void setPlayer(CommandPlayer player) {
@ -1015,18 +1048,8 @@ public class VoiceRouter {
if (isMute()) { if (isMute()) {
return; return;
} }
SoundPool sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0); if (soundPool != null && soundClick != -1) {
int soundClick = -1; soundPool.play(soundClick, 1, 1, 0, 0, 1);
boolean success = true;
try {
// Taken unaltered from https://freesound.org/people/Corsica_S/sounds/91926/ under license http://creativecommons.org/licenses/by/3.0/ :
soundClick = sp.load(settings.getContext().getAssets().openFd("sounds/ding.ogg"), 1);
} catch (IOException e) {
e.printStackTrace();
success = false;
}
if (success) {
sp.play(soundClick, 1 ,1, 0, 0, 1);
} }
} }

View file

@ -10,5 +10,8 @@ public enum ExportSettingsType {
AVOID_ROADS, AVOID_ROADS,
TRACKS, TRACKS,
MULTIMEDIA_NOTES, MULTIMEDIA_NOTES,
GLOBAL GLOBAL,
OSM_NOTES,
OSM_EDITS,
OFFLINE_MAPS
} }

View file

@ -21,11 +21,15 @@ import java.io.OutputStream;
public class FileSettingsItem extends StreamSettingsItem { public class FileSettingsItem extends StreamSettingsItem {
public enum FileSubtype { public enum FileSubtype {
UNKNOWN("", null), UNKNOWN("", null),
OTHER("other", ""), OTHER("other", ""),
ROUTING_CONFIG("routing_config", IndexConstants.ROUTING_PROFILES_DIR), ROUTING_CONFIG("routing_config", IndexConstants.ROUTING_PROFILES_DIR),
RENDERING_STYLE("rendering_style", IndexConstants.RENDERERS_DIR), RENDERING_STYLE("rendering_style", IndexConstants.RENDERERS_DIR),
WIKI_MAP("wiki_map", IndexConstants.WIKI_INDEX_DIR),
SRTM_MAP("srtm_map", IndexConstants.SRTM_INDEX_DIR),
OBF_MAP("obf_map", IndexConstants.MAPS_PATH), OBF_MAP("obf_map", IndexConstants.MAPS_PATH),
TILES_MAP("tiles_map", IndexConstants.TILES_INDEX_DIR), TILES_MAP("tiles_map", IndexConstants.TILES_INDEX_DIR),
GPX("gpx", IndexConstants.GPX_INDEX_DIR), GPX("gpx", IndexConstants.GPX_INDEX_DIR),
@ -41,6 +45,10 @@ public class FileSettingsItem extends StreamSettingsItem {
this.subtypeFolder = subtypeFolder; this.subtypeFolder = subtypeFolder;
} }
public boolean isMap() {
return this == OBF_MAP || this == WIKI_MAP || this == SRTM_MAP;
}
public String getSubtypeName() { public String getSubtypeName() {
return subtypeName; return subtypeName;
} }
@ -68,8 +76,18 @@ public class FileSettingsItem extends StreamSettingsItem {
case UNKNOWN: case UNKNOWN:
case OTHER: case OTHER:
break; break;
case SRTM_MAP:
if (name.endsWith(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)) {
return subtype;
}
break;
case WIKI_MAP:
if (name.endsWith(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT)) {
return subtype;
}
break;
case OBF_MAP: case OBF_MAP:
if (name.endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) { if (name.endsWith(IndexConstants.BINARY_MAP_INDEX_EXT) && !name.contains(File.separator)) {
return subtype; return subtype;
} }
break; break;
@ -93,6 +111,7 @@ public class FileSettingsItem extends StreamSettingsItem {
protected File file; protected File file;
private File appPath; private File appPath;
protected FileSubtype subtype; protected FileSubtype subtype;
private long size;
public FileSettingsItem(@NonNull OsmandApplication app, @NonNull File file) throws IllegalArgumentException { public FileSettingsItem(@NonNull OsmandApplication app, @NonNull File file) throws IllegalArgumentException {
super(app, file.getPath().replace(app.getAppPath(null).getPath(), "")); super(app, file.getPath().replace(app.getAppPath(null).getPath(), ""));
@ -171,6 +190,14 @@ public class FileSettingsItem extends StreamSettingsItem {
} }
} }
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
@NonNull @NonNull
public File getFile() { public File getFile() {
return file; return file;

View file

@ -0,0 +1,199 @@
package net.osmand.plus.settings.backend.backup;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import net.osmand.osm.edit.Entity;
import net.osmand.osm.edit.Node;
import net.osmand.osm.edit.Way;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OpenstreetmapsDbHelper;
import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.osmedit.OsmPoint;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class OsmEditsSettingsItem extends CollectionSettingsItem<OpenstreetmapPoint> {
public static final String ID_KEY = "id";
public static final String NAME_KEY = "name";
public static final String LAT_KEY = "lat";
public static final String LON_KEY = "lon";
public static final String COMMENT_KEY = "comment";
public static final String ACTION_KEY = "action";
public static final String TYPE_KEY = "type";
public static final String TAGS_KEY = "tags";
public static final String ENTITY_KEY = "entity";
public OsmEditsSettingsItem(@NonNull OsmandApplication app, @NonNull List<OpenstreetmapPoint> items) {
super(app, null, items);
}
public OsmEditsSettingsItem(@NonNull OsmandApplication app, @Nullable OsmEditsSettingsItem baseItem,
@NonNull List<OpenstreetmapPoint> items) {
super(app, baseItem, items);
}
public OsmEditsSettingsItem(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
super(app, json);
}
@Override
protected void init() {
super.init();
OsmEditingPlugin osmEditingPlugin = OsmandPlugin.getPlugin(OsmEditingPlugin.class);
if (osmEditingPlugin != null) {
existingItems = osmEditingPlugin.getDBPOI().getOpenstreetmapPoints();
}
}
@NonNull
@Override
public SettingsItemType getType() {
return SettingsItemType.OSM_EDITS;
}
@Override
public void apply() {
List<OpenstreetmapPoint> newItems = getNewItems();
if (!newItems.isEmpty() || !duplicateItems.isEmpty()) {
appliedItems = new ArrayList<>(newItems);
for (OpenstreetmapPoint duplicate : duplicateItems) {
appliedItems.add(shouldReplace ? duplicate : renameItem(duplicate));
}
}
OsmEditingPlugin osmEditingPlugin = OsmandPlugin.getPlugin(OsmEditingPlugin.class);
if (osmEditingPlugin != null) {
OpenstreetmapsDbHelper db = osmEditingPlugin.getDBPOI();
for (OpenstreetmapPoint point : appliedItems) {
db.addOpenstreetmap(point);
}
}
}
@Override
public boolean isDuplicate(@NonNull OpenstreetmapPoint item) {
return false;
}
@NonNull
@Override
public OpenstreetmapPoint renameItem(@NonNull OpenstreetmapPoint item) {
return item;
}
@NonNull
@Override
public String getName() {
return "osm_edits";
}
@NonNull
@Override
public String getPublicName(@NonNull Context ctx) {
return ctx.getString(R.string.osm_edits);
}
@Override
public boolean shouldReadOnCollecting() {
return true;
}
@Override
void readItemsFromJson(@NonNull JSONObject json) throws IllegalArgumentException {
try {
if (!json.has("items")) {
return;
}
JSONArray jsonArray = json.getJSONArray("items");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonPoint = jsonArray.getJSONObject(i);
String comment = jsonPoint.optString(COMMENT_KEY);
comment = comment.isEmpty() ? null : comment;
JSONObject entityJson = jsonPoint.getJSONObject(ENTITY_KEY);
long id = entityJson.getLong(ID_KEY);
double lat = entityJson.getDouble(LAT_KEY);
double lon = entityJson.getDouble(LON_KEY);
String tags = entityJson.getString(TAGS_KEY);
Map<String, String> tagMap = new Gson().fromJson(
tags, new TypeToken<HashMap<String, String>>() {
}.getType()
);
String action = entityJson.getString(ACTION_KEY);
Entity entity;
if (entityJson.get(TYPE_KEY).equals(Entity.EntityType.NODE.name())) {
entity = new Node(lat, lon, id);
} else {
entity = new Way(id);
entity.setLatitude(lat);
entity.setLongitude(lon);
}
entity.replaceTags(tagMap);
OpenstreetmapPoint point = new OpenstreetmapPoint();
point.setComment(comment);
point.setEntity(entity);
point.setAction(action);
items.add(point);
}
} catch (JSONException e) {
warnings.add(app.getString(R.string.settings_item_read_error, String.valueOf(getType())));
throw new IllegalArgumentException("Json parse error", e);
}
}
@Override
void writeItemsToJson(@NonNull JSONObject json) {
JSONArray jsonArray = new JSONArray();
if (!items.isEmpty()) {
try {
for (OpenstreetmapPoint point : items) {
JSONObject jsonPoint = new JSONObject();
JSONObject jsonEntity = new JSONObject();
jsonEntity.put(ID_KEY, point.getId());
jsonEntity.put(NAME_KEY, point.getTagsString());
jsonEntity.put(LAT_KEY, point.getLatitude());
jsonEntity.put(LON_KEY, point.getLongitude());
jsonEntity.put(TYPE_KEY, Entity.EntityType.valueOf(point.getEntity()));
JSONObject jsonTags = new JSONObject(point.getEntity().getTags());
jsonEntity.put(TAGS_KEY, jsonTags);
jsonPoint.put(COMMENT_KEY, point.getComment());
jsonEntity.put(ACTION_KEY, OsmPoint.stringAction.get(point.getAction()));
jsonPoint.put(ENTITY_KEY, jsonEntity);
jsonArray.put(jsonPoint);
}
json.put("items", jsonArray);
} catch (JSONException e) {
warnings.add(app.getString(R.string.settings_item_write_error, String.valueOf(getType())));
SettingsHelper.LOG.error("Failed write to json", e);
}
}
}
@Nullable
@Override
SettingsItemReader<? extends SettingsItem> getReader() {
return getJsonReader();
}
@Nullable
@Override
SettingsItemWriter<? extends SettingsItem> getWriter() {
return null;
}
}

View file

@ -0,0 +1,172 @@
package net.osmand.plus.settings.backend.backup;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.osmedit.OsmBugsDbHelper;
import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.osmedit.OsmNotesPoint;
import net.osmand.plus.osmedit.OsmPoint;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class OsmNotesSettingsItem extends CollectionSettingsItem<OsmNotesPoint> {
public static final String ID_KEY = "id";
public static final String TEXT_KEY = "text";
public static final String LAT_KEY = "lat";
public static final String LON_KEY = "lon";
public static final String AUTHOR_KEY = "author";
public static final String ACTION_KEY = "action";
public OsmNotesSettingsItem(@NonNull OsmandApplication app, @NonNull List<OsmNotesPoint> items) {
super(app, null, items);
}
public OsmNotesSettingsItem(@NonNull OsmandApplication app, @Nullable OsmNotesSettingsItem baseItem,
@NonNull List<OsmNotesPoint> items) {
super(app, baseItem, items);
}
public OsmNotesSettingsItem(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
super(app, json);
}
@Override
protected void init() {
super.init();
OsmEditingPlugin osmEditingPlugin = OsmandPlugin.getPlugin(OsmEditingPlugin.class);
if (osmEditingPlugin != null) {
existingItems = osmEditingPlugin.getDBBug().getOsmbugsPoints();
}
}
@NonNull
@Override
public SettingsItemType getType() {
return SettingsItemType.OSM_NOTES;
}
@Override
public void apply() {
List<OsmNotesPoint> newItems = getNewItems();
if (!newItems.isEmpty() || !duplicateItems.isEmpty()) {
appliedItems = new ArrayList<>(newItems);
for (OsmNotesPoint duplicate : duplicateItems) {
appliedItems.add(shouldReplace ? duplicate : renameItem(duplicate));
}
OsmEditingPlugin osmEditingPlugin = OsmandPlugin.getPlugin(OsmEditingPlugin.class);
if (osmEditingPlugin != null) {
OsmBugsDbHelper db = osmEditingPlugin.getDBBug();
for (OsmNotesPoint point : appliedItems) {
db.addOsmbugs(point);
}
}
}
}
@Override
public boolean isDuplicate(@NonNull OsmNotesPoint item) {
return false;
}
@NonNull
@Override
public OsmNotesPoint renameItem(@NonNull OsmNotesPoint item) {
return item;
}
@NonNull
@Override
public String getName() {
return "osm_notes";
}
@NonNull
@Override
public String getPublicName(@NonNull Context ctx) {
return ctx.getString(R.string.osm_notes);
}
@Override
public boolean shouldReadOnCollecting() {
return true;
}
@Override
void readItemsFromJson(@NonNull JSONObject json) throws IllegalArgumentException {
try {
if (!json.has("items")) {
return;
}
JSONArray jsonArray = json.getJSONArray("items");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
long id = object.getLong(ID_KEY);
String text = object.optString(TEXT_KEY);
double lat = object.getDouble(LAT_KEY);
double lon = object.getDouble(LON_KEY);
String author = object.optString(AUTHOR_KEY);
author = author.isEmpty() ? null : author;
String action = object.getString(ACTION_KEY);
OsmNotesPoint point = new OsmNotesPoint();
point.setId(id);
point.setText(text);
point.setLatitude(lat);
point.setLongitude(lon);
point.setAuthor(author);
point.setAction(action);
items.add(point);
}
} catch (JSONException e) {
warnings.add(app.getString(R.string.settings_item_read_error, String.valueOf(getType())));
throw new IllegalArgumentException("Json parse error", e);
}
}
@Override
void writeItemsToJson(@NonNull JSONObject json) {
JSONArray jsonArray = new JSONArray();
if (!items.isEmpty()) {
try {
for (OsmNotesPoint point : items) {
JSONObject jsonObject = new JSONObject();
jsonObject.put(ID_KEY, point.getId());
jsonObject.put(TEXT_KEY, point.getText());
jsonObject.put(LAT_KEY, point.getLatitude());
jsonObject.put(LON_KEY, point.getLongitude());
jsonObject.put(AUTHOR_KEY, point.getAuthor());
jsonObject.put(ACTION_KEY, OsmPoint.stringAction.get(point.getAction()));
jsonArray.put(jsonObject);
}
json.put("items", jsonArray);
} catch (JSONException e) {
warnings.add(app.getString(R.string.settings_item_write_error, String.valueOf(getType())));
SettingsHelper.LOG.error("Failed write to json", e);
}
}
}
@Nullable
@Override
SettingsItemReader<? extends SettingsItem> getReader() {
return getJsonReader();
}
@Nullable
@Override
SettingsItemWriter<? extends SettingsItem> getWriter() {
return null;
}
}

View file

@ -16,11 +16,17 @@ import net.osmand.map.TileSourceManager.TileSourceTemplate;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.SQLiteTileSource; import net.osmand.plus.SQLiteTileSource;
import net.osmand.plus.activities.LocalIndexHelper;
import net.osmand.plus.activities.LocalIndexInfo;
import net.osmand.plus.audionotes.AudioVideoNotesPlugin; import net.osmand.plus.audionotes.AudioVideoNotesPlugin;
import net.osmand.plus.audionotes.AudioVideoNotesPlugin.Recording; import net.osmand.plus.audionotes.AudioVideoNotesPlugin.Recording;
import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.osmedit.OsmNotesPoint;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.quickaction.QuickAction; import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.quickaction.QuickActionRegistry; import net.osmand.plus.quickaction.QuickActionRegistry;
@ -41,6 +47,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT; import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT;
import static net.osmand.plus.activities.LocalIndexHelper.*;
/* /*
Usage: Usage:
@ -513,9 +520,41 @@ public class SettingsHelper {
} }
dataList.put(ExportSettingsType.PROFILE, appModeBeans); dataList.put(ExportSettingsType.PROFILE, appModeBeans);
} }
OsmEditingPlugin osmEditingPlugin = OsmandPlugin.getPlugin(OsmEditingPlugin.class);
if (osmEditingPlugin != null) {
List<OsmNotesPoint> notesPointList = osmEditingPlugin.getDBBug().getOsmbugsPoints();
if (!notesPointList.isEmpty()) {
dataList.put(ExportSettingsType.OSM_NOTES, notesPointList);
}
List<OpenstreetmapPoint> editsPointList = osmEditingPlugin.getDBPOI().getOpenstreetmapPoints();
if (!editsPointList.isEmpty()) {
dataList.put(ExportSettingsType.OSM_EDITS, editsPointList);
}
}
List<File> files = getLocalMapFiles();
if (!files.isEmpty()) {
dataList.put(ExportSettingsType.OFFLINE_MAPS, files);
}
return dataList; return dataList;
} }
private List<File> getLocalMapFiles() {
List<File> files = new ArrayList<>();
LocalIndexHelper helper = new LocalIndexHelper(app);
List<LocalIndexInfo> localMapFileList = helper.getLocalIndexData(new AbstractLoadLocalIndexTask() {
@Override
public void loadFile(LocalIndexInfo... loaded) {
}
});
for (LocalIndexInfo map : localMapFileList) {
File file = new File(map.getPathToData());
if (file != null && file.exists() && map.getType() != LocalIndexType.TTS_VOICE_DATA) {
files.add(file);
}
}
return files;
}
public List<SettingsItem> prepareAdditionalSettingsItems(List<? super Object> data) { public List<SettingsItem> prepareAdditionalSettingsItems(List<? super Object> data) {
List<SettingsItem> settingsItems = new ArrayList<>(); List<SettingsItem> settingsItems = new ArrayList<>();
List<QuickAction> quickActions = new ArrayList<>(); List<QuickAction> quickActions = new ArrayList<>();
@ -523,6 +562,9 @@ public class SettingsHelper {
List<ITileSource> tileSourceTemplates = new ArrayList<>(); List<ITileSource> tileSourceTemplates = new ArrayList<>();
List<AvoidRoadInfo> avoidRoads = new ArrayList<>(); List<AvoidRoadInfo> avoidRoads = new ArrayList<>();
List<ApplicationModeBean> appModeBeans = new ArrayList<>(); List<ApplicationModeBean> appModeBeans = new ArrayList<>();
List<OsmNotesPoint> osmNotesPointList = new ArrayList<>();
List<OpenstreetmapPoint> osmEditsPointList = new ArrayList<>();
for (Object object : data) { for (Object object : data) {
if (object instanceof QuickAction) { if (object instanceof QuickAction) {
quickActions.add((QuickAction) object); quickActions.add((QuickAction) object);
@ -540,6 +582,10 @@ public class SettingsHelper {
avoidRoads.add((AvoidRoadInfo) object); avoidRoads.add((AvoidRoadInfo) object);
} else if (object instanceof ApplicationModeBean) { } else if (object instanceof ApplicationModeBean) {
appModeBeans.add((ApplicationModeBean) object); appModeBeans.add((ApplicationModeBean) object);
} else if (object instanceof OsmNotesPoint) {
osmNotesPointList.add((OsmNotesPoint) object);
} else if (object instanceof OpenstreetmapPoint) {
osmEditsPointList.add((OpenstreetmapPoint) object);
} }
} }
if (!quickActions.isEmpty()) { if (!quickActions.isEmpty()) {
@ -562,6 +608,12 @@ public class SettingsHelper {
} }
} }
} }
if (!osmNotesPointList.isEmpty()) {
settingsItems.add(new OsmNotesSettingsItem(app, osmNotesPointList));
}
if (!osmEditsPointList.isEmpty()) {
settingsItems.add(new OsmEditsSettingsItem(app, osmEditsPointList));
}
return settingsItems; return settingsItems;
} }
@ -575,8 +627,11 @@ public class SettingsHelper {
List<File> renderFilesList = new ArrayList<>(); List<File> renderFilesList = new ArrayList<>();
List<File> multimediaFilesList = new ArrayList<>(); List<File> multimediaFilesList = new ArrayList<>();
List<File> tracksFilesList = new ArrayList<>(); List<File> tracksFilesList = new ArrayList<>();
List<FileSettingsItem> mapFilesList = new ArrayList<>();
List<AvoidRoadInfo> avoidRoads = new ArrayList<>(); List<AvoidRoadInfo> avoidRoads = new ArrayList<>();
List<GlobalSettingsItem> globalSettingsItems = new ArrayList<>(); List<GlobalSettingsItem> globalSettingsItems = new ArrayList<>();
List<OsmNotesPoint> notesPointList = new ArrayList<>();
List<OpenstreetmapPoint> editsPointList = new ArrayList<>();
for (SettingsItem item : settingsItems) { for (SettingsItem item : settingsItems) {
switch (item.getType()) { switch (item.getType()) {
case PROFILE: case PROFILE:
@ -592,6 +647,11 @@ public class SettingsHelper {
multimediaFilesList.add(fileItem.getFile()); multimediaFilesList.add(fileItem.getFile());
} else if (fileItem.getSubtype() == FileSettingsItem.FileSubtype.GPX) { } else if (fileItem.getSubtype() == FileSettingsItem.FileSubtype.GPX) {
tracksFilesList.add(fileItem.getFile()); tracksFilesList.add(fileItem.getFile());
} else if (fileItem.getSubtype() == FileSettingsItem.FileSubtype.OBF_MAP
|| fileItem.getSubtype() == FileSettingsItem.FileSubtype.WIKI_MAP
|| fileItem.getSubtype() == FileSettingsItem.FileSubtype.SRTM_MAP
|| fileItem.getSubtype() == FileSettingsItem.FileSubtype.TILES_MAP) {
mapFilesList.add(fileItem);
} }
break; break;
case QUICK_ACTIONS: case QUICK_ACTIONS:
@ -629,6 +689,22 @@ public class SettingsHelper {
case GLOBAL: case GLOBAL:
globalSettingsItems.add((GlobalSettingsItem) item); globalSettingsItems.add((GlobalSettingsItem) item);
break; break;
case OSM_NOTES:
OsmNotesSettingsItem osmNotesSettingsItem = (OsmNotesSettingsItem) item;
if (importComplete) {
notesPointList.addAll(osmNotesSettingsItem.getAppliedItems());
} else {
notesPointList.addAll(osmNotesSettingsItem.getItems());
}
break;
case OSM_EDITS:
OsmEditsSettingsItem osmEditsSettingsItem = (OsmEditsSettingsItem) item;
if (importComplete) {
editsPointList.addAll(osmEditsSettingsItem.getAppliedItems());
} else {
editsPointList.addAll(osmEditsSettingsItem.getItems());
}
break;
default: default:
break; break;
} }
@ -664,6 +740,15 @@ public class SettingsHelper {
if (!globalSettingsItems.isEmpty()) { if (!globalSettingsItems.isEmpty()) {
settingsToOperate.put(ExportSettingsType.GLOBAL, globalSettingsItems); settingsToOperate.put(ExportSettingsType.GLOBAL, globalSettingsItems);
} }
if (!notesPointList.isEmpty()) {
settingsToOperate.put(ExportSettingsType.OSM_NOTES, notesPointList);
}
if (!editsPointList.isEmpty()) {
settingsToOperate.put(ExportSettingsType.OSM_EDITS, editsPointList);
}
if (!mapFilesList.isEmpty()) {
settingsToOperate.put(ExportSettingsType.OFFLINE_MAPS, mapFilesList);
}
return settingsToOperate; return settingsToOperate;
} }
} }

View file

@ -15,8 +15,10 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT; import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT;
@ -57,7 +59,9 @@ class SettingsImporter {
} }
try { try {
SettingsItemsFactory itemsFactory = new SettingsItemsFactory(app, itemsJson); SettingsItemsFactory itemsFactory = new SettingsItemsFactory(app, itemsJson);
items.addAll(itemsFactory.getItems()); List<SettingsItem> settingsItemList = itemsFactory.getItems();
getFilesSize(file, settingsItemList);
items.addAll(settingsItemList);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
SettingsHelper.LOG.error("Error parsing items: " + itemsJson, e); SettingsHelper.LOG.error("Error parsing items: " + itemsJson, e);
throw new IllegalArgumentException("No items"); throw new IllegalArgumentException("No items");
@ -77,6 +81,22 @@ class SettingsImporter {
return items; return items;
} }
private void getFilesSize(@NonNull File file, List<SettingsItem> settingsItemList) throws IOException {
ZipFile zipfile = new ZipFile(file.getPath());
Enumeration<? extends ZipEntry> zipEnum = zipfile.entries();
while (zipEnum.hasMoreElements()) {
ZipEntry zipEntry = zipEnum.nextElement();
long size = zipEntry.getSize();
for (SettingsItem settingsItem : settingsItemList) {
if (settingsItem instanceof FileSettingsItem
&& zipEntry.getName().equals(settingsItem.getFileName())) {
((FileSettingsItem) settingsItem).setSize(size);
break;
}
}
}
}
private List<SettingsItem> processItems(@NonNull File file, @Nullable List<SettingsItem> items) throws IllegalArgumentException, IOException { private List<SettingsItem> processItems(@NonNull File file, @Nullable List<SettingsItem> items) throws IllegalArgumentException, IOException {
boolean collecting = items == null; boolean collecting = items == null;
if (collecting) { if (collecting) {

View file

@ -12,5 +12,7 @@ public enum SettingsItemType {
MAP_SOURCES, MAP_SOURCES,
AVOID_ROADS, AVOID_ROADS,
SUGGESTED_DOWNLOADS, SUGGESTED_DOWNLOADS,
DOWNLOADS DOWNLOADS,
OSM_NOTES,
OSM_EDITS,
} }

View file

@ -125,6 +125,12 @@ class SettingsItemsFactory {
case DOWNLOADS: case DOWNLOADS:
item = new DownloadsItem(app, json); item = new DownloadsItem(app, json);
break; break;
case OSM_NOTES:
item = new OsmNotesSettingsItem(app, json);
break;
case OSM_EDITS:
item = new OsmEditsSettingsItem(app, json);
break;
} }
return item; return item;
} }

View file

@ -22,7 +22,11 @@ import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter; import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
import net.osmand.plus.audionotes.AudioVideoNotesPlugin; import net.osmand.plus.audionotes.AudioVideoNotesPlugin;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.osmedit.OsmNotesPoint;
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;
@ -32,6 +36,7 @@ import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean; import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean;
import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.settings.backend.ExportSettingsType;
import net.osmand.plus.settings.backend.backup.GlobalSettingsItem; import net.osmand.plus.settings.backend.backup.GlobalSettingsItem;
import net.osmand.plus.settings.backend.backup.FileSettingsItem;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.view.ThreeStateCheckbox; import net.osmand.view.ThreeStateCheckbox;
@ -44,6 +49,8 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static net.osmand.plus.settings.backend.ExportSettingsType.*;
import static net.osmand.plus.settings.backend.backup.FileSettingsItem.*;
import static net.osmand.view.ThreeStateCheckbox.State.CHECKED; import static net.osmand.view.ThreeStateCheckbox.State.CHECKED;
import static net.osmand.view.ThreeStateCheckbox.State.MISC; import static net.osmand.view.ThreeStateCheckbox.State.MISC;
import static net.osmand.view.ThreeStateCheckbox.State.UNCHECKED; import static net.osmand.view.ThreeStateCheckbox.State.UNCHECKED;
@ -103,7 +110,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
cardBottomDivider.setVisibility(importState && !isExpanded ? View.VISIBLE : View.GONE); cardBottomDivider.setVisibility(importState && !isExpanded ? View.VISIBLE : View.GONE);
final List<?> listItems = itemsMap.get(type); final List<?> listItems = itemsMap.get(type);
subTextTv.setText(getSelectedItemsAmount(listItems)); subTextTv.setText(getSelectedItemsAmount(listItems, type));
if (data.containsAll(listItems)) { if (data.containsAll(listItems)) {
checkBox.setState(CHECKED); checkBox.setState(CHECKED);
@ -154,6 +161,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
TextView title = child.findViewById(R.id.title_tv); TextView title = child.findViewById(R.id.title_tv);
TextView subText = child.findViewById(R.id.sub_title_tv); TextView subText = child.findViewById(R.id.sub_title_tv);
subText.setVisibility(View.GONE);
final CheckBox checkBox = child.findViewById(R.id.check_box); final CheckBox checkBox = child.findViewById(R.id.check_box);
ImageView icon = child.findViewById(R.id.icon); ImageView icon = child.findViewById(R.id.icon);
View lineDivider = child.findViewById(R.id.divider); View lineDivider = child.findViewById(R.id.divider);
@ -198,9 +206,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
LOG.error("Error trying to get routing resource for " + routingProfileValue + "\n" + e); LOG.error("Error trying to get routing resource for " + routingProfileValue + "\n" + e);
} }
} }
if (Algorithms.isEmpty(routingProfile)) { if (!Algorithms.isEmpty(routingProfile)) {
subText.setVisibility(View.GONE);
} else {
subText.setText(String.format( subText.setText(String.format(
app.getString(R.string.ltr_or_rtl_combine_via_colon), app.getString(R.string.ltr_or_rtl_combine_via_colon),
app.getString(R.string.nav_type_hint), app.getString(R.string.nav_type_hint),
@ -214,38 +220,32 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
case QUICK_ACTIONS: case QUICK_ACTIONS:
title.setText(((QuickAction) currentItem).getName(app.getApplicationContext())); title.setText(((QuickAction) currentItem).getName(app.getApplicationContext()));
setupIcon(icon, ((QuickAction) currentItem).getIconRes(), itemSelected); setupIcon(icon, ((QuickAction) currentItem).getIconRes(), itemSelected);
subText.setVisibility(View.GONE);
break; break;
case POI_TYPES: case POI_TYPES:
title.setText(((PoiUIFilter) currentItem).getName()); title.setText(((PoiUIFilter) currentItem).getName());
int iconRes = RenderingIcons.getBigIconResourceId(((PoiUIFilter) currentItem).getIconId()); int iconRes = RenderingIcons.getBigIconResourceId(((PoiUIFilter) currentItem).getIconId());
setupIcon(icon, iconRes != 0 ? iconRes : R.drawable.ic_action_user, itemSelected); setupIcon(icon, iconRes != 0 ? iconRes : R.drawable.ic_action_user, itemSelected);
subText.setVisibility(View.GONE);
break; break;
case MAP_SOURCES: case MAP_SOURCES:
title.setText(((ITileSource) currentItem).getName()); title.setText(((ITileSource) currentItem).getName());
setupIcon(icon, R.drawable.ic_map, itemSelected); setupIcon(icon, R.drawable.ic_map, itemSelected);
subText.setVisibility(View.GONE);
break; break;
case CUSTOM_RENDER_STYLE: case CUSTOM_RENDER_STYLE:
String renderName = ((File) currentItem).getName(); String renderName = ((File) currentItem).getName();
renderName = renderName.replace('_', ' ').replaceAll(IndexConstants.RENDERER_INDEX_EXT, ""); renderName = renderName.replace('_', ' ').replaceAll(IndexConstants.RENDERER_INDEX_EXT, "");
title.setText(renderName); title.setText(renderName);
setupIcon(icon, R.drawable.ic_action_map_style, itemSelected); setupIcon(icon, R.drawable.ic_action_map_style, itemSelected);
subText.setVisibility(View.GONE);
break; break;
case CUSTOM_ROUTING: case CUSTOM_ROUTING:
String routingName = ((File) currentItem).getName(); String routingName = ((File) currentItem).getName();
routingName = routingName.replace('_', ' ').replaceAll(".xml", ""); routingName = routingName.replace('_', ' ').replaceAll(".xml", "");
title.setText(routingName); title.setText(routingName);
setupIcon(icon, R.drawable.ic_action_route_distance, itemSelected); setupIcon(icon, R.drawable.ic_action_route_distance, itemSelected);
subText.setVisibility(View.GONE);
break; break;
case AVOID_ROADS: case AVOID_ROADS:
AvoidRoadInfo avoidRoadInfo = (AvoidRoadInfo) currentItem; AvoidRoadInfo avoidRoadInfo = (AvoidRoadInfo) currentItem;
title.setText(avoidRoadInfo.name); title.setText(avoidRoadInfo.name);
setupIcon(icon, R.drawable.ic_action_alert, itemSelected); setupIcon(icon, R.drawable.ic_action_alert, itemSelected);
subText.setVisibility(View.GONE);
break; break;
case MULTIMEDIA_NOTES: case MULTIMEDIA_NOTES:
File file = (File) currentItem; File file = (File) currentItem;
@ -255,19 +255,53 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
iconId = R.drawable.ic_action_photo_dark; iconId = R.drawable.ic_action_photo_dark;
} }
setupIcon(icon, iconId, itemSelected); setupIcon(icon, iconId, itemSelected);
subText.setVisibility(View.GONE);
break; break;
case TRACKS: case TRACKS:
String fileName = ((File) currentItem).getName(); String fileName = ((File) currentItem).getName();
title.setText(GpxUiHelper.getGpxTitle(fileName)); title.setText(GpxUiHelper.getGpxTitle(fileName));
setupIcon(icon, R.drawable.ic_action_route_distance, itemSelected); setupIcon(icon, R.drawable.ic_action_route_distance, itemSelected);
subText.setVisibility(View.GONE);
break; break;
case GLOBAL: case GLOBAL:
String name = ((GlobalSettingsItem) currentItem).getPublicName(app); String name = ((GlobalSettingsItem) currentItem).getPublicName(app);
title.setText(name); title.setText(name);
setupIcon(icon, R.drawable.ic_action_settings, itemSelected); setupIcon(icon, R.drawable.ic_action_settings, itemSelected);
subText.setVisibility(View.GONE); break;
case OSM_NOTES:
title.setText(((OsmNotesPoint) currentItem).getText());
setupIcon(icon, R.drawable.ic_action_osm_note_add, itemSelected);
break;
case OSM_EDITS:
title.setText(OsmEditingPlugin.getTitle((OpenstreetmapPoint) currentItem, app));
setupIcon(icon, R.drawable.ic_action_info_dark, itemSelected);
break;
case OFFLINE_MAPS:
long size;
if (currentItem instanceof FileSettingsItem) {
FileSettingsItem currentFileItem = (FileSettingsItem) currentItem;
file = currentFileItem.getFile();
size = currentFileItem.getSize();
} else {
file = (File) currentItem;
size = file.length();
}
title.setText(FileNameTranslationHelper.getFileName(app,
app.getResourceManager().getOsmandRegions(),
file.getName()));
FileSubtype subtype = FileSubtype.getSubtypeByFileName(file.getPath().replace(
app.getAppPath(null).getPath(), ""));
switch (subtype) {
case SRTM_MAP:
iconId = R.drawable.ic_plugin_srtm;
break;
case WIKI_MAP:
iconId = R.drawable.ic_plugin_wikipedia;
break;
default:
iconId = R.drawable.ic_map;
}
setupIcon(icon, iconId, itemSelected);
subText.setText(AndroidUtils.formatSize(app, size));
subText.setVisibility(View.VISIBLE);
break; break;
default: default:
return child; return child;
@ -315,14 +349,20 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
return true; return true;
} }
private String getSelectedItemsAmount(List<?> listItems) { private String getSelectedItemsAmount(List<?> listItems, ExportSettingsType type) {
int amount = 0; int amount = 0;
long amountSize = 0;
for (Object item : listItems) { for (Object item : listItems) {
if (data.contains(item)) { if (data.contains(item)) {
amount++; amount++;
if (type == OFFLINE_MAPS && item instanceof FileSettingsItem) {
amountSize += ((FileSettingsItem) item).getSize();
} }
} }
return app.getString(R.string.n_items_of_z, String.valueOf(amount), String.valueOf(listItems.size())); }
String itemsOf = app.getString(R.string.n_items_of_z, String.valueOf(amount), String.valueOf(listItems.size()));
return amountSize == 0 ? itemsOf : app.getString(R.string.ltr_or_rtl_combine_via_bold_point, itemsOf,
AndroidUtils.formatSize(app, amountSize));
} }
private int getGroupTitle(ExportSettingsType type) { private int getGroupTitle(ExportSettingsType type) {
@ -347,6 +387,12 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
return R.string.audionotes_plugin_name; return R.string.audionotes_plugin_name;
case GLOBAL: case GLOBAL:
return R.string.general_settings_2; return R.string.general_settings_2;
case OSM_NOTES:
return R.string.osm_notes;
case OSM_EDITS:
return R.string.osm_edit_modified_poi;
case OFFLINE_MAPS:
return R.string.shared_string_local_maps;
default: default:
return R.string.access_empty_list; return R.string.access_empty_list;
} }

View file

@ -1,6 +1,7 @@
package net.osmand.plus.settings.fragments; package net.osmand.plus.settings.fragments;
import android.app.Activity; import android.app.Activity;
import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
@ -31,6 +32,7 @@ import net.osmand.plus.quickaction.QuickActionListFragment;
import net.osmand.plus.routepreparationmenu.AvoidRoadsBottomSheetDialogFragment; import net.osmand.plus.routepreparationmenu.AvoidRoadsBottomSheetDialogFragment;
import net.osmand.plus.search.QuickSearchDialogFragment; import net.osmand.plus.search.QuickSearchDialogFragment;
import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.settings.backend.ExportSettingsType;
import net.osmand.plus.settings.backend.OsmAndAppCustomization;
import net.osmand.plus.settings.backend.backup.SettingsHelper; import net.osmand.plus.settings.backend.backup.SettingsHelper;
import net.osmand.plus.settings.backend.backup.SettingsItem; import net.osmand.plus.settings.backend.backup.SettingsItem;
@ -187,6 +189,14 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
case AVOID_ROADS: case AVOID_ROADS:
new AvoidRoadsBottomSheetDialogFragment().show(fm, AvoidRoadsBottomSheetDialogFragment.TAG); new AvoidRoadsBottomSheetDialogFragment().show(fm, AvoidRoadsBottomSheetDialogFragment.TAG);
break; break;
case OSM_NOTES:
case OSM_EDITS:
OsmAndAppCustomization appCustomization = app.getAppCustomization();
final Intent favorites = new Intent(activity, appCustomization.getFavoritesActivity());
favorites.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
app.getSettings().FAVORITES_TAB.set(R.string.osm_edits);
startActivity(favorites);
break;
default: default:
break; break;
} }

View file

@ -4,6 +4,7 @@ import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
@ -27,6 +28,7 @@ import androidx.fragment.app.FragmentManager;
import com.google.android.material.appbar.CollapsingToolbarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.IProgress;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.map.ITileSource; import net.osmand.map.ITileSource;
import net.osmand.map.TileSourceManager.TileSourceTemplate; import net.osmand.map.TileSourceManager.TileSourceTemplate;
@ -38,10 +40,14 @@ import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OsmNotesPoint;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.quickaction.QuickAction; import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean; import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean;
import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.settings.backend.ExportSettingsType;
import net.osmand.plus.settings.backend.backup.OsmEditsSettingsItem;
import net.osmand.plus.settings.backend.backup.OsmNotesSettingsItem;
import net.osmand.plus.settings.backend.backup.SettingsHelper; import net.osmand.plus.settings.backend.backup.SettingsHelper;
import net.osmand.plus.settings.backend.backup.AvoidRoadsSettingsItem; import net.osmand.plus.settings.backend.backup.AvoidRoadsSettingsItem;
import net.osmand.plus.settings.backend.backup.FileSettingsItem; import net.osmand.plus.settings.backend.backup.FileSettingsItem;
@ -59,12 +65,12 @@ import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import java.io.File; import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class ImportSettingsFragment extends BaseOsmAndFragment public class ImportSettingsFragment extends BaseOsmAndFragment
implements View.OnClickListener { implements View.OnClickListener {
@ -267,6 +273,7 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
if (succeed) { if (succeed) {
app.getRendererRegistry().updateExternalRenderers(); app.getRendererRegistry().updateExternalRenderers();
AppInitializer.loadRoutingFiles(app, null); AppInitializer.loadRoutingFiles(app, null);
reloadIndexes(items);
if (fm != null && file != null) { if (fm != null && file != null) {
ImportCompleteFragment.showInstance(fm, items, file.getName()); ImportCompleteFragment.showInstance(fm, items, file.getName());
} }
@ -275,6 +282,43 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
}; };
} }
private void reloadIndexes(@NonNull List<SettingsItem> items) {
for (SettingsItem item : items) {
if (item instanceof FileSettingsItem && ((FileSettingsItem) item).getSubtype().isMap()) {
Activity activity = getActivity();
if (activity instanceof MapActivity) {
new ReloadIndexesTack((MapActivity) activity).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
break;
}
}
}
private static class ReloadIndexesTack extends AsyncTask<Void, Void, Void> {
private final WeakReference<MapActivity> mapActivityRef;
private final OsmandApplication app;
ReloadIndexesTack(@NonNull MapActivity mapActivity) {
this.mapActivityRef = new WeakReference<>(mapActivity);
this.app = mapActivity.getMyApplication();
}
@Override
protected Void doInBackground(Void[] params) {
app.getResourceManager().reloadIndexes(IProgress.EMPTY_PROGRESS, new ArrayList<String>());
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null) {
mapActivity.refreshMap();
}
}
}
private SettingsHelper.CheckDuplicatesListener getDuplicatesListener() { private SettingsHelper.CheckDuplicatesListener getDuplicatesListener() {
return new SettingsHelper.CheckDuplicatesListener() { return new SettingsHelper.CheckDuplicatesListener() {
@Override @Override
@ -374,6 +418,16 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
return null; return null;
} }
@Nullable
private <T> T getBaseItem(SettingsItemType settingsItemType, Class<T> clazz) {
for (SettingsItem settingsItem : settingsItems) {
if (settingsItem.getType() == settingsItemType && clazz.isInstance(settingsItem)) {
return clazz.cast(settingsItem);
}
}
return null;
}
private List<SettingsItem> getSettingsItemsFromData(List<?> data) { private List<SettingsItem> getSettingsItemsFromData(List<?> data) {
List<SettingsItem> settingsItems = new ArrayList<>(); List<SettingsItem> settingsItems = new ArrayList<>();
List<ApplicationModeBean> appModeBeans = new ArrayList<>(); List<ApplicationModeBean> appModeBeans = new ArrayList<>();
@ -381,6 +435,8 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
List<PoiUIFilter> poiUIFilters = new ArrayList<>(); List<PoiUIFilter> poiUIFilters = new ArrayList<>();
List<ITileSource> tileSourceTemplates = new ArrayList<>(); List<ITileSource> tileSourceTemplates = new ArrayList<>();
List<AvoidRoadInfo> avoidRoads = new ArrayList<>(); List<AvoidRoadInfo> avoidRoads = new ArrayList<>();
List<OsmNotesPoint> osmNotesPointList = new ArrayList<>();
List<OpenstreetmapPoint> osmEditsPointList = new ArrayList<>();
for (Object object : data) { for (Object object : data) {
if (object instanceof ApplicationModeBean) { if (object instanceof ApplicationModeBean) {
appModeBeans.add((ApplicationModeBean) object); appModeBeans.add((ApplicationModeBean) object);
@ -392,8 +448,14 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
tileSourceTemplates.add((ITileSource) object); tileSourceTemplates.add((ITileSource) object);
} else if (object instanceof File) { } else if (object instanceof File) {
settingsItems.add(new FileSettingsItem(app, (File) object)); settingsItems.add(new FileSettingsItem(app, (File) object));
} else if (object instanceof FileSettingsItem) {
settingsItems.add((FileSettingsItem) object);
} else if (object instanceof AvoidRoadInfo) { } else if (object instanceof AvoidRoadInfo) {
avoidRoads.add((AvoidRoadInfo) object); avoidRoads.add((AvoidRoadInfo) object);
} else if (object instanceof OsmNotesPoint) {
osmNotesPointList.add((OsmNotesPoint) object);
} else if (object instanceof OpenstreetmapPoint) {
osmEditsPointList.add((OpenstreetmapPoint) object);
} }
} }
if (!appModeBeans.isEmpty()) { if (!appModeBeans.isEmpty()) {
@ -413,6 +475,14 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
if (!avoidRoads.isEmpty()) { if (!avoidRoads.isEmpty()) {
settingsItems.add(new AvoidRoadsSettingsItem(app, getBaseAvoidRoadsSettingsItem(), avoidRoads)); settingsItems.add(new AvoidRoadsSettingsItem(app, getBaseAvoidRoadsSettingsItem(), avoidRoads));
} }
if (!osmNotesPointList.isEmpty()) {
OsmNotesSettingsItem baseItem = getBaseItem(SettingsItemType.OSM_NOTES, OsmNotesSettingsItem.class);
settingsItems.add(new OsmNotesSettingsItem(app, baseItem, osmNotesPointList));
}
if (!osmEditsPointList.isEmpty()) {
OsmEditsSettingsItem baseItem = getBaseItem(SettingsItemType.OSM_EDITS, OsmEditsSettingsItem.class);
settingsItems.add(new OsmEditsSettingsItem(app, baseItem, osmEditsPointList));
}
return settingsItems; return settingsItems;
} }

View file

@ -114,6 +114,14 @@ public class ImportedSettingsItemsAdapter extends
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_route_distance, activeColorRes)); holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_route_distance, activeColorRes));
holder.title.setText(R.string.shared_string_tracks); holder.title.setText(R.string.shared_string_tracks);
break; break;
case OSM_NOTES:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_osm_note_add, activeColorRes));
holder.title.setText(R.string.osm_notes);
break;
case OSM_EDITS:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_info_dark, activeColorRes));
holder.title.setText(R.string.osm_edit_modified_poi);
break;
} }
} }

View file

@ -68,7 +68,6 @@ public class TerrainLayer extends MapTileLayer {
} else { } else {
// ignore // ignore
} }
} }
private void indexTerrainFiles(final OsmandApplication app) { private void indexTerrainFiles(final OsmandApplication app) {
@ -77,7 +76,6 @@ public class TerrainLayer extends MapTileLayer {
private String type = mode.name().toLowerCase(); private String type = mode.name().toLowerCase();
@Override @Override
protected Void doInBackground(Void... params) { protected Void doInBackground(Void... params) {
File tilesDir = app.getAppPath(IndexConstants.TILES_INDEX_DIR); File tilesDir = app.getAppPath(IndexConstants.TILES_INDEX_DIR);
File cacheDir = app.getCacheDir(); File cacheDir = app.getCacheDir();
// fix http://stackoverflow.com/questions/26937152/workaround-for-nexus-9-sqlite-file-write-operations-on-external-dirs // fix http://stackoverflow.com/questions/26937152/workaround-for-nexus-9-sqlite-file-write-operations-on-external-dirs
@ -91,6 +89,7 @@ public class TerrainLayer extends MapTileLayer {
sqliteDb = null; sqliteDb = null;
} }
if (sqliteDb != null) { if (sqliteDb != null) {
try {
if (sqliteDb.getVersion() == 0) { if (sqliteDb.getVersion() == 0) {
sqliteDb.setVersion(1); sqliteDb.setVersion(1);
} }
@ -102,6 +101,9 @@ public class TerrainLayer extends MapTileLayer {
indexNonCachedResources(fileModified, rs); indexNonCachedResources(fileModified, rs);
sqliteDb.close(); sqliteDb.close();
resources = rs; resources = rs;
} catch (RuntimeException e) {
log.error(e.getMessage(), e);
}
} }
return null; return null;
} }
@ -150,7 +152,6 @@ public class TerrainLayer extends MapTileLayer {
indexedResources.insert(filename, new QuadRect(left, top, right, bottom)); indexedResources.insert(filename, new QuadRect(left, top, right, bottom));
fileModified.remove(filename); fileModified.remove(filename);
} }
} while(cursor.moveToNext()); } while(cursor.moveToNext());
} }
cursor.close(); cursor.close();
@ -172,7 +173,6 @@ public class TerrainLayer extends MapTileLayer {
} }
return rs; return rs;
} }
}; };
executeTaskInBackground(task); executeTaskInBackground(task);
} }