Merge pull request #10832 from osmandapp/master

update test branch
This commit is contained in:
Hardy 2021-02-10 22:41:28 +01:00 committed by GitHub
commit 76c65130fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 990 additions and 947 deletions

View file

@ -4,7 +4,7 @@
<application <application
android:icon="@mipmap/icon_free" android:icon="@mipmap/icon_free"
android:label="@string/app_name_free" android:label="@string/app_name"
tools:replace="android:icon, android:label"> tools:replace="android:icon, android:label">
<meta-data <meta-data

View file

@ -24,6 +24,7 @@ android {
// Build that doesn't include 3D OpenGL // Build that doesn't include 3D OpenGL
legacy { legacy {
dimension "coreversion" dimension "coreversion"
resValue "string", "app_edition", ""
} }
} }
} }

View file

@ -37,6 +37,7 @@
android:layout_marginRight="@dimen/dialog_content_margin" android:layout_marginRight="@dimen/dialog_content_margin"
android:layout_marginEnd="@dimen/dialog_content_margin" android:layout_marginEnd="@dimen/dialog_content_margin"
android:clickable="false" android:clickable="false"
android:scrollbars="none"
android:focusableInTouchMode="false" /> android:focusableInTouchMode="false" />
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView

View file

@ -1,198 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/text_margin_small"
android:layout_marginRight="@dimen/text_margin_small"
android:background="?attr/wikivoyage_travel_card_bg"
android:orientation="vertical"
android:layout_marginEnd="@dimen/text_margin_small"
android:layout_marginStart="@dimen/text_margin_small">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/bottom_sheet_content_padding_small">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginTop="4dp"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?attr/wikivoyage_primary_text_color"
android:textSize="@dimen/travel_card_primary_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:text="Download file"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="ContentDescription"
tools:src="@drawable/travel_card_download_icon"/>
</LinearLayout>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingMultiplier="@dimen/text_button_line_spacing_multiplier"
android:textColor="@color/wikivoyage_secondary_text"
android:textSize="@dimen/travel_card_primary_text_size"
osmand:typeface="@string/font_roboto_regular"
tools:text="Download this Wikivoyage travel guides file to view articles about places around the world without an internet connection."/>
</LinearLayout>
<LinearLayout
android:id="@+id/file_data_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_padding"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin_small"
android:layout_marginRight="@dimen/bottom_sheet_content_margin_small"
android:background="?attr/wikivoyage_travel_card_stroke_bg"
android:minHeight="@dimen/bottom_sheet_selected_item_title_height"
android:paddingLeft="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:layout_marginStart="@dimen/bottom_sheet_content_margin_small"
android:paddingEnd="@dimen/content_padding"
android:paddingStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin_small">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/file_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_action_read_article"
tools:tint="?attr/wikivoyage_active_color"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:orientation="vertical">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/file_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?attr/wikivoyage_primary_text_color"
android:textSize="@dimen/default_list_text_size"
osmand:typeface="@string/font_roboto_regular"
tools:text="Wikivoyage"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/file_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/wikivoyage_secondary_text"
android:textSize="@dimen/default_sub_text_size"
osmand:typeface="@string/font_roboto_regular"
tools:text="255 Mb • Update 11 April"/>
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:minHeight="0dp"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/bottom_sheet_content_margin_small"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin_small"
android:layout_marginRight="@dimen/bottom_sheet_content_margin_small"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin_small"
android:layout_marginStart="@dimen/bottom_sheet_content_margin_small">
<FrameLayout
android:id="@+id/secondary_btn_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?attr/wikivoyage_secondary_btn_bg">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/secondary_button"
android:layout_width="match_parent"
android:layout_height="@dimen/wikivoyage_card_button_height"
android:layout_gravity="center"
android:background="?attr/selectableItemBackgroundBorderless"
android:ellipsize="end"
android:gravity="center"
android:letterSpacing="@dimen/text_button_letter_spacing"
android:maxLines="1"
android:textColor="?attr/wikivoyage_active_color"
android:textSize="@dimen/text_button_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:ignore="UnusedAttribute"
tools:text="Later"/>
</FrameLayout>
<View
android:id="@+id/buttons_divider"
android:layout_width="@dimen/bottom_sheet_content_margin_small"
android:layout_height="match_parent"/>
<FrameLayout
android:id="@+id/primary_btn_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?attr/wikivoyage_primary_btn_bg">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/primary_button"
android:layout_width="match_parent"
android:layout_height="@dimen/wikivoyage_card_button_height"
android:layout_gravity="center"
android:background="?attr/selectableItemBackgroundBorderless"
android:ellipsize="end"
android:gravity="center"
android:letterSpacing="@dimen/text_button_letter_spacing"
android:maxLines="1"
android:textColor="?attr/wikivoyage_primary_btn_text_color"
android:textSize="@dimen/text_button_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:ignore="UnusedAttribute"
tools:text="Update"/>
</FrameLayout>
</LinearLayout>
</LinearLayout>

View file

@ -18,16 +18,34 @@
android:layout_margin="@dimen/content_padding" android:layout_margin="@dimen/content_padding"
android:orientation="vertical"> android:orientation="vertical">
<net.osmand.plus.widgets.TextViewEx <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_padding" android:layout_marginBottom="@dimen/bottom_sheet_content_padding_small">
android:ellipsize="end"
android:maxLines="1" <net.osmand.plus.widgets.TextViewEx
android:text="@string/maps_you_need" android:id="@+id/title"
android:textColor="?attr/wikivoyage_primary_text_color" android:layout_width="0dp"
android:textSize="@dimen/travel_card_primary_text_size" android:layout_height="wrap_content"
osmand:typeface="@string/font_roboto_medium"/> android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginTop="4dp"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?attr/wikivoyage_primary_text_color"
android:textSize="@dimen/travel_card_primary_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:text="Download file" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="ContentDescription"
tools:src="@drawable/travel_card_download_icon" />
</LinearLayout>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/description" android:id="@+id/description"

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/content_padding"
android:background="?attr/wikivoyage_card_bg_color"
android:gravity="center_vertical">
<include
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="@dimen/dialog_button_height"
layout="@layout/bottom_sheet_dialog_button" />
</LinearLayout>
<include
android:id="@+id/shadow"
layout="@layout/card_bottom_divider"
android:visibility="visible" />
</LinearLayout>

View file

@ -103,6 +103,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLines="2" android:maxLines="2"
android:scrollbars="none"
android:textColor="@color/wikivoyage_secondary_text" android:textColor="@color/wikivoyage_secondary_text"
android:textSize="@dimen/default_sub_text_size" android:textSize="@dimen/default_sub_text_size"
osmand:typeface="@string/font_roboto_regular" osmand:typeface="@string/font_roboto_regular"

View file

@ -329,7 +329,7 @@
<string name="local_osm_changes_backup">نسخ الاحتياطي كتعديل OSM</string> <string name="local_osm_changes_backup">نسخ الاحتياطي كتعديل OSM</string>
<string name="files_limit">%1$d ملف بقى</string> <string name="files_limit">%1$d ملف بقى</string>
<string name="osmand_background_plugin_description">يظهر الإعدادات لتمكين التتبع والملاحة في وضعية السكون ( الشاشة مغلقة ) عبر إيقاظ دوري لجهاز GPS.</string> <string name="osmand_background_plugin_description">يظهر الإعدادات لتمكين التتبع والملاحة في وضعية السكون ( الشاشة مغلقة ) عبر إيقاظ دوري لجهاز GPS.</string>
<string name="precise_routing_mode_descr">حساب الطرق بدقة دون أخطاء. لا يزال محدود المسافة وبطيء.</string> <string name="precise_routing_mode_descr">تمكين لحساب المسارات بدقة دون أخطاء. لا يزال محدود المسافة وبطيء.</string>
<string name="recording_photo_description">صورة %1$s %2$s</string> <string name="recording_photo_description">صورة %1$s %2$s</string>
<string name="dropbox_plugin_description">مزامنة المسارات والملاحظات الصوتية / الفيديو مع حساب Dropbox الخاص بك.</string> <string name="dropbox_plugin_description">مزامنة المسارات والملاحظات الصوتية / الفيديو مع حساب Dropbox الخاص بك.</string>
<string name="av_video_format_descr">تنسيق الفيديو الناتج:</string> <string name="av_video_format_descr">تنسيق الفيديو الناتج:</string>
@ -359,7 +359,7 @@
<string name="osmand_short_description_80_chars">برنامج عرض الخرائط العالمية والملاحة باستخدام خرائط الشوارع المفتوحة OSM أثناء الاتصال بالإنترنت أو من دونه</string> <string name="osmand_short_description_80_chars">برنامج عرض الخرائط العالمية والملاحة باستخدام خرائط الشوارع المفتوحة OSM أثناء الاتصال بالإنترنت أو من دونه</string>
<string name="osmand_plus_play_title_30_chars">أوسماند+ للخرائط و الملاحة</string> <string name="osmand_plus_play_title_30_chars">أوسماند+ للخرائط و الملاحة</string>
<string name="osmand_plus_short_description_80_chars">برنامج عرض الخرائط العالمية والملاحة باستخدام خرائط الشوارع المفتوحة OSM أثناء الاتصال بالإنترنت أو من دونه</string> <string name="osmand_plus_short_description_80_chars">برنامج عرض الخرائط العالمية والملاحة باستخدام خرائط الشوارع المفتوحة OSM أثناء الاتصال بالإنترنت أو من دونه</string>
<string name="filterpoi_activity">أنشئ مُرشِّح نقاط مهمة</string> <string name="filterpoi_activity">إنشاء فلتر نقاط الاهتمام</string>
<string name="recalculate_route_to_your_location">نمط المواصلات:</string> <string name="recalculate_route_to_your_location">نمط المواصلات:</string>
<string name="select_navigation_mode">وسائل النقل:</string> <string name="select_navigation_mode">وسائل النقل:</string>
<string name="day_night_info_description">الشروق: %1$s <string name="day_night_info_description">الشروق: %1$s
@ -471,7 +471,7 @@
<string name="index_name_africa">إفريقيا</string> <string name="index_name_africa">إفريقيا</string>
<string name="index_name_asia">آسيا</string> <string name="index_name_asia">آسيا</string>
<string name="index_name_oceania">أستراليا و أوقيانوسيا</string> <string name="index_name_oceania">أستراليا و أوقيانوسيا</string>
<string name="routing_settings">التوجيه</string> <string name="routing_settings">التوجيه مع الطرق</string>
<string name="routing_settings_descr">ضبط خاص لكل وضع من أوضاع الملاحة.</string> <string name="routing_settings_descr">ضبط خاص لكل وضع من أوضاع الملاحة.</string>
<string name="index_settings">إدارة بيانات الخرائط</string> <string name="index_settings">إدارة بيانات الخرائط</string>
<string name="general_settings">إعدادات عامة</string> <string name="general_settings">إعدادات عامة</string>
@ -977,7 +977,7 @@
<string name="map_source">مصدر الخريطة</string> <string name="map_source">مصدر الخريطة</string>
<string name="layer_amenity_label">عرض أسماء المفضلة</string> <string name="layer_amenity_label">عرض أسماء المفضلة</string>
<string name="map_locale">لغة الخريطة</string> <string name="map_locale">لغة الخريطة</string>
<string name="rendering_category_details">التفاصيل</string> <string name="rendering_category_details">تفاصيل إضافية</string>
<string name="map_widget_plain_time">الوقت الحالي</string> <string name="map_widget_plain_time">الوقت الحالي</string>
<string name="rotate_map_to_bearing">اتجاه الخريطة</string> <string name="rotate_map_to_bearing">اتجاه الخريطة</string>
<string name="rotate_map_bearing_opt">اتجاه الحركة في الأعلى</string> <string name="rotate_map_bearing_opt">اتجاه الحركة في الأعلى</string>
@ -992,7 +992,7 @@
<string name="record_plugin_name">تسجيل المسار</string> <string name="record_plugin_name">تسجيل المسار</string>
<string name="save_track_interval_descr">اختر الفاصل الزمني لتسجيل المسار أثناء الملاحة</string> <string name="save_track_interval_descr">اختر الفاصل الزمني لتسجيل المسار أثناء الملاحة</string>
<string name="voice">صوت مسج</string> <string name="voice">صوت مسج</string>
<string name="get_directions">الاتجاهات</string> <string name="get_directions">التوجيه مع الطرق</string>
<string name="show_point_options">استخدام الموقع…</string> <string name="show_point_options">استخدام الموقع…</string>
<string name="favorite">مفضلة</string> <string name="favorite">مفضلة</string>
<string name="speak_favorites">نقاط مفضلة مجاورة</string> <string name="speak_favorites">نقاط مفضلة مجاورة</string>
@ -1071,7 +1071,7 @@
<string name="impassable_road">تجنب الطرق…</string> <string name="impassable_road">تجنب الطرق…</string>
<string name="rendering_attr_trainLightrailRoutes_name">طرق السكك الحديدية</string> <string name="rendering_attr_trainLightrailRoutes_name">طرق السكك الحديدية</string>
<string name="rendering_attr_tramRoutes_name">خطوط الترام</string> <string name="rendering_attr_tramRoutes_name">خطوط الترام</string>
<string name="rendering_category_routes">الطرق</string> <string name="rendering_category_routes">المسارات الرياضية</string>
<string name="rendering_category_transport">وسائل المواصلات</string> <string name="rendering_category_transport">وسائل المواصلات</string>
<string name="rendering_category_others">سمات أخرى للخريطة</string> <string name="rendering_category_others">سمات أخرى للخريطة</string>
<string name="map_widget_appearance_rem">العناصر الأخرى</string> <string name="map_widget_appearance_rem">العناصر الأخرى</string>
@ -1170,7 +1170,7 @@
<string name="rendering_attr_trolleybusRoutes_name">طرق الحافلات الكهربائية</string> <string name="rendering_attr_trolleybusRoutes_name">طرق الحافلات الكهربائية</string>
<string name="rendering_attr_busRoutes_name">طرق الحافلات</string> <string name="rendering_attr_busRoutes_name">طرق الحافلات</string>
<string name="rendering_attr_subwayMode_name">سكك قطار الأنفاق</string> <string name="rendering_attr_subwayMode_name">سكك قطار الأنفاق</string>
<string name="rendering_attr_shareTaxiRoutes_name">تاكسي مشاركة الطرق</string> <string name="rendering_attr_shareTaxiRoutes_name">شارك طرق التاكسي</string>
<string name="speed_limit_exceed_message">حدد حد السرعة المسموح به لتلقي تنبيه صوتي إذا ما تجاوزته.</string> <string name="speed_limit_exceed_message">حدد حد السرعة المسموح به لتلقي تنبيه صوتي إذا ما تجاوزته.</string>
<string name="traffic_warning_border_control">مراقبة الحدود</string> <string name="traffic_warning_border_control">مراقبة الحدود</string>
<string name="traffic_warning_payment">كشك الرسوم</string> <string name="traffic_warning_payment">كشك الرسوم</string>
@ -1184,7 +1184,7 @@
<string name="rendering_attr_hideAccess_name">قيود الدخول</string> <string name="rendering_attr_hideAccess_name">قيود الدخول</string>
<string name="rendering_attr_showAccess_name">عرض قيود الدخول</string> <string name="rendering_attr_showAccess_name">عرض قيود الدخول</string>
<string name="rendering_attr_showSurfaces_name">عرض سطح الطريق</string> <string name="rendering_attr_showSurfaces_name">عرض سطح الطريق</string>
<string name="rendering_attr_showCycleRoutes_name">إظهار طرق الدراجات</string> <string name="rendering_attr_showCycleRoutes_name">إظهار مسارات الدراجات</string>
<string name="delay_navigation_start">بدء التوجيه المفصل تلقائياً</string> <string name="delay_navigation_start">بدء التوجيه المفصل تلقائياً</string>
<string name="gpx_info_subtracks">مسارات فرعية: %1$s</string> <string name="gpx_info_subtracks">مسارات فرعية: %1$s</string>
<string name="gpx_info_waypoints">نقاط الطريق: %1$s</string> <string name="gpx_info_waypoints">نقاط الطريق: %1$s</string>
@ -1390,7 +1390,7 @@
<string name="app_mode_train">قطار</string> <string name="app_mode_train">قطار</string>
<string name="current_track">المسار الحالي</string> <string name="current_track">المسار الحالي</string>
<string name="map_widget_battery">مستوى البطارية</string> <string name="map_widget_battery">مستوى البطارية</string>
<string name="change_markers_position">تغيير موقع العلامة</string> <string name="change_markers_position">تغيير موقع التوجيه المباشر</string>
<string name="follow_us">تابعنا</string> <string name="follow_us">تابعنا</string>
<string name="access_direction_audio_feedback">اتجاه صدى الصوت</string> <string name="access_direction_audio_feedback">اتجاه صدى الصوت</string>
<string name="use_osm_live_routing">الملاحة عبر أوسماند لايف</string> <string name="use_osm_live_routing">الملاحة عبر أوسماند لايف</string>
@ -1411,7 +1411,7 @@
<string name="map_mode">مظهرالخريطة</string> <string name="map_mode">مظهرالخريطة</string>
<string name="rendering_value_thin_name">رقيقة</string> <string name="rendering_value_thin_name">رقيقة</string>
<string name="rendering_value_medium_name">متوسط</string> <string name="rendering_value_medium_name">متوسط</string>
<string name="no_map_markers_found">أضف علامات عبر الخريطة</string> <string name="no_map_markers_found">لم تضف توجيه مباشر على الخريطة</string>
<string name="no_waypoints_found">لم يتم العثور على نقاط الطريق</string> <string name="no_waypoints_found">لم يتم العثور على نقاط الطريق</string>
<string name="report">التقرير</string> <string name="report">التقرير</string>
<string name="storage_permission_restart_is_required">سمح الآن للتطبيق بالكتابة على وحدة التخزين الخارجية. الرجاء إعادة تشغيله يدويا.</string> <string name="storage_permission_restart_is_required">سمح الآن للتطبيق بالكتابة على وحدة التخزين الخارجية. الرجاء إعادة تشغيله يدويا.</string>
@ -1436,7 +1436,7 @@
<string name="upload_anonymously">رفع كمستخدم مجهول</string> <string name="upload_anonymously">رفع كمستخدم مجهول</string>
<string name="upload_osm_note">رفع ملاحظة OSM</string> <string name="upload_osm_note">رفع ملاحظة OSM</string>
<string name="shared_string_toolbar">شريط الأدوات</string> <string name="shared_string_toolbar">شريط الأدوات</string>
<string name="select_map_markers">حدد علامات الخريطة</string> <string name="select_map_markers">حدد توجيه مباشرعلى الخريطة</string>
<string name="shared_string_reverse_order">ترتيب عكسي</string> <string name="shared_string_reverse_order">ترتيب عكسي</string>
<string name="show_map_markers_description">تفعيل ميزة العلامات.</string> <string name="show_map_markers_description">تفعيل ميزة العلامات.</string>
<string name="lang_ast">الأسترية</string> <string name="lang_ast">الأسترية</string>
@ -1472,7 +1472,7 @@
<string name="file_name_containes_illegal_char">حرف غير قانوني في اسم الملف</string> <string name="file_name_containes_illegal_char">حرف غير قانوني في اسم الملف</string>
<string name="reports_for">تقرير عن</string> <string name="reports_for">تقرير عن</string>
<string name="world_maps">خرائط العالم</string> <string name="world_maps">خرائط العالم</string>
<string name="move_marker_bottom_sheet_title">حرك الخريطة لتغيير مكان العلامة</string> <string name="move_marker_bottom_sheet_title">حرك الخريطة لتغيير مكان التوجيه المباشر</string>
<!-- string name="lat_lon_pattern">خط العرض: %1$.5f خط الطول: %2$.5f</string --> <!-- string name="lat_lon_pattern">خط العرض: %1$.5f خط الطول: %2$.5f</string -->
<string name="access_direction_audio_feedback_descr">إشارة صوتية عند اتجاه نقطة الوصول.</string> <string name="access_direction_audio_feedback_descr">إشارة صوتية عند اتجاه نقطة الوصول.</string>
<string name="access_direction_haptic_feedback_descr">حدد اتجاه النقطة المستهدفة بالاهتزاز.</string> <string name="access_direction_haptic_feedback_descr">حدد اتجاه النقطة المستهدفة بالاهتزاز.</string>
@ -1590,7 +1590,7 @@
<string name="shared_string_move_down">حرك للاسفل</string> <string name="shared_string_move_down">حرك للاسفل</string>
<string name="open_street_map_login_and_pass">اسم مستخدم و كلمة سر OSM</string> <string name="open_street_map_login_and_pass">اسم مستخدم و كلمة سر OSM</string>
<string name="osm_live_email_desc">نحن بحاجة اليه لكي نوفر لك معلومات حول المساهمات.</string> <string name="osm_live_email_desc">نحن بحاجة اليه لكي نوفر لك معلومات حول المساهمات.</string>
<string name="select_map_marker">اختر علامة</string> <string name="select_map_marker">حدد توجيه مباشر</string>
<string name="show_transparency_seekbar">عرض شريط الشفافية</string> <string name="show_transparency_seekbar">عرض شريط الشفافية</string>
<string name="download_files_error_not_enough_space">لا توجد مساحة كافية! <string name="download_files_error_not_enough_space">لا توجد مساحة كافية!
\n {3} MB مطلوب مؤقتا ، {1} ميجا بايت بشكل دائم. \n {3} MB مطلوب مؤقتا ، {1} ميجا بايت بشكل دائم.
@ -1611,7 +1611,7 @@
\nللعودة إلى واحدة من أنماط الخريطة التقليدية، ببساطة إما عطل هذا الملحق مرة أخرى أو غير \'نمط الخريطة\' في \'ضبط الخريطة\' حسب الرغبة.</string> \nللعودة إلى واحدة من أنماط الخريطة التقليدية، ببساطة إما عطل هذا الملحق مرة أخرى أو غير \'نمط الخريطة\' في \'ضبط الخريطة\' حسب الرغبة.</string>
<string name="search_near_map">البحث قرب مركز الخريطة الحالية</string> <string name="search_near_map">البحث قرب مركز الخريطة الحالية</string>
<string name="active_markers">عدد خطوط التوجيه</string> <string name="active_markers">عدد خطوط التوجيه</string>
<string name="map_markers">علامات الخريطة</string> <string name="map_markers">التوجيه المباشر</string>
<string name="routing_attr_avoid_borders_name">تخطي الحدود</string> <string name="routing_attr_avoid_borders_name">تخطي الحدود</string>
<string name="impassable_road_desc">حدد الطرق التي تريد تجنبها أثناء التنقل.</string> <string name="impassable_road_desc">حدد الطرق التي تريد تجنبها أثناء التنقل.</string>
<string name="search_categories">الفئات</string> <string name="search_categories">الفئات</string>
@ -1629,11 +1629,11 @@
<string name="available_maps">الخرائط الموجودة</string> <string name="available_maps">الخرائط الموجودة</string>
<string name="access_shared_string_navigate_up">انتقال للأعلى</string> <string name="access_shared_string_navigate_up">انتقال للأعلى</string>
<string name="osm_user_stat">التعديلات %1$s ، الرتبة %2$s ، مجموع التعديلات %3$s</string> <string name="osm_user_stat">التعديلات %1$s ، الرتبة %2$s ، مجموع التعديلات %3$s</string>
<string name="map_marker_1st">أول علامة</string> <string name="map_marker_1st">التوجيه المباشرالأول للخريطة</string>
<string name="map_marker_2nd">ثاني علامة</string> <string name="map_marker_2nd">التوجيه المباشرالثاني للخريطة</string>
<string name="shared_string_add_to_map_markers">إضافة إلى علامات الخريطة</string> <string name="shared_string_add_to_map_markers">إضافة إلى التوجيه المباشر</string>
<string name="clear_active_markers_q">حذف كافة العلامات النشطة على الخريطة؟</string> <string name="clear_active_markers_q">حذف كافة التوجيه المباشرالنشط على الخريطة؟</string>
<string name="map_marker">علامة خريطة</string> <string name="map_marker">توجيه مباشر على الخريطة</string>
<string name="show_polygons">عرض المضلعات</string> <string name="show_polygons">عرض المضلعات</string>
<string name="shared_string_status">الحالة</string> <string name="shared_string_status">الحالة</string>
<string name="shared_string_save_changes">حفظ التعديلات</string> <string name="shared_string_save_changes">حفظ التعديلات</string>
@ -1655,7 +1655,7 @@
<string name="select_voice_provider">اختر التوجيه الصوتي</string> <string name="select_voice_provider">اختر التوجيه الصوتي</string>
<string name="select_voice_provider_descr">اختر أو قم بتحميل التوجيه الصوتي الخاص بلغتك.</string> <string name="select_voice_provider_descr">اختر أو قم بتحميل التوجيه الصوتي الخاص بلغتك.</string>
<string name="no_location_permission">منح الوصول إلى بيانات الموقع.</string> <string name="no_location_permission">منح الوصول إلى بيانات الموقع.</string>
<string name="rendering_attr_horseRoutes_name">طرق الخيول</string> <string name="rendering_attr_horseRoutes_name">مسارات الخيول</string>
<string name="shared_string_hide">إخفاء</string> <string name="shared_string_hide">إخفاء</string>
<string name="av_video_quality_low">جودة أقل</string> <string name="av_video_quality_low">جودة أقل</string>
<string name="av_video_quality_high">أعلى جودة</string> <string name="av_video_quality_high">أعلى جودة</string>
@ -1749,7 +1749,7 @@
<string name="update_poi_error_local">خطأ تحيين القائمة المحلية لPOI.</string> <string name="update_poi_error_local">خطأ تحيين القائمة المحلية لPOI.</string>
<string name="context_menu_item_update_poi">تحيين الPOI</string> <string name="context_menu_item_update_poi">تحيين الPOI</string>
<string name="upload_osm_note_description">قم بتحميل مذكرة OSM الخاصة بك دون الكشف عن هويتك أو باستخدام ملف تعريف OpenStreetMap.org .</string> <string name="upload_osm_note_description">قم بتحميل مذكرة OSM الخاصة بك دون الكشف عن هويتك أو باستخدام ملف تعريف OpenStreetMap.org .</string>
<string name="add_points_to_map_markers_q">إضافة جميع النقاط إلى علامات الخريطة؟</string> <string name="add_points_to_map_markers_q">إضافة جميع النقاط إلى التوجيه المباشر؟</string>
<string name="clear_markers_history_q">مسح السجلات ؟</string> <string name="clear_markers_history_q">مسح السجلات ؟</string>
<string name="rendering_attr_showMtbRoutes_name">إظهار مسارات الدراجة الجبلية</string> <string name="rendering_attr_showMtbRoutes_name">إظهار مسارات الدراجة الجبلية</string>
<string name="clear_updates_proposition_message">يمكنك إزالة التحديثات المحملة والرجوع إلى الإصدار الأصلي للخريطة</string> <string name="clear_updates_proposition_message">يمكنك إزالة التحديثات المحملة والرجوع إلى الإصدار الأصلي للخريطة</string>
@ -1868,7 +1868,7 @@
<string name="rendering_value_walkingRoutesScopeOSMC_name">تلوين وفق الانتماء للشبكة</string> <string name="rendering_value_walkingRoutesScopeOSMC_name">تلوين وفق الانتماء للشبكة</string>
<string name="rendering_value_walkingRoutesOSMC_name">تلوين وفق رمز تنزه OSMC</string> <string name="rendering_value_walkingRoutesOSMC_name">تلوين وفق رمز تنزه OSMC</string>
<string name="shared_string_logoff">خروج</string> <string name="shared_string_logoff">خروج</string>
<string name="local_recordings_delete_all_confirm">حذف الملاحظات %1$d؟</string> <string name="local_recordings_delete_all_confirm">هل أنت متأكد من أنك تريد حذف الملاحظات %1$d؟</string>
<string name="nautical_maps_missing">لعرض الخرائط البحرية، يجب تحميل خريطة خاصة محلياً.</string> <string name="nautical_maps_missing">لعرض الخرائط البحرية، يجب تحميل خريطة خاصة محلياً.</string>
<string name="save_track_to_gpx_globally_descr">تسجيل الموقع العام إلى ملف GPX يمكن تشغيله أو إيقافه باستخدام نافذة تسجيل GPX على الشاشة خريطة.</string> <string name="save_track_to_gpx_globally_descr">تسجيل الموقع العام إلى ملف GPX يمكن تشغيله أو إيقافه باستخدام نافذة تسجيل GPX على الشاشة خريطة.</string>
<string name="proxy_host_descr">ضبط اسم مضيف البروكسي (مثال 127.0.0.1).</string> <string name="proxy_host_descr">ضبط اسم مضيف البروكسي (مثال 127.0.0.1).</string>
@ -1962,8 +1962,7 @@
\nليست هناك حاجة لتحميل خريطة خاصة،الرؤية يتم إنشاؤها من خلال خرائطنا المحلية. \nليست هناك حاجة لتحميل خريطة خاصة،الرؤية يتم إنشاؤها من خلال خرائطنا المحلية.
\n \n
\nهذه الرؤية يمكن التراجع عنها إما عن طريق تعطيلها هنا، أو تغيير \'نمط الخريطة\' في \'ضبط الخريطة\' حسب الرغبة.</string> \nهذه الرؤية يمكن التراجع عنها إما عن طريق تعطيلها هنا، أو تغيير \'نمط الخريطة\' في \'ضبط الخريطة\' حسب الرغبة.</string>
<string name="create_poi_link_to_osm_doc"> <string name="create_poi_link_to_osm_doc"><u>Online OSM</u> تصنيف الخريطة مع الصور.</string>
<u>Online OSM</u> تصنيف الخريطة مع الصور.</string>
<string name="background_service_wait_int_descr">تعيين الحد الأقصى لوقت الانتظار لكل إصلاح موقع في الخلفية.</string> <string name="background_service_wait_int_descr">تعيين الحد الأقصى لوقت الانتظار لكل إصلاح موقع في الخلفية.</string>
<string name="background_service_wait_int">الانتظار الأقصى للإصلاح</string> <string name="background_service_wait_int">الانتظار الأقصى للإصلاح</string>
<string name="voice_data_not_supported">إصدار غير معتمد من البيانات الصوتية</string> <string name="voice_data_not_supported">إصدار غير معتمد من البيانات الصوتية</string>
@ -2072,7 +2071,7 @@
<string name="rendering_value_fine_name">اللون والسمك</string> <string name="rendering_value_fine_name">اللون والسمك</string>
<string name="route_roundabout_short">خذ المخرج %1$d ثم واصل</string> <string name="route_roundabout_short">خذ المخرج %1$d ثم واصل</string>
<string name="search_map_hint">المدينة أو المنطقة</string> <string name="search_map_hint">المدينة أو المنطقة</string>
<string name="wiki_around">مقالات ويكيبيديا قريبة</string> <string name="wiki_around">مقالات ويكيبيديا القريبة</string>
<string name="routing_attr_allow_motorway_name">استخدام الطرق السريعة</string> <string name="routing_attr_allow_motorway_name">استخدام الطرق السريعة</string>
<string name="routing_attr_allow_motorway_description">السماح للطرق السريعة.</string> <string name="routing_attr_allow_motorway_description">السماح للطرق السريعة.</string>
<string name="lang_sr_latn">الصربية (اللاتينية)</string> <string name="lang_sr_latn">الصربية (اللاتينية)</string>
@ -2089,7 +2088,7 @@
<string name="configure_screen_quick_action">إجراءات سريعة</string> <string name="configure_screen_quick_action">إجراءات سريعة</string>
<string name="quick_action_item_action">إجراء %d</string> <string name="quick_action_item_action">إجراء %d</string>
<string name="quick_action_item_screen">شاشة %d</string> <string name="quick_action_item_screen">شاشة %d</string>
<string name="quick_action_add_marker">إضافة علامة خريطة</string> <string name="quick_action_add_marker">إضافة توجيه مباشر للخريطة</string>
<string name="quick_action_add_poi">إضافة POI</string> <string name="quick_action_add_poi">إضافة POI</string>
<string name="quick_action_map_style">نمط الخريطة</string> <string name="quick_action_map_style">نمط الخريطة</string>
<string name="quick_action_map_style_switch">نمط الخرائط تغير ل \"%s\".</string> <string name="quick_action_map_style_switch">نمط الخرائط تغير ل \"%s\".</string>
@ -2219,18 +2218,19 @@
<string name="select_gpx_folder">حدد مجلد المسار</string> <string name="select_gpx_folder">حدد مجلد المسار</string>
<string name="shared_string_gpx_tracks">المسارات</string> <string name="shared_string_gpx_tracks">المسارات</string>
<string name="shared_string_time">الوقت</string> <string name="shared_string_time">الوقت</string>
<string name="osmand_plus_extended_description_part8">التغطية التقريبية للخريطة و جودتها : <string name="osmand_plus_extended_description_part8">التغطية التقريبية للخريطة و جودتها:
\n• أوروبا الغربية : **** \n • أوروبا الغربية: ****
\n• أوروبا الشرقية : *** \n • أوروبا الشرقية: ***
\n• روسيا : *** \n • روسيا: ***
\n• أمريكا الشمالية : *** \n • أمريكا الشمالية: ***
\n• امريكا الجنوبية : ** \n • امريكا الجنوبية: **
\n• آسيا : ** \n • آسيا: **
\n• اليابان وكوريا : *** \n • اليابان وكوريا: ***
\n• الشرق الأوسط : ** \n • الشرق الأوسط : **
\n• إفريقيا : ** \n • إفريقيا: **
\n• أنتاركتيكا : * \n • أنتاركتيكا: *
\n معظم البلدان في جميع أنحاء العالم متاحة للتنزيل ! من أفغانستان إلى زيمبابوي، من أستراليا إلى الولايات المتحدة الأمريكية. الأرجنتين، البرازيل، كندا، فرنسا، ألمانيا، المكسيك، المملكة المتحدة، إسبانيا \n معظم البلدان في جميع أنحاء العالم متاحة للتنزيل
\n من أفغانستان إلى زيمبابوي، من أستراليا إلى الولايات المتحدة الأمريكية. الأرجنتين، البرازيل، كندا، فرنسا، ألمانيا، المكسيك، المملكة المتحدة، أسبانيا , …
\n</string> \n</string>
<string name="restart_search">إعادة البحث</string> <string name="restart_search">إعادة البحث</string>
<string name="osmand_extended_description_part7">المساهمة في OSM <string name="osmand_extended_description_part7">المساهمة في OSM
@ -2372,12 +2372,13 @@
\n \n
\n بعض الميزات الرئيسية:</string> \n بعض الميزات الرئيسية:</string>
<string name="osmand_plus_extended_description_part2">الملاحة <string name="osmand_plus_extended_description_part2">الملاحة
\n• يعمل على الإنترنت (سريع) أو في وضع غير متصل (لا رسوم تجوال خارج الوطن) \n • يعمل على الإنترنت (سريع) أو في وضع غير متصل (لا رسوم تجوال خارج الوطن)
\n• توجيه صوتي بالتفصيل (الأصوات المسجلة أو مدرجة) \n • توجيه صوتي بالتفصيل (الأصوات المسجلة أو مدرجة)
\n• موجه مسار اختياري، عرض اسم الشارع، والوقت المقدر للوصول \n • موجه مسار اختياري، عرض اسم الشارع، والوقت المقدر للوصول
\n• يدعم نقاط وسيطة خلال مسارك \n • يدعم نقاط وسيطة خلال مسارك
\n• إعادة تلقائية للتوجيه كلما انحرفت عن الطريق \n • إعادة تلقائية للتوجيه كلما انحرفت عن الطريق
\n• البحث عن الأماكن حسب العنوان، النوع (مثل: مطعم، فندق، محطة وقود، متحف)،أو حسب الإحداثيات الجغرافية</string> \n • البحث عن الأماكن حسب العنوان، النوع (مثل: مطعم، فندق، محطة وقود، متحف)،أو حسب الإحداثيات الجغرافية
\n</string>
<string name="osmand_plus_extended_description_part3">عرض الخريطة <string name="osmand_plus_extended_description_part3">عرض الخريطة
\n• عرض موقعك والتوجيه \n• عرض موقعك والتوجيه
\n• محاذاة اختيارية للصورة وفق البوصلة أو توجيه الحركة \n• محاذاة اختيارية للصورة وفق البوصلة أو توجيه الحركة
@ -2418,7 +2419,8 @@
<string name="quick_action_duplicates">اسم الاختصار السريع المحدد قيد الاستخدام، لقد تم تغييره إلى %1$s لتجنب التكرار.</string> <string name="quick_action_duplicates">اسم الاختصار السريع المحدد قيد الاستخدام، لقد تم تغييره إلى %1$s لتجنب التكرار.</string>
<string name="quick_action_page_list_descr">الضغط على زر الإجراء سيطبق أحد الأنماط من القائمة أدناه.</string> <string name="quick_action_page_list_descr">الضغط على زر الإجراء سيطبق أحد الأنماط من القائمة أدناه.</string>
<string name="route_points_category_name">تنقلاتك على هذا الطريق</string> <string name="route_points_category_name">تنقلاتك على هذا الطريق</string>
<string name="navigate_point_olc_info_area">OLC الصالحة بالكامل\nتمثل المنطقة: %1$s x %2$s</string> <string name="navigate_point_olc_info_area">الصالحة بالكامل OLC
\nيمثل المنطقة: %1$s x %2$s</string>
<string name="wrong_user_name">اسم المستخدم خاطئ</string> <string name="wrong_user_name">اسم المستخدم خاطئ</string>
<string name="shared_string_to">إلى</string> <string name="shared_string_to">إلى</string>
<string name="mapillary_menu_date_from">مِن</string> <string name="mapillary_menu_date_from">مِن</string>
@ -2468,7 +2470,7 @@
<string name="add_point_before">إضافة نقطة قبل</string> <string name="add_point_before">إضافة نقطة قبل</string>
<string name="add_point_after">إضافة نقطة بعد</string> <string name="add_point_after">إضافة نقطة بعد</string>
<string name="shared_string_options">خيارات</string> <string name="shared_string_options">خيارات</string>
<string name="measurement_tool_snap_to_road_descr">سيتم توصيل النقاط بطرق الوضع المحدد.</string> <string name="measurement_tool_snap_to_road_descr">سيتم توصيل النقاط بمسارات الوضع المحدد.</string>
<string name="measurement_tool_save_as_new_track_descr">يمكنك حفظ النقاط إما كنقاط طريق أو كخط.</string> <string name="measurement_tool_save_as_new_track_descr">يمكنك حفظ النقاط إما كنقاط طريق أو كخط.</string>
<string name="choose_navigation_type">اختر وضع الملاحة</string> <string name="choose_navigation_type">اختر وضع الملاحة</string>
<string name="add_route_points">إضافة نقاط مسار</string> <string name="add_route_points">إضافة نقاط مسار</string>
@ -2481,12 +2483,12 @@
<string name="map_orientation_change_in_accordance_with_speed">عتبة توجيه الخريطة</string> <string name="map_orientation_change_in_accordance_with_speed">عتبة توجيه الخريطة</string>
<string name="map_orientation_change_in_accordance_with_speed_descr">حدد أدناه على أي سرعة يتغير توجيه الخريطة من \'اتجاه الحركة\' إلى \'البوصلة\'.</string> <string name="map_orientation_change_in_accordance_with_speed_descr">حدد أدناه على أي سرعة يتغير توجيه الخريطة من \'اتجاه الحركة\' إلى \'البوصلة\'.</string>
<string name="all_markers_moved_to_history">تم نقل جميع العلامات إلى السجل</string> <string name="all_markers_moved_to_history">تم نقل جميع العلامات إلى السجل</string>
<string name="marker_moved_to_history">تم نقل العلامة إلى السجل</string> <string name="marker_moved_to_history">تم نقل التوجيه المباشر إلى السجل</string>
<string name="marker_moved_to_active">العلامة أصبحت نشطة</string> <string name="marker_moved_to_active">التوجيه المباشر انتقل كنشط</string>
<string name="shared_string_list">قائمة</string> <string name="shared_string_list">قائمة</string>
<string name="shared_string_groups">مجموعات</string> <string name="shared_string_groups">مجموعات</string>
<string name="passed">آخر استخدام : %1$s</string> <string name="passed">آخر استخدام : %1$s</string>
<string name="make_active">تنشيط العلامة</string> <string name="make_active">تنشيط التوجيه المباشر</string>
<string name="today">اليوم</string> <string name="today">اليوم</string>
<string name="yesterday">أمس</string> <string name="yesterday">أمس</string>
<string name="last_seven_days">آخر ٧ أيام</string> <string name="last_seven_days">آخر ٧ أيام</string>
@ -2502,12 +2504,12 @@
<string name="show_arrows_on_the_map">سهم متجه للهدف</string> <string name="show_arrows_on_the_map">سهم متجه للهدف</string>
<string name="show_passed">عرض المتجاوز</string> <string name="show_passed">عرض المتجاوز</string>
<string name="hide_passed">إخفاء المتجاوز</string> <string name="hide_passed">إخفاء المتجاوز</string>
<string name="remove_from_map_markers">إزالة من \"علامات الخريطة\"</string> <string name="remove_from_map_markers">إزالة من \"التوجيه المباشر\"</string>
<string name="descendingly">تنازلي</string> <string name="descendingly">تنازلي</string>
<string name="ascendingly">تصاعدي</string> <string name="ascendingly">تصاعدي</string>
<string name="date_added">تاريخ الإضافة</string> <string name="date_added">تاريخ الإضافة</string>
<string name="order_by">ترتيب حسب:</string> <string name="order_by">ترتيب حسب:</string>
<string name="marker_show_distance_descr">حدد كيفية الإشارة إلى مسافة واتجاه العلامة على شاشة الخريطة:</string> <string name="marker_show_distance_descr">حدد كيفية الإشارة إلى المسافة والاتجاه للتوجيه المباشر على شاشة الخريطة:</string>
<string name="use_location">استخدم الموقع</string> <string name="use_location">استخدم الموقع</string>
<string name="add_location_as_first_point_descr">أضف موقعك كنقطة أولى لتخطيط طريق مثالي.</string> <string name="add_location_as_first_point_descr">أضف موقعك كنقطة أولى لتخطيط طريق مثالي.</string>
<string name="my_location">موقعي</string> <string name="my_location">موقعي</string>
@ -2518,7 +2520,7 @@
<string name="marker_save_as_track_descr">تصدير علاماتك إلى ملف يمكنك تحديده هنا:</string> <string name="marker_save_as_track_descr">تصدير علاماتك إلى ملف يمكنك تحديده هنا:</string>
<string name="move_to_history">نقل إلى السجل</string> <string name="move_to_history">نقل إلى السجل</string>
<string name="group_will_be_removed_after_restart">سيتم إزالة المجموعة بعد إعادة تشغيل التطبيق.</string> <string name="group_will_be_removed_after_restart">سيتم إزالة المجموعة بعد إعادة تشغيل التطبيق.</string>
<string name="shared_string_markers">العلامات</string> <string name="shared_string_markers">التوجيه المباشر</string>
<string name="coordinates_format">نمط الإحداثيات</string> <string name="coordinates_format">نمط الإحداثيات</string>
<string name="use_system_keyboard">لوحة مفاتيح النظام</string> <string name="use_system_keyboard">لوحة مفاتيح النظام</string>
<string name="fast_coordinates_input_descr">اختر نسق إدخال الأحداثيات. يمكنك دائماً تغييره بالنقر على خيارات.</string> <string name="fast_coordinates_input_descr">اختر نسق إدخال الأحداثيات. يمكنك دائماً تغييره بالنقر على خيارات.</string>
@ -2535,12 +2537,12 @@
<string name="show_map">أظهر الخريطة</string> <string name="show_map">أظهر الخريطة</string>
<string name="route_is_calculated">تم حساب المسار</string> <string name="route_is_calculated">تم حساب المسار</string>
<string name="round_trip">رحلة ذهاب وإياب</string> <string name="round_trip">رحلة ذهاب وإياب</string>
<string name="plan_route_no_markers_toast">يجب عليك إضافة علامة واحدة على الأقل لاستخدام هذه الوظيفة.</string> <string name="plan_route_no_markers_toast">يجب عليك إضافة توجيه مباشر واحد على الأقل لاستخدام هذه الوظيفة.</string>
<string name="wrong_format">تنسيق خاطئ</string> <string name="wrong_format">تنسيق خاطئ</string>
<string name="enter_new_name">أدخل اسم جديد</string> <string name="enter_new_name">أدخل اسم جديد</string>
<string name="shared_string_back">عودة</string> <string name="shared_string_back">عودة</string>
<string name="shared_string_view">عرض</string> <string name="shared_string_view">عرض</string>
<string name="waypoints_added_to_map_markers">تمت إضافة نقاط الطريق إلى علامات الخريطة</string> <string name="waypoints_added_to_map_markers">تمت إضافة نقاط الطريق إلى التوجيه المباشر للخريطة</string>
<string name="wrong_input">إدخال خاطئ</string> <string name="wrong_input">إدخال خاطئ</string>
<string name="import_gpx_file_description">يمكن استيرادها كنقاط مفضلة، أو كملف GPX.</string> <string name="import_gpx_file_description">يمكن استيرادها كنقاط مفضلة، أو كملف GPX.</string>
<string name="import_as_gpx">استيراد كملف GPX</string> <string name="import_as_gpx">استيراد كملف GPX</string>
@ -2548,15 +2550,15 @@
<string name="import_file">استيراد ملف</string> <string name="import_file">استيراد ملف</string>
<string name="tap_on_map_to_hide_interface_descr">نقرة على الخريطة ستفعل أزرار التحكم والويدجت.</string> <string name="tap_on_map_to_hide_interface_descr">نقرة على الخريطة ستفعل أزرار التحكم والويدجت.</string>
<string name="tap_on_map_to_hide_interface">شاشة كاملة</string> <string name="tap_on_map_to_hide_interface">شاشة كاملة</string>
<string name="mark_passed">علامة مُجتازة</string> <string name="mark_passed">توجيه مباشر مجتاز</string>
<string name="empty_state_osm_edits">إنشاء أو تعديل عناصر OSM</string> <string name="empty_state_osm_edits">إنشاء أو تعديل عناصر OSM</string>
<string name="empty_state_osm_edits_descr">قم بإنشاء أو تعديل نقاط الاهتمام OSM ، وفتح ملاحظات OSM أو التعليق عليها ، والمساهمة في ملفات GPX المسجلة.</string> <string name="empty_state_osm_edits_descr">قم بإنشاء أو تعديل نقاط الاهتمام OSM ، وفتح ملاحظات OSM أو التعليق عليها ، والمساهمة في ملفات GPX المسجلة.</string>
<string name="shared_string_deleted">حذف</string> <string name="shared_string_deleted">حذف</string>
<string name="shared_string_edited">مُعدلة</string> <string name="shared_string_edited">مُعدلة</string>
<string name="shared_string_added">تمت الإضافة</string> <string name="shared_string_added">تمت الإضافة</string>
<string name="modify_the_search_query">تعديل طلب البحث.</string> <string name="modify_the_search_query">تعديل طلب البحث.</string>
<string name="marker_activated">تم تنشيط العلامة %s.</string> <string name="marker_activated">تم تنشيط التوجيه المباشر %s.</string>
<string name="one_tap_active_descr">انقر على العلامة في الخريطة لجعلها بالاعلى بدون فتح القائمة.</string> <string name="one_tap_active_descr">انقر على التوجيه المباشر في الخريطة لجعله الاعلى بدون فتح القائمة.</string>
<string name="empty_state_av_notes">تدوين ملاحظات!</string> <string name="empty_state_av_notes">تدوين ملاحظات!</string>
<string name="without_time_limit">بدون حد زمني</string> <string name="without_time_limit">بدون حد زمني</string>
<string name="context_menu_read_full_article">اقرأ المقال كاملا</string> <string name="context_menu_read_full_article">اقرأ المقال كاملا</string>
@ -2564,27 +2566,27 @@
<string name="context_menu_points_of_group">جميع نقاط هذه المجموعة</string> <string name="context_menu_points_of_group">جميع نقاط هذه المجموعة</string>
<string name="open_from">افتح من</string> <string name="open_from">افتح من</string>
<string name="open_till">مفتوح حتى</string> <string name="open_till">مفتوح حتى</string>
<string name="will_close_at">يغلق عند</string> <string name="will_close_at">يغلق أبوابه على</string>
<string name="will_open_at">يفتح عند</string> <string name="will_open_at">سيفتح الأبواب على</string>
<string name="will_open_on">يفتح عند</string> <string name="will_open_on">يفتح أبوابه على</string>
<string name="additional_actions">إجراءات إضافية</string> <string name="additional_actions">إجراءات إضافية</string>
<string name="shared_string_actions">إجراءات</string> <string name="shared_string_actions">إجراءات</string>
<string name="shared_string_marker">العلامات</string> <string name="shared_string_marker">توجيه مباشر</string>
<string name="notes_by_date">الملاحظات حسب التاريخ</string> <string name="notes_by_date">الملاحظات حسب التاريخ</string>
<string name="by_date">حسب التاريخ</string> <string name="by_date">حسب التاريخ</string>
<string name="by_type">حسب النوع</string> <string name="by_type">حسب النوع</string>
<string name="shared_string_more_without_dots">المزيد</string> <string name="shared_string_more_without_dots">المزيد</string>
<string name="appearance_on_the_map">المظهر على الخريطة</string> <string name="appearance_on_the_map">التوجيه المباشر</string>
<string name="shared_string_gpx_waypoints">نقاط المسار</string> <string name="shared_string_gpx_waypoints">نقاط المسار</string>
<string name="add_group">إضافة مجموعة</string> <string name="add_group">إضافة مجموعة</string>
<string name="empty_state_markers_active">قم بإنشاء علامات على الخريطة !</string> <string name="empty_state_markers_active">قم بإنشاء التوجيه المباشر على الخريطة !</string>
<string name="empty_state_markers_groups">استيراد مجموعات</string> <string name="empty_state_markers_groups">استيراد مجموعات</string>
<string name="digits_quantity">عدد الأرقام</string> <string name="digits_quantity">عدد الأرقام</string>
<string name="shared_string_right">اليمين</string> <string name="shared_string_right">اليمين</string>
<string name="shared_string_left">اليسار</string> <string name="shared_string_left">اليسار</string>
<string name="shared_string_paste">لصق</string> <string name="shared_string_paste">لصق</string>
<string name="go_to_next_field">الانتقال إلى الحقل التالي</string> <string name="go_to_next_field">الانتقال إلى الحقل التالي</string>
<string name="rename_marker">إعادة تسمية العلامة</string> <string name="rename_marker">إعادة تسمية التوجيه المباشر</string>
<string name="total_donations">مجموع التبرعات</string> <string name="total_donations">مجموع التبرعات</string>
<string name="rendering_attr_hidePOILabels_name">تسميات POI</string> <string name="rendering_attr_hidePOILabels_name">تسميات POI</string>
<string name="shared_string_without_name">بدون اسم</string> <string name="shared_string_without_name">بدون اسم</string>
@ -2616,7 +2618,7 @@
<string name="south_abbreviation">ج</string> <string name="south_abbreviation">ج</string>
<string name="north_abbreviation">ش</string> <string name="north_abbreviation">ش</string>
<string name="optional_point_name">اسم النقطة</string> <string name="optional_point_name">اسم النقطة</string>
<string name="transport_nearby_routes_within">الطرق القريبة في الداخل</string> <string name="transport_nearby_routes_within">الطرق الداخلية المجاورة</string>
<string name="enter_the_file_name">أدخل اسم الملف.</string> <string name="enter_the_file_name">أدخل اسم الملف.</string>
<string name="map_import_error">خطأ أثناء استرجاع الخريطة</string> <string name="map_import_error">خطأ أثناء استرجاع الخريطة</string>
<string name="map_imported_successfully">تمت عملية استيراد الخريطة</string> <string name="map_imported_successfully">تمت عملية استيراد الخريطة</string>
@ -2628,7 +2630,7 @@
<string name="choose_file_type">قم باختيار نسق الملف</string> <string name="choose_file_type">قم باختيار نسق الملف</string>
<string name="all_data">جميع البيانات</string> <string name="all_data">جميع البيانات</string>
<string name="osm_notes">ملاحظات OSM</string> <string name="osm_notes">ملاحظات OSM</string>
<string name="will_open_tomorrow_at">سيفتح غداً عند</string> <string name="will_open_tomorrow_at">سيفتح أبوابه غداً على</string>
<string name="what_is_here">ماذا هنا:</string> <string name="what_is_here">ماذا هنا:</string>
<string name="lang_lo">اللاوسية</string> <string name="lang_lo">اللاوسية</string>
<string name="touring_view_renderer">عرض خريطة السياحة</string> <string name="touring_view_renderer">عرض خريطة السياحة</string>
@ -2692,7 +2694,7 @@
<string name="download_all">تنزيل الكل</string> <string name="download_all">تنزيل الكل</string>
<string name="shared_string_restart">إعادة تشغيل التطبيق</string> <string name="shared_string_restart">إعادة تشغيل التطبيق</string>
<string name="shared_string_bookmark">إشارة مرجعية</string> <string name="shared_string_bookmark">إشارة مرجعية</string>
<string name="waypoints_removed_from_map_markers">نقاط بالطريق تم إزالتها من علامات الخريطة</string> <string name="waypoints_removed_from_map_markers">نقاط بالطريق تم إزالتها من التوجيه المباشر للخريطة</string>
<string name="powered_by_osmand">بواسطة أوسماند</string> <string name="powered_by_osmand">بواسطة أوسماند</string>
<string name="osm_live_plan_pricing">الأسعار والاشتراك</string> <string name="osm_live_plan_pricing">الأسعار والاشتراك</string>
<string name="osm_live_payment_monthly_title">شهري</string> <string name="osm_live_payment_monthly_title">شهري</string>
@ -2707,14 +2709,14 @@
<string name="osm_live_payment_renews_annually">يجدد سنويا</string> <string name="osm_live_payment_renews_annually">يجدد سنويا</string>
<string name="osm_live_payment_header">حدد فترة الدفع المناسبة لك:</string> <string name="osm_live_payment_header">حدد فترة الدفع المناسبة لك:</string>
<string name="osm_live_payment_contribute_descr">تبرعات مساعدة صندوق رسم الخرائط OSM.</string> <string name="osm_live_payment_contribute_descr">تبرعات مساعدة صندوق رسم الخرائط OSM.</string>
<string name="markers_remove_dialog_msg">حذف العلامة \'%s\'؟</string> <string name="markers_remove_dialog_msg">حذف التوجيه المباشر \'%s\'؟</string>
<string name="edit_map_marker">تعديل العلامة</string> <string name="edit_map_marker">تعديل التوجيه المباشر</string>
<string name="search_street">بحث عن شارع</string> <string name="search_street">بحث عن شارع</string>
<string name="start_search_from_city">اختر المدينة أولاً</string> <string name="start_search_from_city">اختر المدينة أولاً</string>
<string name="shared_string_restore">استعادة</string> <string name="shared_string_restore">استعادة</string>
<string name="third_party_application">تطبيق من طرف ثالث</string> <string name="third_party_application">تطبيق من طرف ثالث</string>
<string name="keep_passed_markers_descr">ستبقى العلامات المضافة من مجموعة إحداثيات أو من نقاط طريق على الخريطة عند اختيار \"تجاوز العلامة\". إذا كانت المجموعة غير نشطة ستختفي العلامات من الخريطة.</string> <string name="keep_passed_markers_descr">عند التفعيل سيبقى التوجيه المباشر المضاف من مجموعة إحداثيات أو من نقاط طريق على الخريطة عند اختيار \"تجاوز التوجيه المباشر\". إذا كانت المجموعة غير نشطة ستختفي الوجهات المباشرة من الخريطة.</string>
<string name="keep_passed_markers">إبقاء العلامة المتجاوز</string> <string name="keep_passed_markers">إبقاء التوجيه المباشر المتجاوز</string>
<string name="more_transport_on_stop_hint">هناك المزيد من وسائل النقل في هذا الموقف.</string> <string name="more_transport_on_stop_hint">هناك المزيد من وسائل النقل في هذا الموقف.</string>
<string name="ask_for_location_permission">يرجى إعطاء إذن تحديد الموقع للتطبيق لكي يواصل.</string> <string name="ask_for_location_permission">يرجى إعطاء إذن تحديد الموقع للتطبيق لكي يواصل.</string>
<string name="thank_you_for_feedback">شكرا على الرد</string> <string name="thank_you_for_feedback">شكرا على الرد</string>
@ -2842,7 +2844,7 @@
<string name="empty_state_av_notes_desc">إضافة ملاحظة صوتية أو فيديو أو صورة لكل نقطة على الخريطة، باستخدام قائمة السياق أو القطعة.</string> <string name="empty_state_av_notes_desc">إضافة ملاحظة صوتية أو فيديو أو صورة لكل نقطة على الخريطة، باستخدام قائمة السياق أو القطعة.</string>
<string name="looking_for_tracks_with_waypoints">ابحث عن المسارات مع نقاط الطريق</string> <string name="looking_for_tracks_with_waypoints">ابحث عن المسارات مع نقاط الطريق</string>
<string name="add_track_to_markers_descr">حدد مسار لإضافة نقاط الطريق إلى العلامات(يتم سرد المسارات فقط مع نقاط الطريق).</string> <string name="add_track_to_markers_descr">حدد مسار لإضافة نقاط الطريق إلى العلامات(يتم سرد المسارات فقط مع نقاط الطريق).</string>
<string name="empty_state_markers_active_desc">نقرة طويلة أو قصيرة على الأماكن ثم اضغط على زر علامة.</string> <string name="empty_state_markers_active_desc">نقرة طويلة أو قصيرة على الأماكن ثم اضغط على زر التوجيه المباشر.</string>
<string name="empty_state_markers_groups_desc">يمكنك استيراد المجموعات المفضلة أو نقاط المسار كتوجيه.</string> <string name="empty_state_markers_groups_desc">يمكنك استيراد المجموعات المفضلة أو نقاط المسار كتوجيه.</string>
<string name="empty_state_markers_history_desc">ستظهر العلامات التي تم تجاوزها على هذه الشاشة.</string> <string name="empty_state_markers_history_desc">ستظهر العلامات التي تم تجاوزها على هذه الشاشة.</string>
<string name="show_guide_line_descr">خط مباشر من موقعك إلى الهدف.</string> <string name="show_guide_line_descr">خط مباشر من موقعك إلى الهدف.</string>
@ -2992,7 +2994,7 @@
<string name="years_5">سنوات</string> <string name="years_5">سنوات</string>
<string name="months_3">ثلاثة أشهر</string> <string name="months_3">ثلاثة أشهر</string>
<string name="price_free">مجاناً</string> <string name="price_free">مجاناً</string>
<string name="rendering_attr_showCycleNodeNetworkRoutes_name">إظهار شبكة طرق الدارجات الهوائية</string> <string name="rendering_attr_showCycleNodeNetworkRoutes_name">إظهار شبكة مسارات الدارجات الهوائية</string>
<string name="download_map_dialog">نافذة تحميل الخريطة</string> <string name="download_map_dialog">نافذة تحميل الخريطة</string>
<string name="dialogs_and_notifications_title">النوافذ والإشعارات</string> <string name="dialogs_and_notifications_title">النوافذ والإشعارات</string>
<string name="dialogs_and_notifications_descr">التحكم في النوافذ المنبثقة ، ومربعات الحوار والإشعارات.</string> <string name="dialogs_and_notifications_descr">التحكم في النوافذ المنبثقة ، ومربعات الحوار والإشعارات.</string>
@ -3017,7 +3019,7 @@
<string name="paste_Osmand_data_folder_path">لصق مسار مجلد بيانات أوسماند</string> <string name="paste_Osmand_data_folder_path">لصق مسار مجلد بيانات أوسماند</string>
<string name="change_osmand_data_folder_question">تغيير مجلد التخزين ؟</string> <string name="change_osmand_data_folder_question">تغيير مجلد التخزين ؟</string>
<string name="move_maps_to_new_destination">نقل للموقع الجديد</string> <string name="move_maps_to_new_destination">نقل للموقع الجديد</string>
<string name="avoid_in_routing_descr_">تجنب بعض أنواع الطرق</string> <string name="avoid_in_routing_descr_">تجنب بعض الطرق</string>
<string name="app_mode_utv">جنبًا إلى جنب</string> <string name="app_mode_utv">جنبًا إلى جنب</string>
<string name="rendering_attr_piste_difficulty_aerialway_name">طريق تلفريك</string> <string name="rendering_attr_piste_difficulty_aerialway_name">طريق تلفريك</string>
<string name="rendering_attr_piste_difficulty_connection_name">اتصال</string> <string name="rendering_attr_piste_difficulty_connection_name">اتصال</string>
@ -3042,7 +3044,7 @@
<string name="routing_attr_prefer_unpaved_name">تفضيل الطرق الغير معبدة</string> <string name="routing_attr_prefer_unpaved_name">تفضيل الطرق الغير معبدة</string>
<string name="routing_attr_prefer_unpaved_description">تفضيل الطرق الغير معبدة.</string> <string name="routing_attr_prefer_unpaved_description">تفضيل الطرق الغير معبدة.</string>
<string name="update_all_maps">تحديث كل الخرائط</string> <string name="update_all_maps">تحديث كل الخرائط</string>
<string name="update_all_maps_q">تحديث (%1$d) خريطة؟</string> <string name="update_all_maps_q">هل أنت متأكد من رغبتك بتحديث (%1$d) خريطة؟</string>
<string name="release_3_5">• تحديث التطبيق وإعدادات الأوضاع: يتم ترتيب الإعدادات الآن حسب النوع. يمكن تخصيص كل وضع بشكل منفصل. <string name="release_3_5">• تحديث التطبيق وإعدادات الأوضاع: يتم ترتيب الإعدادات الآن حسب النوع. يمكن تخصيص كل وضع بشكل منفصل.
\n \n
\n • نافذة جديدة لتنزيل الخريطة المقترحة أثناء تصفح الخرائط \n • نافذة جديدة لتنزيل الخريطة المقترحة أثناء تصفح الخرائط
@ -3328,8 +3330,8 @@
<string name="routing_attr_piste_type_skitour_description">طرق لجولات التزلج.</string> <string name="routing_attr_piste_type_skitour_description">طرق لجولات التزلج.</string>
<string name="routing_attr_piste_type_sled_name">تزلج</string> <string name="routing_attr_piste_type_sled_name">تزلج</string>
<string name="routing_attr_piste_type_sled_description">منحدرات لاستخدام الزلاجات.</string> <string name="routing_attr_piste_type_sled_description">منحدرات لاستخدام الزلاجات.</string>
<string name="routing_attr_allow_intermediate_name">السماح بالطرق المتوسطة</string> <string name="routing_attr_allow_intermediate_name">السماح بالمسارات المتوسطة</string>
<string name="routing_attr_allow_intermediate_description">طرق أكثر صعوبة مع أقسام أكثر حدة. بعض العقبات ينبغي تجنبها.</string> <string name="routing_attr_allow_intermediate_description">طرق أكثر صعوبة مع أقسام أكثر حدة. بعض العقبات التي ينبغي تجنبها.</string>
<string name="routing_attr_allow_advanced_name">السماح للطرق المتقدمة</string> <string name="routing_attr_allow_advanced_name">السماح للطرق المتقدمة</string>
<string name="routing_attr_allow_advanced_description">طرق صعبة ، مع عقبات خطيرة وأقسام شديدة الانحدار.</string> <string name="routing_attr_allow_advanced_description">طرق صعبة ، مع عقبات خطيرة وأقسام شديدة الانحدار.</string>
<string name="routing_attr_allow_expert_name">السماح بطرق المتخصصين</string> <string name="routing_attr_allow_expert_name">السماح بطرق المتخصصين</string>
@ -3355,8 +3357,8 @@
<string name="sett_generic_ext_input">لوحة المفاتيح</string> <string name="sett_generic_ext_input">لوحة المفاتيح</string>
<string name="sett_wunderlinq_ext_input">وندرلينك</string> <string name="sett_wunderlinq_ext_input">وندرلينك</string>
<string name="sett_parrot_ext_input">ببغاء</string> <string name="sett_parrot_ext_input">ببغاء</string>
<string name="new_route_calculated_dist_dbg">المسار: المسافة%1$s، الوقت %2$s. <string name="new_route_calculated_dist_dbg">المسار: المسافة%2$s، وقت التوجيه %1$s.
\nالحساب: %3$.1f ث، %4$d طريق، %5$d تجانب</string> \nالحساب: %3$.1f ث، %4$d طريق، %5$d تجانب)</string>
<string name="lang_oc">الأوكيتانية</string> <string name="lang_oc">الأوكيتانية</string>
<string name="get_discount_second_part">ثم %1$s</string> <string name="get_discount_second_part">ثم %1$s</string>
<string name="apply_to_current_profile">تطبيق فقط على \"%1$s\"</string> <string name="apply_to_current_profile">تطبيق فقط على \"%1$s\"</string>
@ -3378,7 +3380,7 @@
<string name="select_color">اختر اللون</string> <string name="select_color">اختر اللون</string>
<string name="edit_profiles_descr">لا يمكنك حذف أوضاع أوسماند الافتراضية ، ولكن يمكنك تعطيلها في الشاشة السابقة ، أو نقلها إلى الأسفل.</string> <string name="edit_profiles_descr">لا يمكنك حذف أوضاع أوسماند الافتراضية ، ولكن يمكنك تعطيلها في الشاشة السابقة ، أو نقلها إلى الأسفل.</string>
<string name="edit_profiles">تحرير الأوضاع</string> <string name="edit_profiles">تحرير الأوضاع</string>
<string name="select_nav_profile_dialog_message">يؤثر نوع التنقل على قواعد حساب الطرق.</string> <string name="select_nav_profile_dialog_message">يؤثر نوع التنقل على قواعد حسابات المسار.</string>
<string name="profile_appearance">مظهر الوضع</string> <string name="profile_appearance">مظهر الوضع</string>
<string name="choose_icon_color_name">اختر الايقونة واللون والاسم</string> <string name="choose_icon_color_name">اختر الايقونة واللون والاسم</string>
<string name="reorder_profiles">تحرير قائمة الأوضاع</string> <string name="reorder_profiles">تحرير قائمة الأوضاع</string>
@ -3534,7 +3536,7 @@
<string name="restore_all_profile_settings">استعادة جميع إعدادات الوضع؟</string> <string name="restore_all_profile_settings">استعادة جميع إعدادات الوضع؟</string>
<string name="saving_new_profile">حفظ الوضع الجديد</string> <string name="saving_new_profile">حفظ الوضع الجديد</string>
<string name="profile_backup_failed">لا يمكن عمل نسخة احتياطية لهذا الوضع.</string> <string name="profile_backup_failed">لا يمكن عمل نسخة احتياطية لهذا الوضع.</string>
<string name="clear_recorded_data_warning">مسح البيانات المسجلة؟</string> <string name="clear_recorded_data_warning">هل أنت متأكد من أنك تريد مسح البيانات المسجلة؟</string>
<string name="importing_from">استيراد البيانات من %1$s</string> <string name="importing_from">استيراد البيانات من %1$s</string>
<string name="shared_string_importing">استيراد</string> <string name="shared_string_importing">استيراد</string>
<string name="checking_for_duplicate_description">OsmAnd تحقق %1$s للتكرارات مع العناصر الموجودة في التطبيق. <string name="checking_for_duplicate_description">OsmAnd تحقق %1$s للتكرارات مع العناصر الموجودة في التطبيق.
@ -3730,7 +3732,7 @@
<string name="default_screen_timeout">مهلة الشاشة الافتراضية</string> <string name="default_screen_timeout">مهلة الشاشة الافتراضية</string>
<string name="export_import_quick_actions_with_profiles_promo">يمكنك تصدير أو استيراد إجراءات سريعة باستخدام أوضاع التطبيق .</string> <string name="export_import_quick_actions_with_profiles_promo">يمكنك تصدير أو استيراد إجراءات سريعة باستخدام أوضاع التطبيق .</string>
<string name="shared_string_delete_all_q">حذف الكل؟</string> <string name="shared_string_delete_all_q">حذف الكل؟</string>
<string name="delete_all_actions_message_q">حذف الاختصارات السريعة %d نهائيًا؟</string> <string name="delete_all_actions_message_q">هل أنت متأكد من رغبتك في حذف الاختصارات السريعة %d نهائيًا؟</string>
<string name="screen_timeout">مهلة الشاشة</string> <string name="screen_timeout">مهلة الشاشة</string>
<string name="shared_string_tones">نغمات</string> <string name="shared_string_tones">نغمات</string>
<string name="width_limit_description">أدل بعرض مركبتك، قد يتم تطبيق بعض القيود على المركبات العريضة.</string> <string name="width_limit_description">أدل بعرض مركبتك، قد يتم تطبيق بعض القيود على المركبات العريضة.</string>
@ -3787,7 +3789,7 @@
<string name="osm_edit_closed_note">أغلق ملاحظة OSM</string> <string name="osm_edit_closed_note">أغلق ملاحظة OSM</string>
<string name="set_working_days_to_continue">تحتاج إلى تعيين أيام العمل للمتابعة</string> <string name="set_working_days_to_continue">تحتاج إلى تعيين أيام العمل للمتابعة</string>
<string name="route_between_points">المسار بين النقاط</string> <string name="route_between_points">المسار بين النقاط</string>
<string name="plan_a_route">تخطيط طريق</string> <string name="plan_a_route">قياس المسافة</string>
<string name="add_to_a_track">إضافة إلى مسار</string> <string name="add_to_a_track">إضافة إلى مسار</string>
<string name="add_hidden_group_info">لن تكون النقطة المضافة مرئية على الخريطة، نظرًا لأن المجموعة المحددة مخفية، يمكنك العثور عليها في \"%s\".</string> <string name="add_hidden_group_info">لن تكون النقطة المضافة مرئية على الخريطة، نظرًا لأن المجموعة المحددة مخفية، يمكنك العثور عليها في \"%s\".</string>
<string name="track_show_start_finish_icons">إظهار رموز البدء والانتهاء</string> <string name="track_show_start_finish_icons">إظهار رموز البدء والانتهاء</string>
@ -3800,7 +3802,7 @@
<string name="plan_route_last_edited">التعديل الأخير</string> <string name="plan_route_last_edited">التعديل الأخير</string>
<string name="plan_route_import_track">استيراد المسار</string> <string name="plan_route_import_track">استيراد المسار</string>
<string name="plan_route_open_existing_track">فتح مسار موجود</string> <string name="plan_route_open_existing_track">فتح مسار موجود</string>
<string name="plan_route_create_new_route">إنشاء طريق جديد</string> <string name="plan_route_create_new_route">إنشاء مسار جديد</string>
<string name="plan_route_select_track_file_for_open">حدد المسار للفتح.</string> <string name="plan_route_select_track_file_for_open">حدد المسار للفتح.</string>
<string name="shared_string_done">تم</string> <string name="shared_string_done">تم</string>
<string name="overwrite_track">الكتابة فوق المسار</string> <string name="overwrite_track">الكتابة فوق المسار</string>
@ -3816,7 +3818,7 @@
<string name="route_between_points_warning_desc">بعد ذلك ، ألقط مسارك بأقرب طريق مسموح به باستخدام أحد أوضاع التنقل الخاصة بك لاستخدام هذا الخيار.</string> <string name="route_between_points_warning_desc">بعد ذلك ، ألقط مسارك بأقرب طريق مسموح به باستخدام أحد أوضاع التنقل الخاصة بك لاستخدام هذا الخيار.</string>
<string name="threshold_distance">بداية المسافة</string> <string name="threshold_distance">بداية المسافة</string>
<string name="street_level_imagery">صور للشارع</string> <string name="street_level_imagery">صور للشارع</string>
<string name="plan_route_exit_dialog_descr">إغلاق مسار الرحلة دون حفظ؟ ستفقد كل التغييرات؟</string> <string name="plan_route_exit_dialog_descr">هل أنت متأكد أنك تريد إغلاق مسار الرحلة دون حفظ؟ سوف تفقد كل التغييرات؟</string>
<string name="in_case_of_reverse_direction">في حالة الاتجاه المعاكس</string> <string name="in_case_of_reverse_direction">في حالة الاتجاه المعاكس</string>
<string name="save_track_to_gpx">تسجيل المسار أثناء الملاحة</string> <string name="save_track_to_gpx">تسجيل المسار أثناء الملاحة</string>
<string name="shared_string_save_as_gpx">حفظ كملف مسار جديد</string> <string name="shared_string_save_as_gpx">حفظ كملف مسار جديد</string>
@ -3833,10 +3835,10 @@
<string name="quick_action_add_gpx">أضف إحداثية مسار</string> <string name="quick_action_add_gpx">أضف إحداثية مسار</string>
<string name="map_widget_monitoring">تسجيل الرحلة</string> <string name="map_widget_monitoring">تسجيل الرحلة</string>
<string name="marker_save_as_track">حفظ كمسار</string> <string name="marker_save_as_track">حفظ كمسار</string>
<string name="follow_track">اتبع المسار</string> <string name="follow_track">تتبع المسار</string>
<string name="follow_track_descr">اختر مسار للمتابعة</string> <string name="follow_track_descr">اختر مسار للمتابعة</string>
<string name="import_track_descr">اختر ملف المسار للمتابعة أو قم باستيراده من الجهاز.</string> <string name="import_track_descr">اختر ملف المسار للمتابعة أو قم باستيراده من الجهاز.</string>
<string name="select_another_track">حدد مساراً آخر</string> <string name="select_another_track">حدد مسارا آخر</string>
<string name="navigate_to_track_descr">انتقل من موقعي إلى المسار</string> <string name="navigate_to_track_descr">انتقل من موقعي إلى المسار</string>
<string name="pass_whole_track_descr">نقطة المسار للتنقل</string> <string name="pass_whole_track_descr">نقطة المسار للتنقل</string>
<string name="start_of_the_track">بداية المسار</string> <string name="start_of_the_track">بداية المسار</string>
@ -3997,8 +3999,8 @@
\n • دعم ألوان مخصصة للمفضلة ونقاط لمسار الطريق \n • دعم ألوان مخصصة للمفضلة ونقاط لمسار الطريق
\n \n
\n</string> \n</string>
<string name="profile_type_osmand_string">وضع التطبيق</string> <string name="profile_type_osmand_string">وضع الاستعراض</string>
<string name="profile_type_user_string">حساب المستخدم</string> <string name="profile_type_user_string">ملف تعريف المستخدم</string>
<string name="reverse_all_points">عكس جميع النقاط</string> <string name="reverse_all_points">عكس جميع النقاط</string>
<string name="profile_by_default_description">حدد الوضع الذي سيتم استخدامه في بدء التطبيق.</string> <string name="profile_by_default_description">حدد الوضع الذي سيتم استخدامه في بدء التطبيق.</string>
<string name="shared_string_last_used">آخر استخدام</string> <string name="shared_string_last_used">آخر استخدام</string>
@ -4030,7 +4032,7 @@
<string name="select_folder">تحديد مجلد</string> <string name="select_folder">تحديد مجلد</string>
<string name="select_folder_descr">تحديد مجلد أو إضافة واحد جديد</string> <string name="select_folder_descr">تحديد مجلد أو إضافة واحد جديد</string>
<string name="shared_string_empty">فارغ</string> <string name="shared_string_empty">فارغ</string>
<string name="analyze_by_intervals">تحليل حسب الفاصل الزمني</string> <string name="analyze_by_intervals">التحليل حسب الفواصل الزمنية (الفاصل الزمني)</string>
<string name="upload_to_openstreetmap">رفع إلى خريطة الشارع المفتوح</string> <string name="upload_to_openstreetmap">رفع إلى خريطة الشارع المفتوح</string>
<string name="edit_track">تحرير المسار</string> <string name="edit_track">تحرير المسار</string>
<string name="rename_track">تسمية المسار</string> <string name="rename_track">تسمية المسار</string>
@ -4080,7 +4082,20 @@
\nجميع بيانات OpenPlaceReview مفتوحة ومتاحة للجميع: http://openplacereviews.org/data. \nجميع بيانات OpenPlaceReview مفتوحة ومتاحة للجميع: http://openplacereviews.org/data.
\n \n
\nيمكنك قراءة المزيد على: http://openplacereviews.org</string> \nيمكنك قراءة المزيد على: http://openplacereviews.org</string>
<string name="open_place_reviews">مراجعات الأمكنة</string> <string name="open_place_reviews">OpenPlaceReviews</string>
<string name="opr_use_dev_url">استخدام test.openplacereviews.org</string> <string name="opr_use_dev_url">استخدام test.openplacereviews.org</string>
<string name="login_open_place_reviews">الدخول إلى OpenPlaceReviews</string> <string name="login_open_place_reviews">الدخول إلى OpenPlaceReviews</string>
<string name="activity_type_water_name">ماء</string>
<string name="activity_type_winter_name">شتاء</string>
<string name="activity_type_snowmobile_name">الثلج</string>
<string name="activity_type_riding_name">ركوب</string>
<string name="activity_type_racing_name">سباق</string>
<string name="activity_type_mountainbike_name">دراجة جبلية</string>
<string name="activity_type_cycling_name">دراجة</string>
<string name="activity_type_hiking_name">مشي</string>
<string name="activity_type_running_name">الجري</string>
<string name="activity_type_walking_name">مشي</string>
<string name="activity_type_offroad_name">الطرق الوعرة</string>
<string name="activity_type_motorbike_name">دراجة نارية</string>
<string name="activity_type_car_name">سيارة</string>
</resources> </resources>

View file

@ -3881,4 +3881,14 @@
<string name="poi_wildlife_crossing_bat_bridge">Ponto por vespertoj</string> <string name="poi_wildlife_crossing_bat_bridge">Ponto por vespertoj</string>
<string name="poi_wildlife_crossing">Trairejo por sovaĝaj bestoj</string> <string name="poi_wildlife_crossing">Trairejo por sovaĝaj bestoj</string>
<string name="poi_swimming_area">Naĝejo natura</string> <string name="poi_swimming_area">Naĝejo natura</string>
<string name="poi_piste_status_closed">Stato de skivojo: fermita</string>
<string name="poi_piste_status_open">Stato de skivojo: malfermita</string>
<string name="poi_patrolled_no">Kontrolata: ne</string>
<string name="poi_patrolled_yes">Kontrolata: jes</string>
<string name="poi_gladed_yes">Senarbigita: jes</string>
<string name="poi_piste_name">Nomo de skivojo</string>
<string name="poi_piste_ski_jump">Skisaltejo</string>
<string name="poi_mobile_library">Movebla biblioteko (haltloko)</string>
<string name="poi_summit_register_no">Pinttaglibro: ne</string>
<string name="poi_summit_register_yes">Pinttaglibro: jes</string>
</resources> </resources>

View file

@ -4020,4 +4020,17 @@
<string name="open_place_reviews">OpenPlaceReviews</string> <string name="open_place_reviews">OpenPlaceReviews</string>
<string name="opr_use_dev_url">Uzi test.openplacereviews.org</string> <string name="opr_use_dev_url">Uzi test.openplacereviews.org</string>
<string name="login_open_place_reviews">Ensaluti al OpenPlaceReviews</string> <string name="login_open_place_reviews">Ensaluti al OpenPlaceReviews</string>
<string name="activity_type_water_name">Akvo</string>
<string name="activity_type_winter_name">Vintro</string>
<string name="activity_type_snowmobile_name">Motorsledo</string>
<string name="activity_type_riding_name">Rajdado</string>
<string name="activity_type_racing_name">Kurkonkurso</string>
<string name="activity_type_mountainbike_name">Montbiciklo</string>
<string name="activity_type_cycling_name">Biciklado</string>
<string name="activity_type_hiking_name">Marŝado</string>
<string name="activity_type_running_name">Kurado</string>
<string name="activity_type_walking_name">Piedirado</string>
<string name="activity_type_offroad_name">Ekstervoje</string>
<string name="activity_type_motorbike_name">Motorciklo</string>
<string name="activity_type_car_name">Aŭto</string>
</resources> </resources>

View file

@ -4005,4 +4005,13 @@
<string name="open_place_reviews">OpenPlaceReviews</string> <string name="open_place_reviews">OpenPlaceReviews</string>
<string name="opr_use_dev_url">Utilisez test.openplacereviews.org</string> <string name="opr_use_dev_url">Utilisez test.openplacereviews.org</string>
<string name="login_open_place_reviews">Se connecter à OpenPlaceReviews</string> <string name="login_open_place_reviews">Se connecter à OpenPlaceReviews</string>
<string name="activity_type_water_name">Eau</string>
<string name="activity_type_winter_name">Hiver</string>
<string name="activity_type_snowmobile_name">Motoneige</string>
<string name="activity_type_cycling_name">Vélo</string>
<string name="activity_type_mountainbike_name">VTT</string>
<string name="activity_type_hiking_name">Randonnée</string>
<string name="activity_type_running_name">Course à pied</string>
<string name="activity_type_walking_name">Marche</string>
<string name="activity_type_car_name">Voiture</string>
</resources> </resources>

View file

@ -54,7 +54,7 @@
<string name="poi_service_tyres">Autógumi-szerelő</string> <string name="poi_service_tyres">Autógumi-szerelő</string>
<string name="poi_car_wash">Autómosó</string> <string name="poi_car_wash">Autómosó</string>
<string name="poi_fuel">Benzinkút;Töltőállomás;Gázolajtöltő-állomás</string> <string name="poi_fuel">Benzinkút;Töltőállomás;Gázolajtöltő-állomás</string>
<string name="poi_electricity_combined_charging">Elektromos töltőállomás</string> <string name="poi_electricity_combined_charging">Elektromos töltőállomás;Elektromos autó töltése;Villanyautó töltése;Elektromos töltőpont</string>
<string name="poi_compressed_air">Sűrített levegő</string> <string name="poi_compressed_air">Sűrített levegő</string>
<string name="poi_parking">Parkoló</string> <string name="poi_parking">Parkoló</string>
<string name="poi_motorcycle_parking">Motorkerékpár-parkoló</string> <string name="poi_motorcycle_parking">Motorkerékpár-parkoló</string>
@ -3879,4 +3879,14 @@
<string name="poi_wildlife_crossing_bat_tunnel">Denevéralagút</string> <string name="poi_wildlife_crossing_bat_tunnel">Denevéralagút</string>
<string name="poi_wildlife_crossing_bat_bridge">Denevérhíd</string> <string name="poi_wildlife_crossing_bat_bridge">Denevérhíd</string>
<string name="poi_wildlife_crossing">Vadátjáró</string> <string name="poi_wildlife_crossing">Vadátjáró</string>
<string name="poi_summit_register_no">Csúcsnapló nincs</string>
<string name="poi_summit_register_yes">Csúcsnapló van</string>
<string name="poi_patrolled_no">Hegyi mentő nincs</string>
<string name="poi_patrolled_yes">Hegyi mentő van</string>
<string name="poi_gladed_yes">Erdei pálya</string>
<string name="poi_mobile_library">Mozgó könyvtár tartózkodási helye</string>
<string name="poi_piste_status_closed">Pálya állapota: zárva</string>
<string name="poi_piste_status_open">Pálya állapota: nyitva</string>
<string name="poi_piste_name">Pálya neve</string>
<string name="poi_piste_ski_jump">Síugrósánc</string>
</resources> </resources>

View file

@ -3881,4 +3881,14 @@
<string name="poi_wildlife_crossing_bat_bridge">Brú fyrir leðurblökur</string> <string name="poi_wildlife_crossing_bat_bridge">Brú fyrir leðurblökur</string>
<string name="poi_wildlife_crossing">Þverun villtra dýra</string> <string name="poi_wildlife_crossing">Þverun villtra dýra</string>
<string name="poi_swimming_area">Sundsvæði</string> <string name="poi_swimming_area">Sundsvæði</string>
<string name="poi_mobile_library">Stæði fyrir bókabíl</string>
<string name="poi_summit_register_no">Skráning á tind: nei</string>
<string name="poi_summit_register_yes">Skráning á tind: já</string>
<string name="poi_piste_status_closed">Staða brautar: lokuð</string>
<string name="poi_piste_status_open">Staða brautar: opin</string>
<string name="poi_patrolled_no">Eftirlit: nei</string>
<string name="poi_patrolled_yes">Eftirlit: já</string>
<string name="poi_gladed_yes">Skafið: já</string>
<string name="poi_piste_name">Heiti brautar</string>
<string name="poi_piste_ski_jump">Skíðastökk</string>
</resources> </resources>

View file

@ -3972,7 +3972,7 @@
<string name="select_folder">Veldu möppu</string> <string name="select_folder">Veldu möppu</string>
<string name="select_folder_descr">Veldu möppu eða bættu við nýrri</string> <string name="select_folder_descr">Veldu möppu eða bættu við nýrri</string>
<string name="shared_string_empty">Tómt</string> <string name="shared_string_empty">Tómt</string>
<string name="analyze_by_intervals">Greina eftir millibilum (uppskipting millibila)</string> <string name="analyze_by_intervals">Greina eftir uppskiptingu millibila</string>
<string name="upload_to_openstreetmap">Senda inn í OpenStreetMap</string> <string name="upload_to_openstreetmap">Senda inn í OpenStreetMap</string>
<string name="edit_track">Breyta ferli</string> <string name="edit_track">Breyta ferli</string>
<string name="rename_track">Endurnefna feril</string> <string name="rename_track">Endurnefna feril</string>
@ -4005,4 +4005,32 @@
<string name="routing_engine_vehicle_type_mtb">Fjallahjól</string> <string name="routing_engine_vehicle_type_mtb">Fjallahjól</string>
<string name="message_server_error">Villa í netþjóni: %1$s</string> <string name="message_server_error">Villa í netþjóni: %1$s</string>
<string name="message_name_is_already_exists">Nafnið er þegar til staðar</string> <string name="message_name_is_already_exists">Nafnið er þegar til staðar</string>
<string name="delete_online_routing_engine">Eyða þessari leiðagerð á netinu\?</string>
<string name="context_menu_read_full">Lesa óstytt</string>
<string name="context_menu_edit_descr">Breyta lýsingu</string>
<string name="delete_waypoints">Eyða ferilpunktum</string>
<string name="copy_to_map_markers">Afrita í kortamerki</string>
<string name="copy_to_map_favorites">Afrita í eftirlæti</string>
<string name="upload_photo">Sendi inn</string>
<string name="upload_photo_completed">Innsendingu er lokið</string>
<string name="uploading_count">Sendi inn %1$d af %2$d</string>
<string name="uploaded_count">Sent inn %1$d af %2$d</string>
<string name="toast_select_edits_for_upload">Veldu breytingar til að senda inn</string>
<string name="hillshade_slope_contour_lines">Hæðaskygging / Halli / Hæðarlínur</string>
<string name="open_place_reviews">OpenPlaceReviews</string>
<string name="opr_use_dev_url">Nota test.openplacereviews.org</string>
<string name="login_open_place_reviews">Skrá inn á OpenPlaceReviews</string>
<string name="activity_type_water_name">Vatn</string>
<string name="activity_type_winter_name">Vetur</string>
<string name="activity_type_snowmobile_name">Vélsleðar</string>
<string name="activity_type_riding_name">Útreiðar</string>
<string name="activity_type_racing_name">Kappakstur</string>
<string name="activity_type_mountainbike_name">Fjallahjól</string>
<string name="activity_type_cycling_name">Hjólreiðar</string>
<string name="activity_type_hiking_name">Gönguferðir</string>
<string name="activity_type_running_name">Hlaup</string>
<string name="activity_type_walking_name">Gangandi</string>
<string name="activity_type_offroad_name">Utanvegaakstur</string>
<string name="activity_type_motorbike_name">Vélhjól</string>
<string name="activity_type_car_name">Akandi</string>
</resources> </resources>

View file

@ -3970,7 +3970,7 @@
<string name="select_folder">בחירת תקינה</string> <string name="select_folder">בחירת תקינה</string>
<string name="select_folder_descr">נא לבחור תיקייה או להוסיף אחת חדשה</string> <string name="select_folder_descr">נא לבחור תיקייה או להוסיף אחת חדשה</string>
<string name="shared_string_empty">ריק</string> <string name="shared_string_empty">ריק</string>
<string name="analyze_by_intervals">ניתוח לפי מרווחים (פיצול מרווחים)</string> <string name="analyze_by_intervals">ניתוח מרווחי פיצול</string>
<string name="upload_to_openstreetmap">העלאה ל־OpenStreetMap</string> <string name="upload_to_openstreetmap">העלאה ל־OpenStreetMap</string>
<string name="edit_track">עריכת מסלול</string> <string name="edit_track">עריכת מסלול</string>
<string name="rename_track">שינוי שם מסלול</string> <string name="rename_track">שינוי שם מסלול</string>
@ -4016,4 +4016,11 @@
<string name="open_place_reviews">OpenPlaceReviews</string> <string name="open_place_reviews">OpenPlaceReviews</string>
<string name="opr_use_dev_url">להשתמש ב־test.openplacereviews.org</string> <string name="opr_use_dev_url">להשתמש ב־test.openplacereviews.org</string>
<string name="login_open_place_reviews">כניסה ל־OpenPlaceReviews</string> <string name="login_open_place_reviews">כניסה ל־OpenPlaceReviews</string>
<string name="announcement_time_descr">זמן ההכרזה של ההנחיות הקוליות השונות תלוי בסוג ההכרזה, במהירות הניווט הנוכחית ובמהירות הניווט כבררת מחדל.</string>
<string name="hillshade_slope_contour_lines">הצללה / מדרון / קווי מתאר</string>
<string name="open_place_reviews_plugin_description">OpenPlaceReviews הוא מיזם בהובלת הקהילה בנוגע למקומות ציבוריים כגון מסעדות, מלונות, מוזיאונים ונקודות דרך. הוא אוסף מידע ציבורי עליהם כגון תמונות, סקירות, קישורים למערכות אחרות שמקושרות ל־OpenStreetMap, ויקיפדיה.
\n
\nכל הנתונים של OpenPlaceReview הם פתוחים וזמינים לציבור הרחב: http://openplacereviews.org/data.
\n
\nניתן לקרוא עוד באתר: http://openplacereviews.org</string>
</resources> </resources>

View file

@ -502,7 +502,7 @@
<string name="poi_climbing">Tırmanma</string> <string name="poi_climbing">Tırmanma</string>
<string name="poi_cricket">Kriket</string> <string name="poi_cricket">Kriket</string>
<string name="poi_croquet">Kroket</string> <string name="poi_croquet">Kroket</string>
<string name="poi_cycling">Bisiklete binme</string> <string name="poi_cycling">Bisiklet sürme</string>
<string name="poi_diving">Dalış</string> <string name="poi_diving">Dalış</string>
<string name="poi_scuba_diving">Tüplü dalış</string> <string name="poi_scuba_diving">Tüplü dalış</string>
<string name="poi_dog_racing">Köpek yarışı</string> <string name="poi_dog_racing">Köpek yarışı</string>

View file

@ -2227,7 +2227,7 @@
<string name="marker_save_as_track_descr">İşaretleyicilerinizi şu GPX dosyasına aktarın:</string> <string name="marker_save_as_track_descr">İşaretleyicilerinizi şu GPX dosyasına aktarın:</string>
<string name="show_arrows_on_the_map">Haritada yön gösterici okları göster</string> <string name="show_arrows_on_the_map">Haritada yön gösterici okları göster</string>
<string name="measurement_tool_snap_to_road_descr">OsmAnd seçilmiş profil için rotalı noktalara bağlanacak.</string> <string name="measurement_tool_snap_to_road_descr">OsmAnd seçilmiş profil için rotalı noktalara bağlanacak.</string>
<string name="none_point_error">Lütfen en az bir nokta ekleyiniz.</string> <string name="none_point_error">Lütfen en az bir nokta ekleyin.</string>
<string name="measurement_tool_action_bar">Haritayı görüntüle ve nokta ekle</string> <string name="measurement_tool_action_bar">Haritayı görüntüle ve nokta ekle</string>
<string name="store_tracks_in_monthly_directories">Kaydedilmiş izlenen yolları aylık klasörlerde depola</string> <string name="store_tracks_in_monthly_directories">Kaydedilmiş izlenen yolları aylık klasörlerde depola</string>
<string name="mapillary_menu_filter_description">Resimleri göndericiye, tarihe ya da türüne göre filtreleyin. Sadece yakın mesafe yakınlaştırmasında etkin.</string> <string name="mapillary_menu_filter_description">Resimleri göndericiye, tarihe ya da türüne göre filtreleyin. Sadece yakın mesafe yakınlaştırmasında etkin.</string>
@ -3738,7 +3738,7 @@
<string name="track_coloring_solid">Koyu</string> <string name="track_coloring_solid">Koyu</string>
<string name="plan_route_last_edited">Son düzenleme</string> <string name="plan_route_last_edited">Son düzenleme</string>
<string name="plan_route_import_track">Yolu içe aktar</string> <string name="plan_route_import_track">Yolu içe aktar</string>
<string name="plan_route_open_existing_track">Mevcut yolu aç</string> <string name="plan_route_open_existing_track">Var olan yolu aç</string>
<string name="plan_route_create_new_route">Yeni güzergah oluştur</string> <string name="plan_route_create_new_route">Yeni güzergah oluştur</string>
<string name="plan_route_select_track_file_for_open">Açmak için bir yol dosyası seçin.</string> <string name="plan_route_select_track_file_for_open">Açmak için bir yol dosyası seçin.</string>
<string name="shared_string_done">Bitti</string> <string name="shared_string_done">Bitti</string>
@ -3968,7 +3968,7 @@
<string name="select_folder">Klasör seç</string> <string name="select_folder">Klasör seç</string>
<string name="select_folder_descr">Klasör seçin veya yeni bir tane ekleyin</string> <string name="select_folder_descr">Klasör seçin veya yeni bir tane ekleyin</string>
<string name="shared_string_empty">Boş</string> <string name="shared_string_empty">Boş</string>
<string name="analyze_by_intervals">Aralıklara göre analiz et (bölme aralığı)</string> <string name="analyze_by_intervals">Bölünmüş aralıkları analiz et</string>
<string name="upload_to_openstreetmap">OpenStreetMap\'e yükle</string> <string name="upload_to_openstreetmap">OpenStreetMap\'e yükle</string>
<string name="edit_track">Yolu düzenle</string> <string name="edit_track">Yolu düzenle</string>
<string name="rename_track">Yolu yeniden adlandır</string> <string name="rename_track">Yolu yeniden adlandır</string>
@ -4012,4 +4012,26 @@
<string name="uploading_count">%1$d / %2$d karşıya yükleniyor</string> <string name="uploading_count">%1$d / %2$d karşıya yükleniyor</string>
<string name="uploaded_count">%1$d / %2$d karşıya yüklendi</string> <string name="uploaded_count">%1$d / %2$d karşıya yüklendi</string>
<string name="toast_select_edits_for_upload">Karşıya yüklenecek düzenlemeleri seçin</string> <string name="toast_select_edits_for_upload">Karşıya yüklenecek düzenlemeleri seçin</string>
<string name="hillshade_slope_contour_lines">tepe gölgesi / yamaç / eş yükselti eğrileri</string>
<string name="open_place_reviews_plugin_description">OpenPlaceReviews, restoranlar, oteller, müzeler, ara noktalar gibi halka açık yerler hakkında topluluk tarafından yürütülen bir projedir. Fotoğraflar, yorumlar, OpenStreetMap, Wikipedia gibi diğer sistemlere bağlantılar gibi onlar hakkındaki tüm halka açık bilgileri toplar.
\n
\nTüm OpenPlaceReview verileri açık ve herkes tarafından kullanılabilir: http://openplacereviews.org/data
\n
\nDaha fazlasını şu adresten okuyabilirsiniz: http://openplacereviews.org</string>
<string name="open_place_reviews">OpenPlaceReviews</string>
<string name="opr_use_dev_url">test.openplacereviews.org adresini kullan</string>
<string name="login_open_place_reviews">OpenPlaceReviews\'te oturum aç</string>
<string name="activity_type_water_name">Su</string>
<string name="activity_type_winter_name">Kış</string>
<string name="activity_type_snowmobile_name">Kar arabası</string>
<string name="activity_type_riding_name">Binme</string>
<string name="activity_type_racing_name">Yarış</string>
<string name="activity_type_mountainbike_name">Dağ bisikleti</string>
<string name="activity_type_cycling_name">Bisiklet sürme</string>
<string name="activity_type_hiking_name">Yürüyüş</string>
<string name="activity_type_running_name">Koşma</string>
<string name="activity_type_walking_name">Yürüme</string>
<string name="activity_type_offroad_name">Arazi</string>
<string name="activity_type_motorbike_name">Motosiklet</string>
<string name="activity_type_car_name">Araba</string>
</resources> </resources>

View file

@ -2663,7 +2663,7 @@
<string name="shared_string_travel_book">旅游书</string> <string name="shared_string_travel_book">旅游书</string>
<string name="download_images">下载图片</string> <string name="download_images">下载图片</string>
<string name="rendering_value_black_name">黑色</string> <string name="rendering_value_black_name">黑色</string>
<string name="rendering_attr_surface_wood_name"></string> <string name="rendering_attr_surface_wood_name"></string>
<string name="app_mode_subway">地铁</string> <string name="app_mode_subway">地铁</string>
<string name="app_mode_horse">骑马</string> <string name="app_mode_horse">骑马</string>
<string name="shared_string_color_magenta">品红色</string> <string name="shared_string_color_magenta">品红色</string>
@ -2674,7 +2674,7 @@
<string name="points_of_interests">兴趣点POI</string> <string name="points_of_interests">兴趣点POI</string>
<string name="shared_string_capacity">容量</string> <string name="shared_string_capacity">容量</string>
<string name="rendering_attr_surface_metal_name">金属</string> <string name="rendering_attr_surface_metal_name">金属</string>
<string name="rendering_attr_highway_class_path_name">路径</string> <string name="rendering_attr_highway_class_path_name">走道</string>
<string name="app_mode_helicopter">直升机</string> <string name="app_mode_helicopter">直升机</string>
<string name="app_mode_skiing">滑雪</string> <string name="app_mode_skiing">滑雪</string>
<string name="base_profile_descr_ski">滑雪</string> <string name="base_profile_descr_ski">滑雪</string>
@ -2839,7 +2839,7 @@
<string name="show_closed_notes">显示关闭的注记</string> <string name="show_closed_notes">显示关闭的注记</string>
<string name="osm_edit_closed_note">关闭的OSM注记</string> <string name="osm_edit_closed_note">关闭的OSM注记</string>
<string name="add_online_source">添加在线资源</string> <string name="add_online_source">添加在线资源</string>
<string name="rendering_attr_highway_class_bridleway_name"/> <string name="rendering_attr_highway_class_bridleway_name">驮道</string>
<string name="rendering_attr_surface_gravel_name">砾石</string> <string name="rendering_attr_surface_gravel_name">砾石</string>
<string name="rendering_attr_surface_sett_name">比利时石砌路</string> <string name="rendering_attr_surface_sett_name">比利时石砌路</string>
<string name="routing_attr_allow_expert_name">允许专家路线</string> <string name="routing_attr_allow_expert_name">允许专家路线</string>
@ -3124,4 +3124,79 @@
<string name="context_menu_item_add_waypoint">添加轨迹航点</string> <string name="context_menu_item_add_waypoint">添加轨迹航点</string>
<string name="save_track_to_gpx_globally">将轨迹记录到GPX文件</string> <string name="save_track_to_gpx_globally">将轨迹记录到GPX文件</string>
<string name="disable_recording_once_app_killed_descrp">当应用程序被杀死时跟踪日志将被暂停通过最近的应用程序OsmAnd背景指示会从Android通知栏中消失</string> <string name="disable_recording_once_app_killed_descrp">当应用程序被杀死时跟踪日志将被暂停通过最近的应用程序OsmAnd背景指示会从Android通知栏中消失</string>
<string name="add_online_routing_engine">添加在线路线引擎</string>
<string name="edit_online_routing_engine">编辑在线路线引擎</string>
<string name="shared_string_subtype">子类型</string>
<string name="shared_string_vehicle">车辆</string>
<string name="shared_string_api_key">API 密钥</string>
<string name="shared_string_server_url">服务器 URL</string>
<string name="shared_string_enter_param">输入参数</string>
<string name="keep_it_empty_if_not">否则请保持空白</string>
<string name="test_route_calculation">测试路线计算</string>
<string name="routing_engine_vehicle_type_driving">驾驶</string>
<string name="routing_engine_vehicle_type_car">汽车</string>
<string name="copy_address">复制地址</string>
<string name="online_routing_engine">在线路线引擎</string>
<string name="online_routing_engines">在线路线引擎</string>
<string name="shared_string_folders">文件夹</string>
<string name="select_folder">选择文件夹</string>
<string name="select_folder_descr">选择文件夹或添加新文件夹</string>
<string name="upload_to_openstreetmap">上传到 OpenStreetMap</string>
<string name="edit_track">编辑轨迹</string>
<string name="rename_track">重命名轨迹</string>
<string name="change_folder">更改文件夹</string>
<string name="shared_string_sec"></string>
<string name="announcement_time_passing">通过</string>
<string name="announcement_time_prepare_long">长时间准备</string>
<string name="announcement_time_prepare">准备</string>
<string name="announcement_time_off_route">偏离路线</string>
<string name="announcement_time_arrive">到达目的地</string>
<string name="shared_string_turn">转弯</string>
<string name="announcement_time_intervals">时间和距离间隔</string>
<string name="announcement_time_descr">不同语音提示的公告时间取决于提示类型、当前导航速度和默认导航速度。</string>
<string name="announcement_time_title">公告时间</string>
<string name="start_recording">开始录制</string>
<string name="show_track_on_map">在地图上显示轨迹</string>
<string name="routing_engine_vehicle_type_wheelchair">轮椅</string>
<string name="routing_engine_vehicle_type_hiking">徒步</string>
<string name="routing_engine_vehicle_type_walking">步行</string>
<string name="routing_engine_vehicle_type_cycling_electric">电动自行车</string>
<string name="routing_engine_vehicle_type_cycling_mountain">山地自行车</string>
<string name="routing_engine_vehicle_type_cycling_road">公路自行车</string>
<string name="routing_engine_vehicle_type_hgv">重型货车</string>
<string name="routing_engine_vehicle_type_small_truck">小型卡车</string>
<string name="routing_engine_vehicle_type_truck">卡车</string>
<string name="routing_engine_vehicle_type_scooter">踏板车</string>
<string name="routing_engine_vehicle_type_racingbike">竞速自行车</string>
<string name="routing_engine_vehicle_type_mtb">山地车</string>
<string name="message_server_error">服务器错误:%1$s</string>
<string name="delete_online_routing_engine">删除这个在线路线引擎?</string>
<string name="message_name_is_already_exists">名字已经存在</string>
<string name="context_menu_read_full">阅读全文</string>
<string name="context_menu_edit_descr">编辑描述</string>
<string name="delete_waypoints">删除航点</string>
<string name="copy_to_map_markers">复制到地图标记</string>
<string name="copy_to_map_favorites">复制到收藏</string>
<string name="upload_photo">上传中</string>
<string name="upload_photo_completed">上传完成</string>
<string name="uploading_count">正在上传 %1$d共 %2$d</string>
<string name="toast_select_edits_for_upload">选择要上传的编辑</string>
<string name="uploaded_count">已上传 %1$d共 %2$d</string>
<string name="hillshade_slope_contour_lines">山体阴影/斜坡/等高线</string>
<string name="open_place_reviews_plugin_description">OpenPlaceReviews 是一个社区驱动的项目,关于公共场所,如餐馆,酒店,博物馆,航点。它收集了所有关于它们的公共信息,如照片、评论、链接到其他系统的 OpenStreetMap、维基百科。
\n
\n所有 OpenPlaceReview 的数据都是开放的所有人都可以使用http://openplacereviews.org/data。
\n
\n你可以在以下网站阅读更多信息http://openplacereviews.org</string>
<string name="open_place_reviews">OpenPlaceReviews</string>
<string name="opr_use_dev_url">使用 test.openplacereviews.org</string>
<string name="login_open_place_reviews">登录 OpenPlaceReviews</string>
<string name="activity_type_winter_name">冬季</string>
<string name="activity_type_snowmobile_name">雪地摩托</string>
<string name="activity_type_riding_name">骑行</string>
<string name="activity_type_cycling_name">骑车</string>
<string name="activity_type_hiking_name">健行</string>
<string name="activity_type_running_name">跑步</string>
<string name="activity_type_walking_name">步行</string>
<string name="activity_type_motorbike_name">摩托车</string>
</resources> </resources>

View file

@ -36,6 +36,7 @@ import net.osmand.data.LatLon;
import net.osmand.data.QuadRect; import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox; import net.osmand.data.RotatedTileBox;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
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.UiUtilities; import net.osmand.plus.UiUtilities;
@ -66,6 +67,8 @@ public class TrackDetailsMenu {
@Nullable @Nullable
private GpxDisplayItem gpxItem; private GpxDisplayItem gpxItem;
@Nullable @Nullable
private SelectedGpxFile selectedGpxFile;
@Nullable
private TrackDetailsBarController toolbarController; private TrackDetailsBarController toolbarController;
@Nullable @Nullable
private TrkSegment segment; private TrkSegment segment;
@ -101,6 +104,15 @@ public class TrackDetailsMenu {
this.gpxItem = gpxItem; this.gpxItem = gpxItem;
} }
@Nullable
public SelectedGpxFile getSelectedGpxFile() {
return selectedGpxFile;
}
public void setSelectedGpxFile(@NonNull SelectedGpxFile selectedGpxFile) {
this.selectedGpxFile = selectedGpxFile;
}
public boolean isVisible() { public boolean isVisible() {
return visible; return visible;
} }
@ -539,7 +551,7 @@ public class TrackDetailsMenu {
} }
} }
public boolean shouldShowXAxisPoints () { public boolean shouldShowXAxisPoints() {
return true; return true;
} }
@ -707,18 +719,19 @@ public class TrackDetailsMenu {
if (gpxItem.chartTypes != null && gpxItem.chartTypes.length > 0) { if (gpxItem.chartTypes != null && gpxItem.chartTypes.length > 0) {
for (int i = 0; i < gpxItem.chartTypes.length; i++) { for (int i = 0; i < gpxItem.chartTypes.length; i++) {
OrderedLineDataSet dataSet = null; OrderedLineDataSet dataSet = null;
boolean withoutGaps = selectedGpxFile != null && (!selectedGpxFile.isJoinSegments() && gpxItem.isGeneralTrack());
switch (gpxItem.chartTypes[i]) { switch (gpxItem.chartTypes[i]) {
case ALTITUDE: case ALTITUDE:
dataSet = GpxUiHelper.createGPXElevationDataSet(app, chart, analysis, dataSet = GpxUiHelper.createGPXElevationDataSet(app, chart, analysis,
gpxItem.chartAxisType, false, true, false); gpxItem.chartAxisType, false, true, withoutGaps);
break; break;
case SPEED: case SPEED:
dataSet = GpxUiHelper.createGPXSpeedDataSet(app, chart, analysis, dataSet = GpxUiHelper.createGPXSpeedDataSet(app, chart, analysis,
gpxItem.chartAxisType, gpxItem.chartTypes.length > 1, true, false); gpxItem.chartAxisType, gpxItem.chartTypes.length > 1, true, withoutGaps);
break; break;
case SLOPE: case SLOPE:
dataSet = GpxUiHelper.createGPXSlopeDataSet(app, chart, analysis, dataSet = GpxUiHelper.createGPXSlopeDataSet(app, chart, analysis,
gpxItem.chartAxisType, null, gpxItem.chartTypes.length > 1, true, false); gpxItem.chartAxisType, null, gpxItem.chartTypes.length > 1, true, withoutGaps);
break; break;
} }
if (dataSet != null) { if (dataSet != null) {

View file

@ -1,10 +1,10 @@
package net.osmand.plus.track; package net.osmand.plus.track;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.ColorInt; import androidx.annotation.ColorInt;
@ -12,21 +12,19 @@ import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.AppCompatImageView;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.GPXTrackAnalysis; import net.osmand.GPXUtilities.GPXTrackAnalysis;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
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.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType; import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
import net.osmand.plus.myplaces.SegmentActionsListener; import net.osmand.plus.myplaces.SegmentActionsListener;
import net.osmand.plus.widgets.TextViewEx; import net.osmand.plus.widgets.TextViewEx;
@ -40,101 +38,134 @@ public class GpxBlockStatisticsBuilder {
private final OsmandApplication app; private final OsmandApplication app;
private RecyclerView blocksView; private RecyclerView blocksView;
private final SelectedGpxFile selectedGpxFile; private final SelectedGpxFile selectedGpxFile;
private final TrackDisplayHelper displayHelper;
private final GpxDisplayItemType[] filterTypes = {GpxDisplayItemType.TRACK_SEGMENT};
public GpxBlockStatisticsBuilder(OsmandApplication app, SelectedGpxFile selectedGpxFile, TrackDisplayHelper displayHelper) { private BlockStatisticsAdapter adapter;
private final List<StatBlock> items = new ArrayList<>();
private final Handler handler = new Handler();
private Runnable updatingItems;
private boolean updateRunning = false;
public GpxBlockStatisticsBuilder(OsmandApplication app, SelectedGpxFile selectedGpxFile) {
this.app = app; this.app = app;
this.selectedGpxFile = selectedGpxFile; this.selectedGpxFile = selectedGpxFile;
this.displayHelper = displayHelper;
} }
public void setBlocksView(RecyclerView blocksView) { public void setBlocksView(RecyclerView blocksView) {
this.blocksView = blocksView; this.blocksView = blocksView;
} }
private GPXTrackAnalysis getAnalysis() { private GpxDisplayItem getDisplayItem(GPXFile gpxFile) {
return selectedGpxFile.getTrackAnalysis(app); return GpxUiHelper.makeGpxDisplayItem(app, gpxFile);
}
private GPXFile getGPXFile() {
return selectedGpxFile.getGpxFile();
} }
public void initStatBlocks(SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) { public void initStatBlocks(SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) {
GPXTrackAnalysis analysis = getAnalysis(); initItems();
float totalDistance = analysis.totalDistance; boolean isNotEmpty = !Algorithms.isEmpty(items);
float timeSpan = analysis.timeSpan; AndroidUiHelper.updateVisibility(blocksView, isNotEmpty);
String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app); if (isNotEmpty) {
String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app); adapter = new BlockStatisticsAdapter(getDisplayItem(getGPXFile()), actionsListener, activeColor, nightMode);
String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app); adapter.setItems(items);
String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app);
List<StatBlock> items = new ArrayList<>();
prepareData(analysis, items, app.getString(R.string.distance), OsmAndFormatter.getFormattedDistance(totalDistance, app),
R.drawable.ic_action_track_16, R.color.icon_color_default_light, GPXDataSetType.ALTITUDE, GPXDataSetType.SPEED, ItemType.ITEM_DISTANCE);
prepareData(analysis, items, app.getString(R.string.altitude_ascent), asc,
R.drawable.ic_action_arrow_up_16, R.color.gpx_chart_red, GPXDataSetType.SLOPE, null, ItemType.ITEM_ALTITUDE);
prepareData(analysis, items, app.getString(R.string.altitude_descent), desc,
R.drawable.ic_action_arrow_down_16, R.color.gpx_pale_green, GPXDataSetType.ALTITUDE, GPXDataSetType.SLOPE, ItemType.ITEM_ALTITUDE);
prepareData(analysis, items, app.getString(R.string.average_speed), avg,
R.drawable.ic_action_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED);
prepareData(analysis, items, app.getString(R.string.max_speed), max,
R.drawable.ic_action_max_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED);
prepareData(analysis, items, app.getString(R.string.shared_string_time_span),
Algorithms.formatDuration((int) (timeSpan / 1000), app.accessibilityEnabled()),
R.drawable.ic_action_time_span_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_TIME);
if (Algorithms.isEmpty(items)) {
AndroidUiHelper.updateVisibility(blocksView, false);
} else {
final BlockStatisticsAdapter sbAdapter = new BlockStatisticsAdapter(items, actionsListener, activeColor, nightMode);
blocksView.setLayoutManager(new LinearLayoutManager(app, LinearLayoutManager.HORIZONTAL, false)); blocksView.setLayoutManager(new LinearLayoutManager(app, LinearLayoutManager.HORIZONTAL, false));
blocksView.setAdapter(sbAdapter); blocksView.setAdapter(adapter);
} }
} }
public void prepareData(GPXTrackAnalysis analysis, List<StatBlock> listItems, String title, public void stopUpdatingStatBlocks() {
String value, @DrawableRes int imageResId, @ColorRes int imageColorId, handler.removeCallbacks(updatingItems);
updateRunning = false;
}
public void runUpdatingStatBlocks() {
updatingItems = new Runnable() {
@Override
public void run() {
if (adapter != null) {
initItems();
adapter.setItems(items);
AndroidUiHelper.updateVisibility(blocksView, !Algorithms.isEmpty(items));
}
int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get();
handler.postDelayed(this, Math.max(1000, interval));
}
};
updateRunning = handler.post(updatingItems);
}
public void initItems() {
GPXFile gpxFile = getGPXFile();
GpxDisplayItem gpxDisplayItem = null;
GPXTrackAnalysis analysis = null;
boolean withoutGaps = true;
if (gpxFile.tracks.size() > 0) {
gpxDisplayItem = getDisplayItem(gpxFile);
}
if (gpxDisplayItem != null) {
analysis = gpxDisplayItem.analysis;
withoutGaps = !selectedGpxFile.isJoinSegments() && gpxDisplayItem.isGeneralTrack();
}
if (analysis != null) {
float totalDistance = withoutGaps ? analysis.totalDistanceWithoutGaps : analysis.totalDistance;
float timeSpan = withoutGaps ? analysis.timeSpanWithoutGaps : analysis.timeSpan;
String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app);
String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app);
String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app);
String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app);
items.clear();
prepareData(analysis, app.getString(R.string.distance), OsmAndFormatter.getFormattedDistance(totalDistance, app),
R.drawable.ic_action_track_16, R.color.icon_color_default_light, GPXDataSetType.ALTITUDE, GPXDataSetType.SPEED, ItemType.ITEM_DISTANCE);
prepareData(analysis, app.getString(R.string.altitude_ascent), asc,
R.drawable.ic_action_arrow_up_16, R.color.gpx_chart_red, GPXDataSetType.SLOPE, null, ItemType.ITEM_ALTITUDE);
prepareData(analysis, app.getString(R.string.altitude_descent), desc,
R.drawable.ic_action_arrow_down_16, R.color.gpx_pale_green, GPXDataSetType.ALTITUDE, GPXDataSetType.SLOPE, ItemType.ITEM_ALTITUDE);
prepareData(analysis, app.getString(R.string.average_speed), avg,
R.drawable.ic_action_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED);
prepareData(analysis, app.getString(R.string.max_speed), max,
R.drawable.ic_action_max_speed_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_SPEED);
prepareData(analysis, app.getString(R.string.shared_string_time_span),
Algorithms.formatDuration((int) (timeSpan / 1000), app.accessibilityEnabled()),
R.drawable.ic_action_time_span_16, R.color.icon_color_default_light, GPXDataSetType.SPEED, null, ItemType.ITEM_TIME);
}
}
public void prepareData(GPXTrackAnalysis analysis, String title, String value,
@DrawableRes int imageResId, @ColorRes int imageColorId,
GPXDataSetType firstType, GPXDataSetType secondType, ItemType itemType) { GPXDataSetType firstType, GPXDataSetType secondType, ItemType itemType) {
StatBlock statBlock = new StatBlock(title, value, imageResId, imageColorId, firstType, secondType, itemType); StatBlock statBlock = new StatBlock(title, value, imageResId, imageColorId, firstType, secondType, itemType);
switch (statBlock.itemType) { switch (statBlock.itemType) {
case ITEM_DISTANCE: { case ITEM_DISTANCE: {
if (analysis.totalDistance != 0f) { if (analysis.totalDistance != 0f) {
listItems.add(statBlock); items.add(statBlock);
} }
break; break;
} }
case ITEM_ALTITUDE: { case ITEM_ALTITUDE: {
if (analysis.hasElevationData) { if (analysis.hasElevationData) {
listItems.add(statBlock); items.add(statBlock);
} }
break; break;
} }
case ITEM_SPEED: { case ITEM_SPEED: {
if (analysis.isSpeedSpecified()) { if (analysis.isSpeedSpecified()) {
listItems.add(statBlock); items.add(statBlock);
} }
break; break;
} }
case ITEM_TIME: { case ITEM_TIME: {
if (analysis.hasSpeedData) { if (analysis.hasSpeedData) {
listItems.add(statBlock); items.add(statBlock);
} }
break; break;
} }
} }
} }
private void setImageDrawable(ImageView iv, @DrawableRes Integer resId, @ColorRes int color) {
Drawable icon = resId != null ? app.getUIUtilities().getIcon(resId, color)
: UiUtilities.tintDrawable(iv.getDrawable(), getResolvedColor(color));
iv.setImageDrawable(icon);
}
@ColorInt
protected int getResolvedColor(@ColorRes int colorId) {
return ContextCompat.getColor(app, colorId);
}
public class StatBlock { public class StatBlock {
private final String title; private final String title;
private final String value; private final String value;
private final int imageResId; private final int imageResId;
@ -164,14 +195,16 @@ public class GpxBlockStatisticsBuilder {
private class BlockStatisticsAdapter extends RecyclerView.Adapter<BlockStatisticsViewHolder> { private class BlockStatisticsAdapter extends RecyclerView.Adapter<BlockStatisticsViewHolder> {
private final List<StatBlock> items = new ArrayList<>();
private final GpxDisplayItem displayItem;
private final SegmentActionsListener actionsListener;
@ColorInt @ColorInt
private final int activeColor; private final int activeColor;
private final List<StatBlock> statBlocks;
private final boolean nightMode; private final boolean nightMode;
private final SegmentActionsListener actionsListener;
public BlockStatisticsAdapter(List<StatBlock> statBlocks, SegmentActionsListener actionsListener, @ColorInt int activeColor, boolean nightMode) { public BlockStatisticsAdapter(GpxDisplayItem displayItem, SegmentActionsListener actionsListener,
this.statBlocks = statBlocks; @ColorInt int activeColor, boolean nightMode) {
this.displayItem = displayItem;
this.actionsListener = actionsListener; this.actionsListener = actionsListener;
this.activeColor = activeColor; this.activeColor = activeColor;
this.nightMode = nightMode; this.nightMode = nightMode;
@ -179,7 +212,7 @@ public class GpxBlockStatisticsBuilder {
@Override @Override
public int getItemCount() { public int getItemCount() {
return statBlocks.size(); return items.size();
} }
@NonNull @NonNull
@ -192,46 +225,44 @@ public class GpxBlockStatisticsBuilder {
@Override @Override
public void onBindViewHolder(BlockStatisticsViewHolder holder, int position) { public void onBindViewHolder(BlockStatisticsViewHolder holder, int position) {
final StatBlock item = statBlocks.get(position); final StatBlock item = items.get(position);
holder.valueText.setText(item.value); holder.valueText.setText(item.value);
holder.titleText.setText(item.title); holder.titleText.setText(item.title);
if (updateRunning) {
holder.titleText.setWidth(app.getResources().getDimensionPixelSize(R.dimen.map_route_buttons_width));
}
holder.valueText.setTextColor(activeColor); holder.valueText.setTextColor(activeColor);
holder.titleText.setTextColor(app.getResources().getColor(R.color.text_color_secondary_light)); holder.titleText.setTextColor(app.getResources().getColor(R.color.text_color_secondary_light));
holder.itemView.setOnClickListener(new View.OnClickListener() { holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
List<GpxDisplayGroup> groups = displayHelper.getDisplayGroups(filterTypes); GPXTrackAnalysis analysis = displayItem != null ? displayItem.analysis : null;
GpxDisplayGroup group = null; if (analysis != null) {
for (GpxDisplayGroup g : groups) { ArrayList<GPXDataSetType> list = new ArrayList<>();
if (g.isGeneralTrack()) { if (analysis.hasElevationData || analysis.isSpeedSpecified() || analysis.hasSpeedData) {
group = g; if (item.firstType != null) {
} list.add(item.firstType);
} }
if (group == null && !groups.isEmpty()) { if (item.secondType != null) {
group = groups.get(0); list.add(item.secondType);
}
if (group != null) {
GpxDisplayItem displayItem = group.getModifiableList().get(0);
if (displayItem != null && displayItem.analysis != null) {
ArrayList<GPXDataSetType> list = new ArrayList<>();
if (displayItem.analysis.hasElevationData || displayItem.analysis.isSpeedSpecified() || displayItem.analysis.hasSpeedData) {
if (item.firstType != null) {
list.add(item.firstType);
}
if (item.secondType != null) {
list.add(item.secondType);
}
} }
displayItem.chartTypes = list.size() > 0 ? list.toArray(new GPXDataSetType[0]) : null;
displayItem.locationOnMap = displayItem.locationStart;
actionsListener.openAnalyzeOnMap(displayItem);
} }
displayItem.chartTypes = list.size() > 0 ? list.toArray(new GPXDataSetType[0]) : null;
displayItem.locationOnMap = displayItem.locationStart;
actionsListener.openAnalyzeOnMap(displayItem);
} }
} }
}); });
setImageDrawable(holder.imageView, item.imageResId, item.imageColorId); Drawable icon = app.getUIUtilities().getIcon(item.imageResId, item.imageColorId);
holder.imageView.setImageDrawable(icon);
AndroidUtils.setBackgroundColor(app, holder.divider, nightMode, R.color.divider_color_light, R.color.divider_color_dark); AndroidUtils.setBackgroundColor(app, holder.divider, nightMode, R.color.divider_color_light, R.color.divider_color_dark);
AndroidUiHelper.updateVisibility(holder.divider, position != statBlocks.size() - 1); AndroidUiHelper.updateVisibility(holder.divider, position != items.size() - 1);
}
public void setItems(List<StatBlock> items) {
this.items.clear();
this.items.addAll(items);
notifyDataSetChanged();
} }
} }

View file

@ -43,12 +43,11 @@ public class OverviewCard extends BaseCard {
private final SelectedGpxFile selectedGpxFile; private final SelectedGpxFile selectedGpxFile;
private final GpxBlockStatisticsBuilder blockStatisticsBuilder; private final GpxBlockStatisticsBuilder blockStatisticsBuilder;
public OverviewCard(@NonNull MapActivity mapActivity, @NonNull TrackDisplayHelper displayHelper, public OverviewCard(@NonNull MapActivity mapActivity, @NonNull SegmentActionsListener actionsListener, SelectedGpxFile selectedGpxFile) {
@NonNull SegmentActionsListener actionsListener, SelectedGpxFile selectedGpxFile) {
super(mapActivity); super(mapActivity);
this.actionsListener = actionsListener; this.actionsListener = actionsListener;
this.selectedGpxFile = selectedGpxFile; this.selectedGpxFile = selectedGpxFile;
blockStatisticsBuilder = new GpxBlockStatisticsBuilder(app, selectedGpxFile, displayHelper); blockStatisticsBuilder = new GpxBlockStatisticsBuilder(app, selectedGpxFile);
} }
@Override @Override

View file

@ -326,7 +326,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
} }
headerContainer.addView(overviewCard.getView()); headerContainer.addView(overviewCard.getView());
} else { } else {
overviewCard = new OverviewCard(getMapActivity(), displayHelper, this, selectedGpxFile); overviewCard = new OverviewCard(getMapActivity(), this, selectedGpxFile);
overviewCard.setListener(this); overviewCard.setListener(this);
headerContainer.addView(overviewCard.build(getMapActivity())); headerContainer.addView(overviewCard.build(getMapActivity()));
} }
@ -760,7 +760,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
segment = segments.get(0); segment = segments.get(0);
} }
} }
GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_SEGMENT}; GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[]{GpxDisplayItemType.TRACK_SEGMENT};
List<GpxDisplayItem> items = TrackDisplayHelper.flatten(displayHelper.getOriginalGroups(filterTypes)); List<GpxDisplayItem> items = TrackDisplayHelper.flatten(displayHelper.getOriginalGroups(filterTypes));
if (segment != null && !Algorithms.isEmpty(items)) { if (segment != null && !Algorithms.isEmpty(items)) {
SplitSegmentDialogFragment.showInstance(fragmentManager, displayHelper, items.get(0), segment); SplitSegmentDialogFragment.showInstance(fragmentManager, displayHelper, items.get(0), segment);
@ -1013,6 +1013,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
public void openAnalyzeOnMap(GpxDisplayItem gpxItem) { public void openAnalyzeOnMap(GpxDisplayItem gpxItem) {
TrackDetailsMenu trackDetailsMenu = getMapActivity().getTrackDetailsMenu(); TrackDetailsMenu trackDetailsMenu = getMapActivity().getTrackDetailsMenu();
trackDetailsMenu.setGpxItem(gpxItem); trackDetailsMenu.setGpxItem(gpxItem);
trackDetailsMenu.setSelectedGpxFile(selectedGpxFile);
trackDetailsMenu.show(); trackDetailsMenu.show();
hide(); hide();
} }
@ -1110,7 +1111,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
@Override @Override
public void gpxSavingFinished(Exception errorMessage) { public void gpxSavingFinished(Exception errorMessage) {
if (selectedGpxFile != null) { if (selectedGpxFile != null) {
List<GpxDisplayGroup> groups = displayHelper.getDisplayGroups(new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_SEGMENT}); List<GpxDisplayGroup> groups = displayHelper.getDisplayGroups(new GpxDisplayItemType[]{GpxDisplayItemType.TRACK_SEGMENT});
selectedGpxFile.setDisplayGroups(groups, app); selectedGpxFile.setDisplayGroups(groups, app);
selectedGpxFile.processPoints(app); selectedGpxFile.processPoints(app);
} }

View file

@ -169,6 +169,26 @@ public class TravelArticle {
return new String[]{md5.substring(0, 1), md5.substring(0, 2)}; return new String[]{md5.substring(0, 1), md5.substring(0, 2)};
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
TravelArticle that = (TravelArticle) o;
return TravelArticleIdentifier.areLatLonEqual(that.lat, that.lon, lat, lon) &&
Algorithms.objectEquals(file, that.file) &&
Algorithms.stringsEqual(routeId, that.routeId) &&
Algorithms.stringsEqual(routeSource, that.routeSource);
}
@Override
public int hashCode() {
return Algorithms.hash(file, lat, lon, routeId, routeSource);
}
public static class TravelArticleIdentifier implements Parcelable { public static class TravelArticleIdentifier implements Parcelable {
@Nullable File file; @Nullable File file;
double lat; double lat;
@ -249,7 +269,7 @@ public class TravelArticle {
return Algorithms.hash(file, lat, lon, routeId, routeSource); return Algorithms.hash(file, lat, lon, routeId, routeSource);
} }
private static boolean areLatLonEqual(double lat1, double lon1, double lat2, double lon2) { public static boolean areLatLonEqual(double lat1, double lon1, double lat2, double lon2) {
boolean latEqual = (Double.isNaN(lat1) && Double.isNaN(lat2)) || Math.abs(lat1 - lat2) < 0.00001; boolean latEqual = (Double.isNaN(lat1) && Double.isNaN(lat2)) || Math.abs(lat1 - lat2) < 0.00001;
boolean lonEqual = (Double.isNaN(lon1) && Double.isNaN(lon2)) || Math.abs(lon1 - lon2) < 0.00001; boolean lonEqual = (Double.isNaN(lon1) && Double.isNaN(lon2)) || Math.abs(lon1 - lon2) < 0.00001;
return latEqual && lonEqual; return latEqual && lonEqual;

View file

@ -174,7 +174,7 @@ public class TravelDbHelper implements TravelHelper {
} }
@Override @Override
public void initializeDataToDisplay() { public void initializeDataToDisplay(boolean resetData) {
localDataHelper.refreshCachedData(); localDataHelper.refreshCachedData();
loadPopularArticles(); loadPopularArticles();
} }
@ -292,7 +292,7 @@ public class TravelDbHelper implements TravelHelper {
} }
String LANG_WHERE = " WHERE " + ARTICLES_COL_LANG + " = '" + language + "'"; String LANG_WHERE = " WHERE " + ARTICLES_COL_LANG + " = '" + language + "'";
SQLiteCursor cursor = conn.rawQuery(POP_ARTICLES_TABLE_SELECT + LANG_WHERE, null); SQLiteCursor cursor = conn.rawQuery(POP_ARTICLES_TABLE_SELECT + LANG_WHERE, null);
if(cursor == null) { if (cursor == null) {
return popularArticles; return popularArticles;
} }
// read popular articles // read popular articles
@ -549,13 +549,13 @@ public class TravelDbHelper implements TravelHelper {
@Override @Override
@Nullable @Nullable
public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @NonNull String lang, boolean readGpx, @Nullable GpxReadCallback callback) { public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @Nullable String lang, boolean readGpx, @Nullable GpxReadCallback callback) {
TravelArticle res = null; TravelArticle res = null;
SQLiteConnection conn = openConnection(); SQLiteConnection conn = openConnection();
String routeId = articleId.routeId; String routeId = articleId.routeId;
if (conn != null && !Algorithms.isEmpty(routeId)) { if (conn != null && !Algorithms.isEmpty(routeId) && lang != null) {
SQLiteCursor cursor = conn.rawQuery(ARTICLES_TABLE_SELECT + " WHERE " + ARTICLES_COL_TRIP_ID + " = ? AND " SQLiteCursor cursor = conn.rawQuery(ARTICLES_TABLE_SELECT + " WHERE " + ARTICLES_COL_TRIP_ID + " = ? AND "
+ ARTICLES_COL_LANG + " = ?", new String[] { routeId, lang }); + ARTICLES_COL_LANG + " = ?", new String[]{routeId, lang});
if (cursor != null) { if (cursor != null) {
if (cursor.moveToFirst()) { if (cursor.moveToFirst()) {
res = readArticle(cursor); res = readArticle(cursor);

View file

@ -3,7 +3,6 @@ package net.osmand.plus.wikivoyage.data;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXFile;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.QuadRect; import net.osmand.data.QuadRect;
@ -18,6 +17,7 @@ public interface TravelHelper {
interface GpxReadCallback { interface GpxReadCallback {
void onGpxFileReading(); void onGpxFileReading();
void onGpxFileRead(@Nullable GPXFile gpxFile); void onGpxFileRead(@Nullable GPXFile gpxFile);
} }
@ -25,7 +25,7 @@ public interface TravelHelper {
void initializeDataOnAppStartup(); void initializeDataOnAppStartup();
void initializeDataToDisplay(); void initializeDataToDisplay(boolean resetData);
boolean isAnyTravelBookPresent(); boolean isAnyTravelBookPresent();
@ -39,7 +39,7 @@ public interface TravelHelper {
Map<WikivoyageSearchResult, List<WikivoyageSearchResult>> getNavigationMap(@NonNull TravelArticle article); Map<WikivoyageSearchResult, List<WikivoyageSearchResult>> getNavigationMap(@NonNull TravelArticle article);
@Nullable @Nullable
TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @NonNull String lang, boolean readGpx, @Nullable GpxReadCallback callback); TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @Nullable String lang, boolean readGpx, @Nullable GpxReadCallback callback);
@Nullable @Nullable
TravelArticle getArticleByTitle(@NonNull String title, @NonNull String lang, boolean readGpx, @Nullable GpxReadCallback callback); TravelArticle getArticleByTitle(@NonNull String title, @NonNull String lang, boolean readGpx, @Nullable GpxReadCallback callback);

View file

@ -69,9 +69,7 @@ public class TravelObfHelper implements TravelHelper {
public static final String ROUTE_ARTICLE = "route_article"; public static final String ROUTE_ARTICLE = "route_article";
public static final String ROUTE_ARTICLE_POINT = "route_article_point"; public static final String ROUTE_ARTICLE_POINT = "route_article_point";
public static final String ROUTE_TRACK = "route_track"; public static final String ROUTE_TRACK = "route_track";
public static final int POPULAR_ARTICLES_SEARCH_RADIUS = 100000;
public static final int ARTICLE_SEARCH_RADIUS = 50000; public static final int ARTICLE_SEARCH_RADIUS = 50000;
public static final int GPX_TRACKS_SEARCH_RADIUS = 10000;
public static final int MAX_POPULAR_ARTICLES_COUNT = 30; public static final int MAX_POPULAR_ARTICLES_COUNT = 30;
public static final String REF_TAG = "ref"; public static final String REF_TAG = "ref";
public static final String NAME_TAG = "name"; public static final String NAME_TAG = "name";
@ -82,6 +80,9 @@ public class TravelObfHelper implements TravelHelper {
private List<TravelArticle> popularArticles = new ArrayList<>(); private List<TravelArticle> popularArticles = new ArrayList<>();
private final Map<TravelArticleIdentifier, Map<String, TravelArticle>> cachedArticles = new ConcurrentHashMap<>(); private final Map<TravelArticleIdentifier, Map<String, TravelArticle>> cachedArticles = new ConcurrentHashMap<>();
private final TravelLocalDataHelper localDataHelper; private final TravelLocalDataHelper localDataHelper;
private int searchRadius = ARTICLE_SEARCH_RADIUS;
private int foundAmenitiesIndex = 0;
private final List<Pair<File, Amenity>> foundAmenities = new ArrayList<>();
public TravelObfHelper(OsmandApplication app) { public TravelObfHelper(OsmandApplication app) {
this.app = app; this.app = app;
@ -99,7 +100,13 @@ public class TravelObfHelper implements TravelHelper {
} }
@Override @Override
public void initializeDataToDisplay() { public void initializeDataToDisplay(boolean resetData) {
if (resetData) {
foundAmenities.clear();
foundAmenitiesIndex = 0;
popularArticles.clear();
searchRadius = ARTICLE_SEARCH_RADIUS;
}
localDataHelper.refreshCachedData(); localDataHelper.refreshCachedData();
loadPopularArticles(); loadPopularArticles();
} }
@ -107,38 +114,47 @@ public class TravelObfHelper implements TravelHelper {
@NonNull @NonNull
public synchronized List<TravelArticle> loadPopularArticles() { public synchronized List<TravelArticle> loadPopularArticles() {
String lang = app.getLanguage(); String lang = app.getLanguage();
List<TravelArticle> popularArticles = new ArrayList<>(); List<TravelArticle> popularArticles = new ArrayList<>(this.popularArticles);
final List<Pair<File, Amenity>> amenities = new ArrayList<>(); if (foundAmenities.size() - foundAmenitiesIndex < MAX_POPULAR_ARTICLES_COUNT) {
final LatLon location = app.getMapViewTrackingUtilities().getMapLocation(); final LatLon location = app.getMapViewTrackingUtilities().getMapLocation();
for (final BinaryMapIndexReader reader : getReaders()) { for (final BinaryMapIndexReader reader : getReaders()) {
try { try {
searchAmenity(amenities, location, reader, POPULAR_ARTICLES_SEARCH_RADIUS, -1, ROUTE_ARTICLE); searchAmenity(foundAmenities, location, reader, searchRadius, -1, ROUTE_ARTICLE);
searchAmenity(amenities, location, reader, GPX_TRACKS_SEARCH_RADIUS, 15, ROUTE_TRACK); searchAmenity(foundAmenities, location, reader, searchRadius / 5, 15, ROUTE_TRACK);
} catch (Exception e) { } catch (Exception e) {
LOG.error(e.getMessage(), e); LOG.error(e.getMessage(), e);
}
} }
if (foundAmenities.size() > 0) {
Collections.sort(foundAmenities, new Comparator<Pair<File, Amenity>>() {
@Override
public int compare(Pair article1, Pair article2) {
Amenity amenity1 = (Amenity) article1.second;
double d1 = MapUtils.getDistance(amenity1.getLocation(), location)
/ (ROUTE_ARTICLE.equals(amenity1.getSubType()) ? 5 : 1);
Amenity amenity2 = (Amenity) article2.second;
double d2 = MapUtils.getDistance(amenity2.getLocation(), location)
/ (ROUTE_ARTICLE.equals(amenity2.getSubType()) ? 5 : 1);
return Double.compare(d1, d2);
}
});
}
searchRadius *= 2;
} }
if (amenities.size() > 0) { int pagesCount = popularArticles.size() / MAX_POPULAR_ARTICLES_COUNT;
Collections.sort(amenities, new Comparator<Pair<File, Amenity>>() { while (foundAmenitiesIndex < foundAmenities.size() - 1) {
@Override Pair<File, Amenity> amenity = foundAmenities.get(foundAmenitiesIndex);
public int compare(Pair article1, Pair article2) { if (!Algorithms.isEmpty(amenity.second.getName(lang))) {
int d1 = (int) (MapUtils.getDistance(((Amenity) article1.second).getLocation(), location)); TravelArticle article = cacheTravelArticles(amenity.first, amenity.second, lang, false, null);
int d2 = (int) (MapUtils.getDistance(((Amenity) article2.second).getLocation(), location)); if (article != null && !popularArticles.contains(article)) {
return d1 < d2 ? -1 : (d1 == d2 ? 0 : 1); popularArticles.add(article);
} if (popularArticles.size() >= (pagesCount + 1) * MAX_POPULAR_ARTICLES_COUNT) {
}); break;
for (Pair<File, Amenity> amenity : amenities) {
if (!Algorithms.isEmpty(amenity.second.getName(lang))) {
TravelArticle article = cacheTravelArticles(amenity.first, amenity.second, lang, false, null);
if (article != null) {
popularArticles.add(article);
if (popularArticles.size() >= MAX_POPULAR_ARTICLES_COUNT) {
break;
}
} }
} }
} }
foundAmenitiesIndex++;
} }
this.popularArticles = popularArticles; this.popularArticles = popularArticles;
return popularArticles; return popularArticles;
@ -616,8 +632,8 @@ public class TravelObfHelper implements TravelHelper {
} }
@Override @Override
public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @NonNull String lang, public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @Nullable String lang,
boolean readGpx, @Nullable GpxReadCallback callback) { boolean readGpx, @Nullable GpxReadCallback callback) {
TravelArticle article = getCachedArticle(articleId, lang, readGpx, callback); TravelArticle article = getCachedArticle(articleId, lang, readGpx, callback);
if (article == null) { if (article == null) {
article = localDataHelper.getSavedArticle(articleId.file, articleId.routeId, lang); article = localDataHelper.getSavedArticle(articleId.file, articleId.routeId, lang);
@ -629,8 +645,8 @@ public class TravelObfHelper implements TravelHelper {
} }
@Nullable @Nullable
private TravelArticle getCachedArticle(@NonNull TravelArticleIdentifier articleId, @NonNull String lang, private TravelArticle getCachedArticle(@NonNull TravelArticleIdentifier articleId, @Nullable String lang,
boolean readGpx, @Nullable GpxReadCallback callback) { boolean readGpx, @Nullable GpxReadCallback callback) {
TravelArticle article = null; TravelArticle article = null;
Map<String, TravelArticle> articles = cachedArticles.get(articleId); Map<String, TravelArticle> articles = cachedArticles.get(articleId);
if (articles != null) { if (articles != null) {

View file

@ -18,8 +18,9 @@ import net.osmand.plus.wikivoyage.explore.travelcards.OpenBetaTravelCard;
import net.osmand.plus.wikivoyage.explore.travelcards.OpenBetaTravelCard.OpenBetaTravelVH; import net.osmand.plus.wikivoyage.explore.travelcards.OpenBetaTravelCard.OpenBetaTravelVH;
import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard;
import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard.StartEditingTravelVH; import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard.StartEditingTravelVH;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelButtonCard;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelButtonCard.TravelButtonVH;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelDownloadUpdateCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelDownloadUpdateCard;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelDownloadUpdateCard.DownloadUpdateVH;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard.TravelGpxVH; import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard.TravelGpxVH;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelNeededMapsCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelNeededMapsCard;
@ -53,12 +54,13 @@ public class ExploreRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
case TravelGpxCard.TYPE: case TravelGpxCard.TYPE:
return new TravelGpxVH(inflate(parent, R.layout.wikivoyage_travel_gpx_card)); return new TravelGpxVH(inflate(parent, R.layout.wikivoyage_travel_gpx_card));
case TravelDownloadUpdateCard.TYPE:
return new DownloadUpdateVH(inflate(parent, R.layout.travel_download_update_card));
case HeaderTravelCard.TYPE: case HeaderTravelCard.TYPE:
return new HeaderTravelVH(inflate(parent, R.layout.wikivoyage_list_header)); return new HeaderTravelVH(inflate(parent, R.layout.wikivoyage_list_header));
case TravelButtonCard.TYPE:
return new TravelButtonVH(inflate(parent, R.layout.wikivoyage_button_card));
case TravelDownloadUpdateCard.TYPE:
case TravelNeededMapsCard.TYPE: case TravelNeededMapsCard.TYPE:
return new NeededMapsVH(inflate(parent, R.layout.travel_needed_maps_card)); return new NeededMapsVH(inflate(parent, R.layout.travel_needed_maps_card));
@ -115,6 +117,9 @@ public class ExploreRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
private int getLastArticleItemIndex() { private int getLastArticleItemIndex() {
for (int i = items.size() - 1; i > 0; i--) { for (int i = items.size() - 1; i > 0; i--) {
BaseTravelCard o = items.get(i); BaseTravelCard o = items.get(i);
if (o instanceof TravelButtonCard) {
return 0;
}
if (o instanceof ArticleTravelCard || o instanceof TravelGpxCard) { if (o instanceof ArticleTravelCard || o instanceof TravelGpxCard) {
return i; return i;
} }
@ -205,7 +210,7 @@ public class ExploreRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
if(onlyProgress) { if(onlyProgress) {
TravelDownloadUpdateCard dc = this.downloadCard; TravelDownloadUpdateCard dc = this.downloadCard;
if(dc != null) { if(dc != null) {
dc.updateProgresBar(); dc.updateView();
} }
return; return;
} }

View file

@ -1,7 +1,6 @@
package net.osmand.plus.wikivoyage.explore; package net.osmand.plus.wikivoyage.explore;
import android.app.Activity; import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.util.Pair; import android.util.Pair;
@ -37,6 +36,7 @@ import net.osmand.plus.wikivoyage.explore.travelcards.BaseTravelCard;
import net.osmand.plus.wikivoyage.explore.travelcards.HeaderTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.HeaderTravelCard;
import net.osmand.plus.wikivoyage.explore.travelcards.OpenBetaTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.OpenBetaTravelCard;
import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelButtonCard;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelDownloadUpdateCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelDownloadUpdateCard;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelNeededMapsCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelNeededMapsCard;
@ -46,6 +46,8 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static net.osmand.plus.wikivoyage.explore.WikivoyageExploreActivity.*;
public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEvents, TravelLocalDataHelper.Listener { public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEvents, TravelLocalDataHelper.Listener {
private static boolean SHOW_TRAVEL_UPDATE_CARD = true; private static boolean SHOW_TRAVEL_UPDATE_CARD = true;
@ -63,9 +65,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
private DownloadValidationManager downloadManager; private DownloadValidationManager downloadManager;
@Nullable @Nullable
private IndexItem currentDownloadingIndexItem; private IndexItem currentDownloadingIndexItem;
@Nullable private final List<IndexItem> mainIndexItems = new ArrayList<>();
private IndexItem mainIndexItem;
private final List<IndexItem> neededIndexItems = new ArrayList<>(); private final List<IndexItem> neededIndexItems = new ArrayList<>();
private boolean waitForIndexes; private boolean waitForIndexes;
@ -175,17 +175,39 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
if (!Version.isPaidVersion(app) && !OpenBetaTravelCard.isClosed()) { if (!Version.isPaidVersion(app) && !OpenBetaTravelCard.isClosed()) {
items.add(new OpenBetaTravelCard(activity, nightMode)); items.add(new OpenBetaTravelCard(activity, nightMode));
} }
List<TravelArticle> popularArticles = app.getTravelHelper().getPopularArticles(); final List<TravelArticle> popularArticles = app.getTravelHelper().getPopularArticles();
if (!popularArticles.isEmpty()) { if (!popularArticles.isEmpty()) {
items.add(new HeaderTravelCard(app, nightMode, getString(R.string.popular_destinations))); items.add(new HeaderTravelCard(app, nightMode, getString(R.string.popular_destinations)));
for (TravelArticle article : popularArticles) { for (TravelArticle article : popularArticles) {
if (article instanceof TravelGpx) { if (article instanceof TravelGpx) {
items.add(new TravelGpxCard(app, nightMode, (TravelGpx) article, getActivity())); items.add(new TravelGpxCard(app, nightMode, (TravelGpx) article, activity));
} else { } else {
items.add(new ArticleTravelCard(app, nightMode, article, activity.getSupportFragmentManager())); items.add(new ArticleTravelCard(app, nightMode, article, activity.getSupportFragmentManager()));
} }
} }
} }
TravelButtonCard travelButtonCard = new TravelButtonCard(app, nightMode);
travelButtonCard.setListener(new TravelNeededMapsCard.CardListener() {
@Override
public void onPrimaryButtonClick() {
if (activity instanceof WikivoyageExploreActivity) {
new LoadWikivoyageData((WikivoyageExploreActivity) activity,false).execute();
}
}
@Override
public void onSecondaryButtonClick() {
}
@Override
public void onIndexItemClick(IndexItem item) {
}
});
items.add(travelButtonCard);
items.add(new StartEditingTravelCard(activity, nightMode)); items.add(new StartEditingTravelCard(activity, nightMode));
adapter.setItems(items); adapter.setItems(items);
final DownloadIndexesThread downloadThread = app.getDownloadThread(); final DownloadIndexesThread downloadThread = app.getDownloadThread();
@ -199,17 +221,24 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
} }
private void removeRedundantCards() { private void removeRedundantCards() {
if (mainIndexItem != null && mainIndexItem.isDownloaded() && !mainIndexItem.isOutdated()) { boolean allTravelGuideDownloaded = true;
removeDownloadUpdateCard(); for (IndexItem item : mainIndexItems) {
}
boolean allMapsDownloaded = true;
for (IndexItem item : neededIndexItems) {
if (!item.isDownloaded()) { if (!item.isDownloaded()) {
allMapsDownloaded = false; allTravelGuideDownloaded = false;
break; break;
} }
} }
if (allMapsDownloaded) { if (allTravelGuideDownloaded) {
removeDownloadUpdateCard();
}
boolean neededMapsDownloaded = true;
for (IndexItem item : neededIndexItems) {
if (!item.isDownloaded()) {
neededMapsDownloaded = false;
break;
}
}
if (neededMapsDownloaded) {
removeNeededMapsCard(); removeNeededMapsCard();
} }
} }
@ -218,8 +247,9 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
new ProcessIndexItemsTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new ProcessIndexItemsTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
private void addIndexItemCards(IndexItem mainIndexItem, List<IndexItem> neededIndexItems) { private void addIndexItemCards(List<IndexItem> mainIndexItem, List<IndexItem> neededIndexItems) {
this.mainIndexItem = mainIndexItem; this.mainIndexItems.clear();
this.mainIndexItems.addAll(mainIndexItem);
this.neededIndexItems.clear(); this.neededIndexItems.clear();
this.neededIndexItems.addAll(neededIndexItems); this.neededIndexItems.addAll(neededIndexItems);
addDownloadUpdateCard(); addDownloadUpdateCard();
@ -228,53 +258,58 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
private void addDownloadUpdateCard() { private void addDownloadUpdateCard() {
final OsmandApplication app = getMyApplication(); final OsmandApplication app = getMyApplication();
if (app != null) { if (app != null && !mainIndexItems.isEmpty() && SHOW_TRAVEL_UPDATE_CARD) {
final DownloadIndexesThread downloadThread = app.getDownloadThread(); boolean outdated = isMapsOutdated();
downloadUpdateCard = new TravelDownloadUpdateCard(app, nightMode, mainIndexItems, !outdated);
boolean outdated = mainIndexItem != null && mainIndexItem.isOutdated(); downloadUpdateCard.setListener(new TravelDownloadUpdateCard.CardListener() {
boolean needsDownloading = mainIndexItem != null && !mainIndexItem.isDownloaded(); @Override
public void onPrimaryButtonClick() {
if (!app.getTravelHelper().isAnyTravelBookPresent() || needsDownloading || (outdated && SHOW_TRAVEL_UPDATE_CARD)) { if (downloadManager != null) {
boolean showOtherMaps = false; downloadManager.startDownload(getMyActivity(), getAllItemsForDownload(mainIndexItems));
if (needsDownloading) { adapter.updateDownloadUpdateCard(false);
List<IndexItem> items = downloadThread.getIndexes().getWikivoyageItems(); }
showOtherMaps = items != null && items.size() > 1;
} }
downloadUpdateCard = new TravelDownloadUpdateCard(app, nightMode, !outdated); @Override
downloadUpdateCard.setShowOtherMapsBtn(showOtherMaps); public void onSecondaryButtonClick() {
downloadUpdateCard.setListener(new TravelDownloadUpdateCard.ClickListener() { if (downloadUpdateCard.isDownloading()) {
@Override app.getDownloadThread().cancelDownload(mainIndexItems);
public void onPrimaryButtonClick() { adapter.updateDownloadUpdateCard(false);
if (mainIndexItem != null && downloadManager != null) { } else {
downloadManager.startDownload(getMyActivity(), mainIndexItem); SHOW_TRAVEL_UPDATE_CARD = false;
adapter.updateDownloadUpdateCard(false); removeDownloadUpdateCard();
}
} }
}
@Override @Override
public void onSecondaryButtonClick() { public void onIndexItemClick(IndexItem item) {
if (downloadUpdateCard.isLoading()) { if (item.getType() == DownloadActivityType.WIKIPEDIA_FILE && !Version.isPaidVersion(app)) {
downloadThread.cancelDownload(mainIndexItem); FragmentManager fm = getFragmentManager();
adapter.updateDownloadUpdateCard(false); if (fm != null) {
} else if (!downloadUpdateCard.isDownload()) { ChoosePlanDialogFragment.showWikipediaInstance(fm);
SHOW_TRAVEL_UPDATE_CARD = false;
removeDownloadUpdateCard();
} else if (downloadUpdateCard.isShowOtherMapsBtn()) {
Activity activity = getActivity();
if (activity != null) {
Intent newIntent = new Intent(activity,
((OsmandApplication) activity.getApplication()).getAppCustomization().getDownloadActivity());
newIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
activity.startActivity(newIntent);
}
} }
} else {
DownloadIndexesThread downloadThread = app.getDownloadThread();
if (downloadThread.isDownloading(item)) {
downloadThread.cancelDownload(item);
} else if (!item.isDownloaded() && downloadManager != null) {
downloadManager.startDownload(getMyActivity(), item);
}
adapter.updateDownloadUpdateCard(false);
} }
}); }
downloadUpdateCard.setIndexItem(mainIndexItem); });
adapter.addDownloadUpdateCard(downloadUpdateCard); adapter.addDownloadUpdateCard(downloadUpdateCard);
}
}
private boolean isMapsOutdated() {
for (IndexItem indexItem : mainIndexItems) {
if (indexItem.isOutdated()) {
return true;
} }
} }
return false;
} }
private void addNeededMapsCard() { private void addNeededMapsCard() {
@ -285,7 +320,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
@Override @Override
public void onPrimaryButtonClick() { public void onPrimaryButtonClick() {
if (downloadManager != null) { if (downloadManager != null) {
downloadManager.startDownload(getMyActivity(), getAllItemsForDownload()); downloadManager.startDownload(getMyActivity(), getAllItemsForDownload(neededIndexItems));
adapter.updateNeededMapsCard(false); adapter.updateNeededMapsCard(false);
} }
} }
@ -323,10 +358,10 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
} }
} }
private IndexItem[] getAllItemsForDownload() { private IndexItem[] getAllItemsForDownload(List<IndexItem> indexItems) {
boolean paidVersion = Version.isPaidVersion(getMyApplication()); boolean paidVersion = Version.isPaidVersion(getMyApplication());
ArrayList<IndexItem> res = new ArrayList<>(); ArrayList<IndexItem> res = new ArrayList<>();
for (IndexItem item : neededIndexItems) { for (IndexItem item : indexItems) {
if (!item.isDownloaded() && (paidVersion || item.getType() != DownloadActivityType.WIKIPEDIA_FILE)) { if (!item.isDownloaded() && (paidVersion || item.getType() != DownloadActivityType.WIKIPEDIA_FILE)) {
res.add(item); res.add(item);
} }
@ -344,7 +379,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
neededMapsCard = null; neededMapsCard = null;
} }
private static class ProcessIndexItemsTask extends AsyncTask<Void, Void, Pair<IndexItem, List<IndexItem>>> { private static class ProcessIndexItemsTask extends AsyncTask<Void, Void, Pair<List<IndexItem>, List<IndexItem>>> {
private static final DownloadActivityType[] types = new DownloadActivityType[]{ private static final DownloadActivityType[] types = new DownloadActivityType[]{
DownloadActivityType.NORMAL_FILE, DownloadActivityType.NORMAL_FILE,
@ -354,40 +389,41 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
private final OsmandApplication app; private final OsmandApplication app;
private final WeakReference<ExploreTabFragment> weakFragment; private final WeakReference<ExploreTabFragment> weakFragment;
private final String fileName;
ProcessIndexItemsTask(ExploreTabFragment fragment) { ProcessIndexItemsTask(ExploreTabFragment fragment) {
app = fragment.getMyApplication(); app = fragment.getMyApplication();
weakFragment = new WeakReference<>(fragment); weakFragment = new WeakReference<>(fragment);
fileName = app != null ? app.getTravelHelper().getWikivoyageFileName() : null;
} }
@Override @Override
protected Pair<IndexItem, List<IndexItem>> doInBackground(Void... voids) { protected Pair<List<IndexItem>, List<IndexItem>> doInBackground(Void... voids) {
if (fileName != null) { List<IndexItem> mainItems = new ArrayList<>();
IndexItem mainItem = app.getDownloadThread().getIndexes().getWikivoyageItem(fileName); List<IndexItem> allWikivoyageItems = app.getDownloadThread().getIndexes().getWikivoyageItems();
if (allWikivoyageItems != null) {
List<IndexItem> neededItems = new ArrayList<>(); for (IndexItem item : allWikivoyageItems) {
for (TravelArticle article : app.getTravelHelper().getBookmarksHelper().getSavedArticles()) { if (!item.isDownloaded() && !mainItems.contains(item)) {
LatLon latLon = new LatLon(article.getLat(), article.getLon()); mainItems.add(item);
try {
for (DownloadActivityType type : types) {
IndexItem item = DownloadResources.findSmallestIndexItemAt(app, latLon, type);
if (item != null && !item.isDownloaded() && !neededItems.contains(item)) {
neededItems.add(item);
}
}
} catch (IOException e) {
// ignore
} }
} }
return new Pair<>(mainItem, neededItems);
} }
return null; List<IndexItem> neededItems = new ArrayList<>();
for (TravelArticle article : app.getTravelHelper().getBookmarksHelper().getSavedArticles()) {
LatLon latLon = new LatLon(article.getLat(), article.getLon());
try {
for (DownloadActivityType type : types) {
IndexItem item = DownloadResources.findSmallestIndexItemAt(app, latLon, type);
if (item != null && !item.isDownloaded() && !neededItems.contains(item)) {
neededItems.add(item);
}
}
} catch (IOException e) {
// ignore
}
}
return new Pair<>(mainItems, neededItems);
} }
@Override @Override
protected void onPostExecute(Pair<IndexItem, List<IndexItem>> res) { protected void onPostExecute(Pair<List<IndexItem>, List<IndexItem>> res) {
ExploreTabFragment fragment = weakFragment.get(); ExploreTabFragment fragment = weakFragment.get();
if (res != null && fragment != null && fragment.isResumed()) { if (res != null && fragment != null && fragment.isResumed()) {
fragment.addIndexItemCards(res.first, res.second); fragment.addIndexItemCards(res.first, res.second);

View file

@ -326,12 +326,12 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv
public void onFinish(AppInitializer init) { public void onFinish(AppInitializer init) {
WikivoyageExploreActivity activity = activityRef.get(); WikivoyageExploreActivity activity = activityRef.get();
if (AndroidUtils.isActivityNotDestroyed(activity)) { if (AndroidUtils.isActivityNotDestroyed(activity)) {
new LoadWikivoyageData(activity).execute(); new LoadWikivoyageData(activity,true).execute();
} }
} }
}); });
} else { } else {
new LoadWikivoyageData(this).execute(); new LoadWikivoyageData(this,true).execute();
} }
} }
@ -380,19 +380,21 @@ public class WikivoyageExploreActivity extends TabActivity implements DownloadEv
updateFragments(); updateFragments();
} }
private static class LoadWikivoyageData extends AsyncTask<Void, Void, Void> { public static class LoadWikivoyageData extends AsyncTask<Void, Void, Void> {
private final WeakReference<WikivoyageExploreActivity> activityRef; private final WeakReference<WikivoyageExploreActivity> activityRef;
private final TravelHelper travelHelper; private final TravelHelper travelHelper;
private final boolean resetData;
LoadWikivoyageData(WikivoyageExploreActivity activity) { LoadWikivoyageData(WikivoyageExploreActivity activity, boolean resetData) {
travelHelper = activity.getMyApplication().getTravelHelper(); travelHelper = activity.getMyApplication().getTravelHelper();
activityRef = new WeakReference<>(activity); activityRef = new WeakReference<>(activity);
this.resetData = resetData;
} }
@Override @Override
protected Void doInBackground(Void... params) { protected Void doInBackground(Void... params) {
travelHelper.initializeDataToDisplay(); travelHelper.initializeDataToDisplay(resetData);
return null; return null;
} }

View file

@ -0,0 +1,56 @@
package net.osmand.plus.wikivoyage.explore.travelcards;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelNeededMapsCard.CardListener;
public class TravelButtonCard extends BaseTravelCard {
public static final int TYPE = 5;
private CardListener listener;
public TravelButtonCard(OsmandApplication app, boolean nightMode) {
super(app, nightMode);
}
public void setListener(CardListener listener) {
this.listener = listener;
}
@Override
public void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) {
if (viewHolder instanceof TravelButtonVH) {
final TravelButtonVH holder = (TravelButtonVH) viewHolder;
UiUtilities.setupDialogButton(nightMode, holder.button, UiUtilities.DialogButtonType.SECONDARY, R.string.show_more);
holder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.onPrimaryButtonClick();
}
}
});
}
}
public static class TravelButtonVH extends RecyclerView.ViewHolder {
final View button;
public TravelButtonVH(View itemView) {
super(itemView);
button = itemView.findViewById(R.id.button);
}
}
@Override
public int getCardType() {
return TYPE;
}
}

View file

@ -1,257 +1,47 @@
package net.osmand.plus.wikivoyage.explore.travelcards; package net.osmand.plus.wikivoyage.explore.travelcards;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.recyclerview.widget.RecyclerView;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.download.IndexItem; import net.osmand.plus.download.IndexItem;
import java.lang.ref.WeakReference; import java.util.List;
import java.text.DateFormat;
public class TravelDownloadUpdateCard extends BaseTravelCard { public class TravelDownloadUpdateCard extends TravelNeededMapsCard {
public static final int TYPE = 50; public static final int TYPE = 50;
private boolean download; private final boolean download;
private boolean showOtherMapsBtn;
private WeakReference<DownloadUpdateVH> ref;
private ClickListener listener; public TravelDownloadUpdateCard(@NonNull OsmandApplication app, boolean nightMode, @NonNull List<IndexItem> items,
boolean download) {
@Nullable super(app, nightMode, items);
private IndexItem indexItem;
private DateFormat dateFormat;
public boolean isDownload() {
return download;
}
public boolean isShowOtherMapsBtn() {
return showOtherMapsBtn;
}
public void setShowOtherMapsBtn(boolean showOtherMapsBtn) {
this.showOtherMapsBtn = showOtherMapsBtn;
}
public void setListener(ClickListener listener) {
this.listener = listener;
}
public void setIndexItem(@Nullable IndexItem indexItem) {
this.indexItem = indexItem;
}
public TravelDownloadUpdateCard(OsmandApplication app, boolean nightMode, boolean download) {
super(app, nightMode);
this.download = download; this.download = download;
dateFormat = android.text.format.DateFormat.getMediumDateFormat(app); }
public int getTitle() {
if (isDownloading()) {
return R.string.shared_string_downloading;
}
return download ? R.string.download_file : R.string.update_is_available;
} }
@Override @Override
public void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) { public int getDescription() {
if (viewHolder instanceof DownloadUpdateVH) { if (!isInternetAvailable()) {
boolean loading = isLoading(); return R.string.no_index_file_to_download;
DownloadUpdateVH holder = (DownloadUpdateVH) viewHolder;
this.ref = new WeakReference<TravelDownloadUpdateCard.DownloadUpdateVH>(holder);
holder.title.setText(getTitle(loading));
holder.icon.setImageResource(getIconRes());
holder.description.setText(getDescription());
if (indexItem == null) {
holder.fileDataContainer.setVisibility(View.GONE);
} else {
holder.fileDataContainer.setVisibility(View.VISIBLE);
holder.fileIcon.setImageDrawable(getFileIcon());
holder.fileTitle.setText(getFileTitle());
holder.fileDescription.setText(getFileDescription());
holder.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
updateProgressBar(holder);
}
boolean primaryBtnVisible = updatePrimaryButton(holder, loading);
boolean secondaryBtnVisible = updateSecondaryButton(holder, loading);
holder.buttonsDivider.setVisibility(primaryBtnVisible && secondaryBtnVisible ? View.VISIBLE : View.GONE);
} }
return download ? R.string.travel_card_download_descr : R.string.travel_card_update_descr;
} }
public void updateProgresBar() { @Override
if(ref != null) { public int getIconRes() {
DownloadUpdateVH holder = ref.get(); return download ? R.drawable.travel_card_download_icon : R.drawable.travel_card_update_icon;
if (holder != null && holder.itemView.isShown()) {
updateProgressBar(holder);
}
}
}
private void updateProgressBar(DownloadUpdateVH holder) {
if (isLoadingInProgress()) {
int progress = app.getDownloadThread().getCurrentDownloadingItemProgress();
holder.progressBar.setProgress(progress < 0 ? 0 : progress);
} else {
holder.progressBar.setProgress(0);
}
} }
@Override @Override
public int getCardType() { public int getCardType() {
return TYPE; return TYPE;
} }
@NonNull
private String getTitle(boolean loading) {
if (loading) {
return app.getString(R.string.shared_string_downloading);
}
return app.getString(download ? R.string.download_file : R.string.update_is_available);
}
private int getIconRes() {
return download ? R.drawable.travel_card_download_icon : R.drawable.travel_card_update_icon;
}
@NonNull
private String getDescription() {
if (!isInternetAvailable()) {
return app.getString(R.string.no_index_file_to_download);
}
return app.getString(download ? R.string.travel_card_download_descr : R.string.travel_card_update_descr);
}
@NonNull
private String getFileTitle() {
return indexItem == null ? "" : indexItem.getVisibleName(app, app.getRegions(), false);
}
@NonNull
private String getFileDescription() {
StringBuilder sb = new StringBuilder();
if (indexItem != null) {
sb.append(app.getString(R.string.file_size_in_mb, indexItem.getArchiveSizeMB()));
sb.append("");
sb.append(indexItem.getRemoteDate(dateFormat));
}
return sb.toString();
}
private Drawable getFileIcon() {
return getActiveIcon(R.drawable.ic_action_read_article);
}
/**
* @return true if button is visible, false otherwise.
*/
private boolean updateSecondaryButton(DownloadUpdateVH vh, boolean loading) {
if (loading || !download || showOtherMapsBtn) {
vh.secondaryBtnContainer.setVisibility(View.VISIBLE);
vh.secondaryBtn.setText(getSecondaryBtnTextId(loading));
vh.secondaryBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onSecondaryButtonClick();
}
}
});
return true;
}
vh.secondaryBtnContainer.setVisibility(View.GONE);
return false;
}
@StringRes
private int getSecondaryBtnTextId(boolean loading) {
if (loading) {
return R.string.shared_string_cancel;
}
if (!download) {
return R.string.later;
}
return R.string.download_select_map_types;
}
/**
* @return true if button is visible, false otherwise.
*/
private boolean updatePrimaryButton(DownloadUpdateVH vh, boolean loading) {
if (!loading) {
boolean enabled = isInternetAvailable();
vh.primaryBtnContainer.setVisibility(View.VISIBLE);
vh.primaryBtnContainer.setBackgroundResource(getPrimaryBtnBgRes(enabled));
vh.primaryButton.setTextColor(getResolvedColor(getPrimaryBtnTextColorRes(enabled)));
vh.primaryButton.setEnabled(enabled);
vh.primaryButton.setText(download ? R.string.shared_string_download : R.string.shared_string_update);
vh.primaryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onPrimaryButtonClick();
}
}
});
return true;
}
vh.primaryBtnContainer.setVisibility(View.GONE);
return false;
}
public boolean isLoading() {
return indexItem != null && app.getDownloadThread().isDownloading(indexItem);
}
private boolean isLoadingInProgress() {
IndexItem current = app.getDownloadThread().getCurrentDownloadingItem();
return indexItem != null && current != null && indexItem == current;
}
public interface ClickListener {
void onPrimaryButtonClick();
void onSecondaryButtonClick();
}
public static class DownloadUpdateVH extends RecyclerView.ViewHolder {
final TextView title;
final ImageView icon;
final TextView description;
final View fileDataContainer;
final ImageView fileIcon;
final TextView fileTitle;
final TextView fileDescription;
final ProgressBar progressBar;
final View secondaryBtnContainer;
final TextView secondaryBtn;
final View buttonsDivider;
final View primaryBtnContainer;
final TextView primaryButton;
@SuppressWarnings("RedundantCast")
public DownloadUpdateVH(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
icon = (ImageView) itemView.findViewById(R.id.icon);
description = (TextView) itemView.findViewById(R.id.description);
fileDataContainer = itemView.findViewById(R.id.file_data_container);
fileIcon = (ImageView) itemView.findViewById(R.id.file_icon);
fileTitle = (TextView) itemView.findViewById(R.id.file_title);
fileDescription = (TextView) itemView.findViewById(R.id.file_description);
progressBar = (ProgressBar) itemView.findViewById(R.id.progress_bar);
secondaryBtnContainer = itemView.findViewById(R.id.secondary_btn_container);
secondaryBtn = (TextView) itemView.findViewById(R.id.secondary_button);
buttonsDivider = itemView.findViewById(R.id.buttons_divider);
primaryBtnContainer = itemView.findViewById(R.id.primary_btn_container);
primaryButton = (TextView) itemView.findViewById(R.id.primary_button);
}
}
} }

View file

@ -9,7 +9,9 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
@ -60,8 +62,12 @@ public class TravelNeededMapsCard extends BaseTravelCard {
if (viewHolder instanceof NeededMapsVH) { if (viewHolder instanceof NeededMapsVH) {
NeededMapsVH holder = (NeededMapsVH) viewHolder; NeededMapsVH holder = (NeededMapsVH) viewHolder;
ref = new WeakReference<NeededMapsVH>(holder); ref = new WeakReference<NeededMapsVH>(holder);
holder.description.setText(isInternetAvailable() holder.title.setText(getTitle());
? R.string.maps_you_need_descr : R.string.no_index_file_to_download); holder.description.setText(getDescription());
int iconRes = getIconRes();
if (iconRes > 0) {
holder.icon.setImageResource(iconRes);
}
adjustChildCount(holder.itemsContainer); adjustChildCount(holder.itemsContainer);
updateView(holder); updateView(holder);
@ -72,6 +78,22 @@ public class TravelNeededMapsCard extends BaseTravelCard {
} }
} }
@StringRes
public int getTitle() {
return R.string.maps_you_need;
}
@StringRes
public int getDescription() {
return isInternetAvailable()
? R.string.maps_you_need_descr : R.string.no_index_file_to_download;
}
@DrawableRes
public int getIconRes() {
return 0;
}
public void updateView() { public void updateView() {
if (ref != null) { if (ref != null) {
NeededMapsVH holder = ref.get(); NeededMapsVH holder = ref.get();
@ -227,7 +249,9 @@ public class TravelNeededMapsCard extends BaseTravelCard {
public static class NeededMapsVH extends RecyclerView.ViewHolder { public static class NeededMapsVH extends RecyclerView.ViewHolder {
final TextView title;
final TextView description; final TextView description;
final ImageView icon;
final LinearLayout itemsContainer; final LinearLayout itemsContainer;
final View secondaryBtnContainer; final View secondaryBtnContainer;
final TextView secondaryBtn; final TextView secondaryBtn;
@ -238,7 +262,9 @@ public class TravelNeededMapsCard extends BaseTravelCard {
@SuppressWarnings("RedundantCast") @SuppressWarnings("RedundantCast")
public NeededMapsVH(View itemView) { public NeededMapsVH(View itemView) {
super(itemView); super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
description = (TextView) itemView.findViewById(R.id.description); description = (TextView) itemView.findViewById(R.id.description);
icon = (ImageView) itemView.findViewById(R.id.icon);
itemsContainer = (LinearLayout) itemView.findViewById(R.id.items_container); itemsContainer = (LinearLayout) itemView.findViewById(R.id.items_container);
secondaryBtnContainer = itemView.findViewById(R.id.secondary_btn_container); secondaryBtnContainer = itemView.findViewById(R.id.secondary_btn_container);
secondaryBtn = (TextView) itemView.findViewById(R.id.secondary_button); secondaryBtn = (TextView) itemView.findViewById(R.id.secondary_button);