Resolve conflicts

This commit is contained in:
PavelRatushny 2017-09-15 11:56:43 +03:00
commit 07d56a7316
98 changed files with 3611 additions and 914 deletions

View file

@ -220,6 +220,16 @@ public class GeoPointParserUtil {
actual = GeoPointParserUtil.parse(url);
assertGeoPoint(actual, new GeoParsedPoint(ilat, ilon, z));
url = "http://www.openstreetmap.org/search?query=" + qlat + "%2C" + qlon;
System.out.println("url: " + url);
actual = GeoPointParserUtil.parse(url);
assertGeoPoint(actual, new GeoParsedPoint(qlat, qlon));
url = "http://www.openstreetmap.org/search?query=" + qlat + "%20" + qlon;
System.out.println("url: " + url);
actual = GeoPointParserUtil.parse(url);
assertGeoPoint(actual, new GeoParsedPoint(qlat, qlon));
// http://download.osmand.net/go?lat=34.99393&lon=-106.61568&z=11
url = "http://download.osmand.net/go?lat=" + dlat + "&lon=" + dlon + "&z=" + z;
System.out.println("url: " + url);
@ -559,6 +569,20 @@ public class GeoPointParserUtil {
actual = GeoPointParserUtil.parse(url);
assertGeoPoint(actual, new GeoParsedPoint(qstr));
// http://www.openstreetmap.org/search?query=Amsterdam
qstr = "Amsterdam";
url = "http://www.openstreetmap.org/search?query=" + URLEncoder.encode(qstr);
System.out.println("url: " + url);
actual = GeoPointParserUtil.parse(url);
assertGeoPoint(actual, new GeoParsedPoint(qstr));
// http://www.openstreetmap.org/search?query=Bloemstraat+51A,+Amsterdam
qstr = "Bloemstraat 51A, Amsterdam";
url = "http://www.openstreetmap.org/search?query=" + URLEncoder.encode(qstr);
System.out.println("url: " + url);
actual = GeoPointParserUtil.parse(url);
assertGeoPoint(actual, new GeoParsedPoint(qstr.replace(',',' ')));
// http://maps.google.com/maps?daddr=760+West+Genesee+Street+Syracuse+NY+13204
qstr = "760 West Genesee Street Syracuse NY 13204";
url = "http://www.google.com/maps?daddr=" + URLEncoder.encode(qstr);
@ -918,6 +942,7 @@ public class GeoPointParserUtil {
double lat = 0;
double lon = 0;
int zoom = GeoParsedPoint.NO_ZOOM;
Map<String, String> queryMap = getQueryParameters(uri);
if (fragment != null) {
if (fragment.startsWith("map=")) {
fragment = fragment.substring("map=".length());
@ -928,6 +953,19 @@ public class GeoPointParserUtil {
lat = parseSilentDouble(vls[1]);
lon = parseSilentDouble(vls[2]);
}
} else if (queryMap != null) {
String queryStr = queryMap.get("query");
if (queryStr != null) {
queryStr = queryStr.replace("+", " ").replace(",", " ");
String[] vls = queryStr.split(" ");
if (vls.length == 2) {
lat = parseSilentDouble(vls[0]);
lon = parseSilentDouble(vls[1]);
}
if (lat == 0 || lon == 0) {
return new GeoParsedPoint(queryStr);
}
}
}
// the query string sometimes has higher resolution values
String mlat = getQueryParameter("mlat", uri);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="@color/dashboard_divider_light"/>
</shape>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/marker_circle_background_light_n"
android:insetBottom="14dp"
android:insetLeft="14dp"
android:insetRight="14dp"
android:insetTop="14dp"/>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/marker_circle_background_p_with_inset" android:state_pressed="true"/>
<item android:drawable="@drawable/marker_circle_background_light_n_with_inset"/>
</selector>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="@color/map_markers_on_map_color"/>
</shape>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/marker_circle_background_on_map_n"
android:insetBottom="14dp"
android:insetLeft="14dp"
android:insetRight="14dp"
android:insetTop="14dp"/>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/marker_circle_background_p_with_inset" android:state_pressed="true"/>
<item android:drawable="@drawable/marker_circle_background_on_map_n_with_inset"/>
</selector>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="@color/map_widget_blue"/>
</shape>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/marker_circle_background_p"
android:insetBottom="14dp"
android:insetLeft="14dp"
android:insetRight="14dp"
android:insetTop="14dp">
</inset>

View file

@ -46,10 +46,10 @@
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_content_margin"
android:layout_marginLeft="@dimen/measurement_tool_content_margin"
android:layout_marginRight="@dimen/measurement_tool_content_margin"
android:layout_marginStart="@dimen/measurement_tool_content_margin"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:background="@null"
tools:src="@drawable/ic_action_ruler"/>
@ -60,10 +60,10 @@
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_content_margin"
android:layout_marginLeft="@dimen/measurement_tool_content_margin"
android:layout_marginRight="@dimen/measurement_tool_content_margin"
android:layout_marginStart="@dimen/measurement_tool_content_margin"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:background="@null"
tools:src="@drawable/ic_action_arrow_down"/>

View file

@ -4,7 +4,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="@dimen/measurement_tool_content_padding">
android:padding="@dimen/bottom_sheet_content_padding">
<TextView
android:layout_width="0dp"
@ -16,7 +16,7 @@
android:id="@+id/toggle_show_on_map"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/measurement_tool_content_margin"
android:layout_marginStart="@dimen/measurement_tool_content_margin"/>
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"/>
</LinearLayout>

View file

@ -4,53 +4,65 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:osmand="http://schemas.android.com/tools"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/map_markers_toolbar"
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dashboard_map_toolbar"
android:background="@color/osmand_orange"
android:minHeight="@dimen/dashboard_map_toolbar"
android:theme="?attr/toolbar_theme"
app:contentInsetLeft="54dp"
app:contentInsetStart="54dp">
android:layout_height="@dimen/dashboard_map_toolbar">
<LinearLayout
<android.support.v7.widget.Toolbar
android:id="@+id/map_markers_toolbar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:gravity="center_vertical">
android:layout_height="match_parent"
app:contentInsetLeft="54dp"
app:contentInsetStart="54dp">
<TextView
android:layout_width="0dp"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:text="@string/map_markers"
android:textColor="@color/color_white"
android:textSize="@dimen/default_list_text_size_large"/>
android:gravity="center_vertical">
<ImageButton
android:id="@+id/options_button"
style="@style/Widget.AppCompat.ActionButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_overflow_menu_white"/>
</LinearLayout>
<net.osmand.plus.widgets.TextViewEx
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:text="@string/map_markers"
android:textColor="@color/color_white"
osmand:typeface="@string/font_roboto_medium"
android:textSize="@dimen/dialog_header_text_size"/>
</android.support.v7.widget.Toolbar>
<ImageButton
android:id="@+id/options_button"
style="@style/Widget.AppCompat.ActionButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_overflow_menu_white"/>
</LinearLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
android:layout_weight="1"
android:background="?attr/ctx_menu_info_view_bg">
<net.osmand.plus.LockableViewPager
android:id="@+id/map_markers_view_pager"
<!-- Coordinator layout is needed in order to display the snackbar above the bottom navigation -->
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="wrap_content">
<net.osmand.plus.LockableViewPager
android:id="@+id/map_markers_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.design.widget.CoordinatorLayout>
<ImageView
android:layout_width="match_parent"
@ -67,7 +79,7 @@
android:layout_height="wrap_content"
android:background="?attr/bg_color"
app:itemBackground="?attr/bg_color"
app:itemIconTint="@color/bottom_navigation_color_selector"
app:itemTextColor="@color/bottom_navigation_color_selector"
app:itemIconTint="@drawable/bottom_navigation_color_selector"
app:itemTextColor="@drawable/bottom_navigation_color_selector"
app:menu="@menu/map_markers_bottom_navigation"/>
</LinearLayout>

View file

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
android:background="?attr/bg_color"
android:orientation="vertical">
<ScrollView
android:id="@+id/history_marker_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_selected_item_title_height"
android:minHeight="@dimen/bottom_sheet_selected_item_title_height"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/map_marker_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_flag_dark"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="@+id/map_marker_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textStyle="bold"
android:textSize="@dimen/default_list_text_size"
android:textAppearance="@style/TextAppearance.ListItemTitle"
tools:text="Bloemstraat 179"/>
<net.osmand.plus.widgets.TextViewEx
osmand:typeface="@string/font_roboto_regular"
android:id="@+id/map_marker_passed_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_sub_text_size"
tools:text="Passed: July 28"/>
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
<LinearLayout
android:id="@+id/make_active_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:layout_marginTop="@dimen/bottom_sheet_content_margin_small"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/make_active_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_reset_to_default_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="@string/make_active"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</LinearLayout>
<LinearLayout
android:id="@+id/delete_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/delete_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_delete_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="@string/shared_string_delete"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
<FrameLayout
android:id="@+id/cancel_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_cancel_button_height"
android:background="?attr/selectableItemBackground">
<TextView
android:id="@+id/cancel_row_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/shared_string_close"
android:textAllCaps="true"
android:textColor="?attr/color_dialog_buttons"
android:textSize="@dimen/default_desc_text_size"
android:textStyle="bold"/>
</FrameLayout>
</LinearLayout>

View file

@ -21,34 +21,34 @@
<net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_title_height"
android:layout_height="@dimen/bottom_sheet_title_height"
android:gravity="center_vertical"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding"
android:text="@string/marker_options"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
android:text="@string/shared_string_options"
android:textAppearance="@style/TextAppearance.ListItemTitle"
osmand:typeface="@string/font_roboto_medium"/>
<LinearLayout
android:id="@+id/sort_by_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/sort_by_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_sort_waypoint_dark"/>
<TextView
@ -63,22 +63,22 @@
<LinearLayout
android:id="@+id/show_direction_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/show_direction_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
tools:src="@drawable/ic_sort_waypoint_dark"/>
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:background="@drawable/ic_action_device_top"/>
<TextView
android:layout_width="0dp"
@ -113,21 +113,21 @@
<LinearLayout
android:id="@+id/build_route_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/build_route_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/map_directions"/>
<TextView
@ -142,21 +142,21 @@
<LinearLayout
android:id="@+id/save_as_new_track_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/save_as_new_track_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_polygom_dark"/>
<TextView
@ -180,21 +180,21 @@
<LinearLayout
android:id="@+id/move_all_to_history_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/move_all_to_history_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_history2"/>
<TextView
@ -218,7 +218,7 @@
<FrameLayout
android:id="@+id/cancel_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measure_distance_bottom_sheet_cancel_button_height"
android:layout_height="@dimen/bottom_sheet_cancel_button_height"
android:background="?attr/selectableItemBackground">
<TextView

View file

@ -0,0 +1,275 @@
<?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:background="?attr/bg_color"
android:orientation="vertical">
<ScrollView
android:id="@+id/marker_show_direction_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/bottom_sheet_content_padding_small">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/show_direction_title"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_title_height"
android:gravity="center_vertical"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
android:text="@string/show_direction"
android:textAppearance="@style/TextAppearance.ListItemTitle"
osmand:typeface="@string/font_roboto_medium"/>
<TextView
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_descr_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
android:text="@string/measurement_tool_save_as_new_track_descr"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"/>
<LinearLayout
android:id="@+id/images_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/bottom_sheet_content_margin"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin_small"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/bottom_sheet_content_margin_small"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:layout_weight="1">
<ImageView
android:id="@+id/top_bar_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:foreground="?attr/selectableItemBackground"
tools:src="@drawable/img_help_trip_route_points_night"/>
<TextView
android:id="@+id/top_bar_image_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/top_bar_image"
android:layout_alignStart="@id/top_bar_image"
android:layout_marginLeft="@dimen/bottom_sheet_image_text_margin_start"
android:layout_marginStart="@dimen/bottom_sheet_image_text_margin_start"
android:layout_marginTop="@dimen/bottom_sheet_content_margin_small"
android:text="@string/top_bar"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_split_segments_sub"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin_small"
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin_small"
android:layout_weight="1">
<ImageView
android:id="@+id/widget_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:foreground="?attr/selectableItemBackground"
tools:src="@drawable/img_help_trip_track_night"/>
<TextView
android:id="@+id/widget_image_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/widget_image"
android:layout_alignStart="@id/widget_image"
android:layout_marginLeft="@dimen/bottom_sheet_image_text_margin_start"
android:layout_marginStart="@dimen/bottom_sheet_image_text_margin_start"
android:layout_marginTop="@dimen/bottom_sheet_content_margin_small"
android:text="@string/widget"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_split_segments_sub"/>
</RelativeLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/top_bar_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:foreground="?attr/selectableItemBackground"
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/top_bar_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:background="@drawable/ic_action_device_top"
tools:src="@drawable/ic_action_device_topbar"/>
<TextView
android:id="@+id/top_bar_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/top_bar_icon"
android:layout_toRightOf="@id/top_bar_icon"
android:maxLines="1"
android:text="@string/top_bar"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
<RadioButton
android:focusable="false"
android:clickable="false"
android:background="@null"
android:id="@+id/top_bar_radio_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/widget_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:foreground="?attr/selectableItemBackground"
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/widget_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:background="@drawable/ic_action_device_top"
tools:src="@drawable/ic_action_device_widget"/>
<TextView
android:id="@+id/widget_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/widget_icon"
android:layout_toRightOf="@id/widget_icon"
android:maxLines="1"
android:text="@string/widget"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
<RadioButton
android:focusable="false"
android:clickable="false"
android:background="@null"
android:id="@+id/widget_radio_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/none_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:foreground="?attr/selectableItemBackground"
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/none_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:background="@drawable/ic_action_device_top"/>
<TextView
android:id="@+id/none_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/none_icon"
android:layout_toRightOf="@id/none_icon"
android:maxLines="1"
android:text="@string/shared_string_none"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
<RadioButton
android:focusable="false"
android:clickable="false"
android:background="@null"
android:id="@+id/none_radio_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"/>
</RelativeLayout>
</LinearLayout>
</ScrollView>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
<FrameLayout
android:id="@+id/cancel_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_cancel_button_height"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/shared_string_cancel"
android:textAllCaps="true"
android:textColor="?attr/color_dialog_buttons"
android:textSize="@dimen/default_desc_text_size"
android:textStyle="bold"/>
</FrameLayout>
</LinearLayout>

View file

@ -41,10 +41,10 @@
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_content_margin"
android:layout_marginLeft="@dimen/measurement_tool_content_margin"
android:layout_marginRight="@dimen/measurement_tool_content_margin"
android:layout_marginStart="@dimen/measurement_tool_content_margin"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:background="@null"
tools:src="@drawable/ic_action_ruler"/>
@ -55,10 +55,10 @@
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_content_margin"
android:layout_marginLeft="@dimen/measurement_tool_content_margin"
android:layout_marginRight="@dimen/measurement_tool_content_margin"
android:layout_marginStart="@dimen/measurement_tool_content_margin"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:background="@null"
tools:src="@drawable/ic_action_arrow_down"/>

View file

@ -22,12 +22,12 @@
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/options_title"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_title_height"
android:layout_height="@dimen/bottom_sheet_title_height"
android:gravity="center_vertical"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
android:text="@string/shared_string_options"
android:textAppearance="@style/TextAppearance.ListItemTitle"
osmand:typeface="@string/font_roboto_medium"/>
@ -35,21 +35,21 @@
<RelativeLayout
android:id="@+id/snap_to_road_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/snap_to_road_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_snap_to_road"/>
<android.support.v7.widget.SwitchCompat
@ -59,8 +59,8 @@
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/measurement_tool_content_margin"
android:layout_marginStart="@dimen/measurement_tool_content_margin"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:background="@null"
android:clickable="false"
android:focusable="false"
@ -108,13 +108,13 @@
<RelativeLayout
android:id="@+id/save_as_new_segment_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding"
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
android:visibility="gone">
<ImageView
@ -122,8 +122,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_polygom_dark"/>
<TextView
@ -140,21 +140,21 @@
<RelativeLayout
android:id="@+id/save_as_new_track_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/save_as_new_track_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_polygom_dark"/>
<TextView
@ -171,21 +171,21 @@
<RelativeLayout
android:id="@+id/add_to_the_track_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/add_to_the_track_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_split_interval"/>
<TextView
@ -211,21 +211,21 @@
<RelativeLayout
android:id="@+id/clear_all_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/clear_all_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_reset_to_default_dark"/>
<TextView
@ -251,7 +251,7 @@
<FrameLayout
android:id="@+id/cancel_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measure_distance_bottom_sheet_cancel_button_height"
android:layout_height="@dimen/bottom_sheet_cancel_button_height"
android:background="?attr/selectableItemBackground">
<TextView

View file

@ -16,28 +16,28 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/measurement_tool_content_padding_small">
android:paddingBottom="@dimen/bottom_sheet_content_padding_small">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/save_as_new_track_title"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_title_height"
android:layout_height="@dimen/bottom_sheet_title_height"
android:gravity="center_vertical"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
android:text="@string/shared_string_save_as_gpx"
android:textAppearance="@style/TextAppearance.ListItemTitle"
osmand:typeface="@string/font_roboto_medium"/>
<TextView
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_descr_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding"
android:layout_height="@dimen/bottom_sheet_descr_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
android:text="@string/measurement_tool_save_as_new_track_descr"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"/>
@ -46,16 +46,16 @@
android:id="@+id/images_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginBottom="@dimen/bottom_sheet_content_margin"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/measurement_tool_content_margin_small"
android:layout_marginLeft="@dimen/measurement_tool_content_margin"
android:layout_marginRight="@dimen/measurement_tool_content_margin_small"
android:layout_marginStart="@dimen/measurement_tool_content_margin"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin_small"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/bottom_sheet_content_margin_small"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:layout_weight="1">
<ImageView
@ -73,9 +73,9 @@
android:layout_height="wrap_content"
android:layout_alignLeft="@id/route_point_image"
android:layout_alignStart="@id/route_point_image"
android:layout_marginLeft="@dimen/measurement_tool_bottom_image_text_margin_start"
android:layout_marginStart="@dimen/measurement_tool_bottom_image_text_margin_start"
android:layout_marginTop="@dimen/measurement_tool_content_margin_small"
android:layout_marginLeft="@dimen/bottom_sheet_image_text_margin_start"
android:layout_marginStart="@dimen/bottom_sheet_image_text_margin_start"
android:layout_marginTop="@dimen/bottom_sheet_content_margin_small"
android:text="@string/route_point"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_split_segments_sub"/>
@ -84,10 +84,10 @@
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/measurement_tool_content_margin"
android:layout_marginLeft="@dimen/measurement_tool_content_margin_small"
android:layout_marginRight="@dimen/measurement_tool_content_margin"
android:layout_marginStart="@dimen/measurement_tool_content_margin_small"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin_small"
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin_small"
android:layout_weight="1">
<ImageView
@ -105,9 +105,9 @@
android:layout_height="wrap_content"
android:layout_alignLeft="@id/line_image"
android:layout_alignStart="@id/line_image"
android:layout_marginLeft="@dimen/measurement_tool_bottom_image_text_margin_start"
android:layout_marginStart="@dimen/measurement_tool_bottom_image_text_margin_start"
android:layout_marginTop="@dimen/measurement_tool_content_margin_small"
android:layout_marginLeft="@dimen/bottom_sheet_image_text_margin_start"
android:layout_marginStart="@dimen/bottom_sheet_image_text_margin_start"
android:layout_marginTop="@dimen/bottom_sheet_content_margin_small"
android:text="@string/line"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_split_segments_sub"/>
@ -118,21 +118,21 @@
<RelativeLayout
android:id="@+id/save_as_route_point_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/route_point_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_route_points"/>
<TextView
@ -149,21 +149,21 @@
<RelativeLayout
android:id="@+id/save_as_line_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/line_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_split_interval"/>
<TextView
@ -189,7 +189,7 @@
<FrameLayout
android:id="@+id/cancel_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measure_distance_bottom_sheet_cancel_button_height"
android:layout_height="@dimen/bottom_sheet_cancel_button_height"
android:background="?attr/selectableItemBackground">
<TextView

View file

@ -16,24 +16,24 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/measurement_tool_content_padding_small">
android:paddingBottom="@dimen/bottom_sheet_content_padding_small">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_selected_point_title_height"
android:minHeight="@dimen/measurement_tool_selected_point_title_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:layout_height="@dimen/bottom_sheet_selected_item_title_height"
android:minHeight="@dimen/bottom_sheet_selected_item_title_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/selected_point_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_measure_point"/>
<LinearLayout
@ -74,8 +74,8 @@
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"
android:layout_marginLeft="@dimen/measurement_tool_content_margin_small"
android:layout_marginRight="@dimen/measurement_tool_content_margin_small"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin_small"
android:layout_marginRight="@dimen/bottom_sheet_content_margin_small"
tools:text="A: 345 m"/>
<android.support.v7.widget.AppCompatTextView
@ -101,21 +101,21 @@
<RelativeLayout
android:id="@+id/move_point_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/move_point_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_move_point"/>
<TextView
@ -132,21 +132,21 @@
<RelativeLayout
android:id="@+id/delete_point_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/delete_point_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_remove_dark"/>
<TextView
@ -172,21 +172,21 @@
<RelativeLayout
android:id="@+id/add_point_after_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/add_point_after_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_addpoint_above"/>
<TextView
@ -203,21 +203,21 @@
<RelativeLayout
android:id="@+id/add_point_before_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/add_point_before_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_addpoint_below"/>
<TextView
@ -243,7 +243,7 @@
<FrameLayout
android:id="@+id/cancel_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measure_distance_bottom_sheet_cancel_button_height"
android:layout_height="@dimen/bottom_sheet_cancel_button_height"
android:background="?attr/selectableItemBackground">
<TextView

View file

@ -16,27 +16,27 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/measurement_tool_content_padding_small">
android:paddingBottom="@dimen/bottom_sheet_content_padding_small">
<TextView
android:id="@+id/choose_navigation_title"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_title_height"
android:layout_height="@dimen/bottom_sheet_title_height"
android:gravity="center_vertical"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
android:text="@string/choose_navigation_type"
android:textAppearance="@style/TextAppearance.ListItemTitle"/>
<TextView
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_descr_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding"
android:layout_height="@dimen/bottom_sheet_descr_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding"
android:text="@string/measurement_tool_snap_to_road_descr"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"/>
@ -50,7 +50,7 @@
<FrameLayout
android:id="@+id/cancel_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measure_distance_bottom_sheet_cancel_button_height"
android:layout_height="@dimen/bottom_sheet_cancel_button_height"
android:background="?attr/selectableItemBackground">
<TextView

View file

@ -3,21 +3,21 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_bottom_list_item_height"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/measurement_tool_bottom_list_item_height"
android:paddingEnd="@dimen/measurement_tool_content_padding"
android:paddingLeft="@dimen/measurement_tool_content_padding"
android:paddingRight="@dimen/measurement_tool_content_padding"
android:paddingStart="@dimen/measurement_tool_content_padding">
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingEnd="@dimen/bottom_sheet_content_padding"
android:paddingLeft="@dimen/bottom_sheet_content_padding"
android:paddingRight="@dimen/bottom_sheet_content_padding"
android:paddingStart="@dimen/bottom_sheet_content_padding">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginRight="@dimen/measurement_tool_bottom_icon_margin"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
tools:src="@drawable/ic_action_car_dark"/>
<TextView

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
<include layout="@layout/list_item_divider"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:background="?attr/bg_color">
<android.support.v7.widget.AppCompatTextView
android:id="@+id/date_title"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingStart="16dp"
android:gravity="center_vertical"
tools:text="Today"/>
<ImageButton
android:id="@+id/date_options_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center_vertical|end"
android:background="@null"
android:focusableInTouchMode="true"
tools:src="@drawable/ic_overflow_menu_white"/>
</LinearLayout>
</LinearLayout>

View file

@ -1,123 +1,154 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?attr/bg_color"
android:descendantFocusability="blocksDescendants">
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical">
<LinearLayout
android:id="@+id/main_layout"
android:background="?attr/bg_color"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground">
<android.support.v7.widget.AppCompatImageView
android:id="@+id/map_marker_reorder_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:tint="?attr/secondary_icon_color"
tools:src="@drawable/ic_action_reorder"/>
<android.support.v7.widget.AppCompatImageView
android:id="@+id/map_marker_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
tools:src="@drawable/ic_action_flag_dark"/>
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:orientation="vertical">
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?attr/selectableItemBackground">
<android.support.v7.widget.AppCompatTextView
android:id="@+id/map_marker_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_desc_text_size"
tools:text="Van Gogh Museum"/>
<android.support.v7.widget.AppCompatImageView
android:id="@+id/map_marker_reorder_icon"
android:layout_width="56dp"
android:layout_height="56dp"
android:scaleType="centerInside"
android:layout_gravity="center_vertical"
android:tint="?attr/secondary_icon_color"
tools:src="@drawable/ic_action_reorder"/>
<View
tools:visibility="visible"
android:visibility="gone"
android:id="@+id/flag_icon_left_space"
android:layout_width="16dp"
android:layout_height="wrap_content"/>
<android.support.v7.widget.AppCompatImageView
android:id="@+id/map_marker_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
tools:src="@drawable/ic_action_flag_dark"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:id="@+id/map_marker_direction_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
tools:src="@drawable/ic_direction_arrow"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="28dp">
<android.support.v7.widget.AppCompatTextView
android:id="@+id/map_marker_distance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:maxLines="1"
android:textSize="@dimen/default_sub_text_size"
tools:text="213 m"/>
<android.support.v7.widget.AppCompatTextView
android:layout_marginBottom="2dp"
android:layout_gravity="bottom"
android:id="@+id/map_marker_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
tools:text="Van Gogh Museum"/>
<android.support.v7.widget.AppCompatTextView
android:id="@+id/map_marker_point_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="•"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_sub_text_size"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout>
<LinearLayout
android:layout_marginTop="1dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/map_marker_direction_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="4dp"
android:layout_marginEnd="4dp"
tools:src="@drawable/ic_direction_arrow"/>
<android.support.v7.widget.AppCompatTextView
android:id="@+id/map_marker_distance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:textSize="@dimen/default_desc_text_size"
tools:text="213 m"/>
<View
android:id="@+id/map_marker_left_point_space"
android:layout_width="4dp"
android:layout_height="wrap_content"/>
<android.support.v7.widget.AppCompatTextView
android:id="@+id/map_marker_point_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="•"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
android:visibility="gone"
tools:visibility="visible"/>
<View
android:id="@+id/map_marker_right_point_space"
android:layout_width="4dp"
android:layout_height="wrap_content"/>
<android.support.v7.widget.AppCompatTextView
android:id="@+id/map_marker_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
tools:text="Amsterdam Weekend"/>
</LinearLayout>
<android.support.v7.widget.AppCompatTextView
android:id="@+id/map_marker_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_sub_text_size"
tools:text="Amsterdam Weekend"/>
</LinearLayout>
<ImageButton
android:id="@+id/map_marker_options_button"
android:layout_width="56dp"
android:layout_height="56dp"
android:background="@drawable/marker_circle_background_light_with_inset"
android:focusableInTouchMode="true"
tools:src="@drawable/ic_action_marker_passed"/>
</LinearLayout>
<ImageButton
android:id="@+id/map_marker_options_button"
<View
android:id="@+id/divider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:background="?attr/selectableItemBackground"
android:focusableInTouchMode="true"
android:paddingBottom="16dp"
android:paddingLeft="14dp"
android:paddingRight="14dp"
android:paddingTop="16dp"
tools:src="@drawable/ic_overflow_menu_white"/>
android:layout_height="1dp"
android:layout_marginLeft="56dp"
android:layout_marginStart="56dp"
android:background="?attr/dashboard_divider"/>
</LinearLayout>
<View
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_gravity="bottom"
android:layout_marginLeft="56dp"
android:layout_marginStart="56dp"
android:background="?attr/dashboard_divider"/>
<include layout="@layout/card_bottom_divider"
tools:visibility="visible"
android:visibility="gone"
android:id="@+id/bottom_shadow"/>
</FrameLayout>
</LinearLayout>

View file

@ -9,21 +9,21 @@
android:id="@+id/gpx_name_et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/measurement_tool_content_margin"
android:layout_marginLeft="@dimen/measurement_tool_content_margin"
android:layout_marginRight="@dimen/measurement_tool_content_margin"
android:layout_marginStart="@dimen/measurement_tool_content_margin"
android:layout_marginTop="@dimen/measurement_tool_content_margin"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:layout_marginTop="@dimen/bottom_sheet_content_margin"
android:inputType="text"/>
<TextView
android:id="@+id/file_exists_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/measurement_tool_content_margin"
android:layout_marginLeft="@dimen/measurement_tool_content_margin"
android:layout_marginRight="@dimen/measurement_tool_content_margin"
android:layout_marginStart="@dimen/measurement_tool_content_margin"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:gravity="center_horizontal"
android:text="@string/file_with_name_already_exists"
android:textColor="@color/marker_red"
@ -38,7 +38,7 @@
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/measurement_tool_content_padding">
android:padding="@dimen/bottom_sheet_content_padding">
<android.support.v7.widget.SwitchCompat
android:id="@+id/toggle_show_on_map"
@ -47,8 +47,8 @@
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/measurement_tool_content_margin"
android:layout_marginStart="@dimen/measurement_tool_content_margin"/>
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"/>
<TextView
android:layout_width="wrap_content"

View file

@ -2,8 +2,13 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_active"
android:icon="@drawable/ic_map"
android:title="@string/osm_live_active"/>
android:icon="@drawable/ic_action_markers_list"
android:title="@string/shared_string_list"/>
<item
android:id="@+id/action_groups"
android:icon="@drawable/ic_action_folder"
android:title="@string/shared_string_groups" />
<item
android:id="@+id/action_history"

View file

@ -3120,4 +3120,9 @@
<string name="poi_boat_rental_type">Lloguer d\'embarcacions</string>
</resources>
<string name="poi_microwave_oven_yes">Forn microones: sí</string>
<string name="poi_microwave_oven_no">Forn microones: no</string>
<string name="poi_water_heater_yes">Escalfador d\'aigua: sí</string>
<string name="poi_water_heater_no">Escalfador d\'aigua: no</string>
</resources>

View file

@ -3462,4 +3462,34 @@
<string name="poi_beds">Postele</string>
<string name="poi_boat_rental_type">Pronajímání lodí</string>
<string name="poi_cuisine_cajun">Cajunská</string>
<string name="poi_boat_rental">Půjčovna lodí</string>
<string name="poi_boat_motorboat_rental_yes">Motorové čluny: Ano</string>
<string name="poi_boat_motorboat_rental_no">Motorové čluny: ne</string>
<string name="poi_boat_houseboat_rental_yes">Hausbóty: ano</string>
<string name="poi_boat_houseboat_rental_no">Hausbóty: ne</string>
<string name="poi_boat_pedalboat_rental_yes">Šlapadla: ano</string>
<string name="poi_boat_pedalboat_rental_no">Šlapadla: ne</string>
<string name="poi_boat_sailboat_rental_yes">Plachetnice: ano</string>
<string name="poi_boat_sailboat_rental_no">Plachetnice: ne</string>
<string name="poi_boat_dinghy_rental_rental_yes">Malé čluny: ano</string>
<string name="poi_boat_dinghy_rental_rental_no">Malé čluny: ne</string>
<string name="poi_boat_kayak_rental_rental_yes">Kajaky: ano</string>
<string name="poi_boat_kayak_rental_rental_no">Kajaky: ne</string>
<string name="poi_boat_canoe_rental_rental_yes">Kanoe: ano</string>
<string name="poi_boat_canoe_rental_rental_no">Kanoe: ne</string>
<string name="poi_network">Síť</string>
<string name="poi_government_archive">Archiv</string>
<string name="poi_government_ministry">Ministerstvo</string>
<string name="poi_government_public_service">Veřejné služby</string>
<string name="poi_government_social_security">Sociální zabezpečení</string>
<string name="poi_government_social_services">Sociální služby</string>
<string name="poi_government_treasury">Ministerstvo financí</string>
<string name="poi_government_transportation">Dopravní instituce</string>
<string name="poi_government_legislative">Legislativní instituce</string>
</resources>

View file

@ -2564,7 +2564,7 @@ Pokud potřebujete pomoci s aplikací OsmAnd, prosím kontaktujte naši podporu
<string name="do_not_send_anonymous_app_usage">Neposílat anonymní statistiky používání aplikace</string>
<string name="do_not_send_anonymous_app_usage_desc">OsmAnd sbírá informace o tom, které části aplikace otevíráte. Nikdy se neodesílá poloha, nic co je zapisováno do aplikace nebo detaily prohlížených oblastí, hledání nebo stahování.</string>
<string name="do_not_show_startup_messages">Nezobrazovat zprávy při spuštění</string>
<string name="do_not_show_startup_messages_desc">Zobrazuje slevy aplikace a mimořádné zprávy o lokálních událostech</string>
<string name="do_not_show_startup_messages_desc">Zakáže zobrazení slev aplikace a mimořádné zprávy lokálních událostí</string>
<string name="parking_options">Možnosti parkování</string>
<string name="full_version_thanks">Děkujeme vám za zakoupení plné verze OsmAnd!</string>
<string name="routing_attr_relief_smoothness_factor_name">Zvolte kolísání výšky</string>
@ -2717,9 +2717,9 @@ Pokud potřebujete pomoci s aplikací OsmAnd, prosím kontaktujte naši podporu
<string name="add_point_before">Přidat bod před</string>
<string name="add_point_after">Přidat bod za</string>
<string name="shared_string_options">Možnosti</string>
<string name="measurement_tool_snap_to_road_descr">OsmAnd bude přidávat další body, dle typu navigace.</string>
<string name="measurement_tool_snap_to_road_descr">OsmAnd spojí body s trasami pro vybraný profil.</string>
<string name="measurement_tool_save_as_new_track_descr">Body můžete uložit jako body trasy nebo jako čáru.</string>
<string name="choose_navigation_type">Zvolte typ navigace</string>
<string name="choose_navigation_type">Vyberte profil navigace</string>
<string name="add_route_points">Přidat body trasy</string>
<string name="add_line">Přidat čáru</string>
<string name="empty_state_my_tracks">Přidat a zaznamenat trasy</string>
@ -2730,4 +2730,13 @@ Pokud potřebujete pomoci s aplikací OsmAnd, prosím kontaktujte naši podporu
<string name="import_track_desc">Soubor %$1s neobsahuje body trasy, importovat jako trasu?</string>
<string name="move_point">Přesunout bod</string>
<string name="add_segment_to_the_track">Přidat do GPX trasy</string>
</resources>
<string name="move_all_to_history">Přesunout vše do historie</string>
<string name="build_route">Vytvořit trasu</string>
<string name="show_direction">Zobrazit směr</string>
<string name="sort_by">Seřadit podle</string>
<string name="marker_options">Možnosti značek</string>
<string name="do_not_use_animations">Nepoužívat animace</string>
<string name="do_not_use_animations_descr">Zakáže animace v aplikaci</string>
<string name="keep_showing_on_map">Stále zobrazovat na mapě</string>
<string name="exit_without_saving">Ukončit bez uložení?</string>
</resources>

View file

@ -3567,4 +3567,13 @@
<string name="poi_network">Netværk</string>
<string name="poi_government_archive">Arkiv</string>
<string name="poi_government_ministry">Ministerie</string>
<string name="poi_government_public_service">Offentlig service</string>
<string name="poi_government_social_security">Social sikring</string>
<string name="poi_government_social_services">Sociale ydelser</string>
<string name="poi_government_treasury">Finansministeriet</string>
<string name="poi_government_transportation">Transportministeriet</string>
<string name="poi_government_legislative">Lovgivende institution</string>
</resources>

View file

@ -746,7 +746,7 @@
<string name="poi_internet_access_terminal">Internetzugang: Terminal</string>
<string name="poi_internet_access_service">Internetzugang: Dienst</string>
<string name="poi_fee_yes">Ja</string>
<string name="poi_fee_yes">ja</string>
<string name="poi_brand">Marke</string>
<string name="poi_maxweight">Höchstgewicht</string>
@ -958,9 +958,9 @@
<string name="poi_fax">Fax</string>
<string name="facebook">Facebook</string>
<string name="poi_mobile">Handy</string>
<string name="poi_fee_no">Nein</string>
<string name="poi_drinking_water_yes">Ja</string>
<string name="poi_drinking_water_no">Nein</string>
<string name="poi_fee_no">nein</string>
<string name="poi_drinking_water_yes">ja</string>
<string name="poi_drinking_water_no">nein</string>
<string name="poi_supervised_yes">Beaufsichtigt</string>
<string name="poi_supervised_no">Ohne Aufsicht</string>
<string name="poi_crossing_traffic_signals">Mit Ampeln</string>
@ -987,8 +987,8 @@
<string name="poi_recycling_plasterboard">Gipskartonplatte</string>
<string name="poi_recycling_animal_waste">Tierischer Abfall</string>
<string name="poi_monitoring_station">Überwachungsstation</string>
<string name="poi_seasonal_yes">Ja</string>
<string name="poi_seasonal_no">Nein</string>
<string name="poi_seasonal_yes">ja</string>
<string name="poi_seasonal_no">nein</string>
<string name="poi_seasonal_dry_season">Trockenzeit</string>
<string name="poi_seasonal_wet_season">Regenzeit</string>
<string name="poi_recycling_container">Container</string>
@ -1059,8 +1059,8 @@
<string name="poi_height">Höhe</string>
<string name="poi_ele">Meereshöhe</string>
<string name="poi_start_date">Anfangsdatum</string>
<string name="poi_wheelchair_yes">Ja</string>
<string name="poi_wheelchair_no">Nein</string>
<string name="poi_wheelchair_yes">ja</string>
<string name="poi_wheelchair_no">nein</string>
<string name="poi_wheelchair_limited">Eingeschränkt</string>
<string name="poi_wholesale">Großhandel</string>
@ -1163,7 +1163,7 @@
<string name="poi_beach_rocky">Fels</string>
<string name="poi_cypress">Zypresse</string>
<string name="poi_bench_yes">Ja</string>
<string name="poi_bench_yes">ja</string>
<string name="poi_bench_no">Ohne Sitzbank</string>
<string name="poi_bin_yes">Mit Abfalleimer</string>
<string name="poi_bin_no">Ohne Abfalleimer</string>
@ -1235,7 +1235,7 @@
<string name="poi_openfire_yes">Offenes Feuer erlaubt</string>
<string name="poi_openfire_no">Offenes Feuer verboten</string>
<string name="poi_washing_machine_yes">Ja</string>
<string name="poi_washing_machine_yes">ja</string>
<string name="poi_washing_machine_no">Waschmaschine: nein</string>
<string name="poi_shower_yes">Dusche: ja</string>
<string name="poi_shower_no">Dusche: nein</string>
@ -1243,9 +1243,9 @@
<string name="poi_shower_outdoor">Dusche: im Freien</string>
<string name="poi_shower_cold">Dusche: kalt</string>
<string name="poi_shower_indoor">Dusche: drinnen</string>
<string name="poi_caravans_yes">Ja</string>
<string name="poi_caravans_yes">ja</string>
<string name="poi_caravans_no">Wohnwagen: nein</string>
<string name="poi_power_supply_yes">Ja</string>
<string name="poi_power_supply_yes">ja</string>
<string name="poi_power_supply_no">Stromanschluss: nein</string>
<string name="poi_power_supply_cee_17_blue">Stromanschluss: CEE 17 blau</string>
<string name="poi_power_supply_cee_7_4">Stromanschluss: CEE 7/4</string>
@ -1376,7 +1376,7 @@
<string name="poi_pump_manual">Manuell</string>
<string name="poi_pump_no">Keine Pumpe</string>
<string name="poi_pump_yes">Ja</string>
<string name="poi_pump_yes">ja</string>
<string name="poi_information_board">Tafel</string>
<string name="poi_information_map">Karte</string>
@ -1396,18 +1396,18 @@
<string name="poi_board_type_astronomy">Astronomie</string>
<string name="poi_commercial">Gewerbegebiet</string>
<string name="poi_fireplace_yes">Ja</string>
<string name="poi_fireplace_yes">ja</string>
<string name="poi_fireplace_no">Keine Feuerstelle</string>
<string name="poi_covered_yes">Ja</string>
<string name="poi_covered_yes">ja</string>
<string name="poi_covered_no">offen</string>
<string name="poi_smoking_no">Nicht erlaubt</string>
<string name="poi_smoking_outside">nur Außerhalb</string>
<string name="poi_smoking_yes">Erlaubt</string>
<string name="poi_smoking_separated">In einem separaten Raum</string>
<string name="poi_traffic_signals_sound_yes">Ja</string>
<string name="poi_traffic_signals_sound_no">Nein</string>
<string name="poi_traffic_signals_sound_yes">ja</string>
<string name="poi_traffic_signals_sound_no">nein</string>
<string name="poi_rescue_station">Rettungsstation</string>
<string name="poi_mini_roundabout">Mini-Kreisverkehr</string>
@ -1442,7 +1442,7 @@
<string name="poi_garden_style_japanese">Gartenstil: Japanisch</string>
<string name="poi_capacity">Kapazität</string>
<string name="poi_capacity_disabled_yes">Ja</string>
<string name="poi_capacity_disabled_yes">ja</string>
<string name="poi_capacity_disabled_no">keine Behindertenplätze</string>
<string name="poi_capacity_disabled">Behindertenplätze</string>
<string name="poi_capacity_women_yes">Frauenplätze</string>
@ -1459,7 +1459,7 @@
<string name="poi_aerialway_duration">durchschnittliche Fahrzeit, Minuten</string>
<string name="poi_aerialway_bubble_yes">Blase</string>
<string name="poi_aerialway_bubble_no">Keine Blase</string>
<string name="poi_aerialway_heating_yes">Ja</string>
<string name="poi_aerialway_heating_yes">ja</string>
<string name="poi_aerialway_heating_no">keine Heizung</string>
<string name="poi_aerialway_bicycle_yes">Erlaubt</string>
<string name="poi_aerialway_bicycle_no">Fahrrad: nicht erlaubt</string>
@ -1514,9 +1514,9 @@
<string name="poi_payment_diners_club_no">Diners Club Karte nicht akzeptiert</string>
<string name="poi_payment_dkv_yes">DKV</string>
<string name="poi_payment_dkv_no">DKV nicht akzeptiert</string>
<string name="poi_drive_in_yes">Ja</string>
<string name="poi_drive_in_yes">ja</string>
<string name="poi_drive_in_no">Drive-in: nein</string>
<string name="poi_drive_through_yes">Ja</string>
<string name="poi_drive_through_yes">ja</string>
<string name="poi_drive_through_no">Durchfahrt: nein</string>
<string name="poi_brewery_additional">Brauereiname</string>
@ -1531,12 +1531,12 @@
<string name="poi_delivery_no">Kein Lieferservice</string>
<string name="poi_delivery_only">Nur Lieferung</string>
<string name="poi_cocktails_yes">Ja</string>
<string name="poi_cocktails_yes">ja</string>
<string name="poi_service_dealer">Händler</string>
<string name="poi_service_repair">Reparatur</string>
<string name="poi_service_repair_no">Keine Reparatur</string>
<string name="poi_automated_yes">Ja</string>
<string name="poi_automated_yes">ja</string>
<string name="poi_automated_no">Nicht automatisiert</string>
<string name="poi_brushless_no">Bürstenlos: nein</string>
<string name="poi_car_wash_no">Autowäsche: nein</string>
@ -1545,7 +1545,7 @@
<string name="poi_male_no">Für Männer verboten</string>
<string name="poi_female_yes">Weiblich</string>
<string name="poi_female_no">Für Frauen verboten</string>
<string name="poi_toilets_yes">Ja</string>
<string name="poi_toilets_yes">ja</string>
<string name="poi_toilets_no">Keine Toiletten</string>
<string name="poi_religion_bahai">Bahaitum</string>
<string name="poi_religion_pagan">Heidentum</string>
@ -1733,7 +1733,7 @@
<string name="poi_toll_yes">Maut</string>
<string name="poi_toll_no">keine Maut</string>
<string name="poi_toll_hgv_yes">LKW Maut</string>
<string name="poi_tactile_paving_yes">Ja</string>
<string name="poi_tactile_paving_yes">ja</string>
<string name="poi_tactile_paving_no">Ohne Blindenleitsystem</string>
<string name="poi_traffic_signals_sound_walk">Nur wenn Gehen erlaubt ist</string>
@ -1751,7 +1751,7 @@
<string name="poi_piste_grooming_backcountry">Tourenski</string>
<string name="poi_piste_grooming_scooter">Schneemobil</string>
<string name="poi_piste_grooming_skating">Skaten</string>
<string name="poi_piste_grooming_no">Nein</string>
<string name="poi_piste_grooming_no">nein</string>
<string name="poi_piste_grooming_mogul">Buckel</string>
<string name="poi_garden_type_residential">Gartentyp: Hausgarten</string>
@ -1773,7 +1773,7 @@
<string name="poi_payment_girocard_no">Girokarte nicht akzeptiert</string>
<string name="poi_payment_discover_card_yes">Discover-Karte</string>
<string name="poi_payment_discover_card_no">Discover Karte nicht akzeptiert</string>
<string name="poi_brushless_yes">Ja</string>
<string name="poi_brushless_yes">ja</string>
<string name="poi_parish">Gemeindebüro</string>
<string name="poi_payment_cheque_yes">Schecks</string>
<string name="poi_payment_cheque_no">Schecks nicht akzeptiert</string>
@ -1919,7 +1919,7 @@
<string name="poi_service_parts">Teile</string>
<string name="poi_service_electrical">Reparatur von elektrischen Fahrzeugen</string>
<string name="poi_motorcycle_repair">Motorradreparatur</string>
<string name="poi_self_service_yes">Ja</string>
<string name="poi_self_service_yes">ja</string>
<string name="poi_self_service_no">keine Selbstbedienung</string>
<string name="poi_full_service_yes">Rundumservice</string>
<string name="poi_aeroway_fuel">Flugzeugtankstelle</string>
@ -2271,9 +2271,9 @@
<string name="poi_tents_yes">Erlaubt</string>
<string name="poi_tents_no">Zelten nicht gestattet</string>
<string name="poi_backcountry_yes">Ja</string>
<string name="poi_backcountry_no">Nein</string>
<string name="poi_scout_yes">Ja</string>
<string name="poi_backcountry_yes">ja</string>
<string name="poi_backcountry_no">nein</string>
<string name="poi_scout_yes">ja</string>
<string name="poi_scout_no">Pfadfinderlager: nein</string>
<string name="poi_group_only_yes">Nur Gruppen: ja</string>
<string name="poi_group_only_no">Nur Gruppen: nein</string>
@ -2630,12 +2630,12 @@
<string name="poi_plant_nursery">Baumschule</string>
<string name="poi_compressed_air_yes">Ja</string>
<string name="poi_compressed_air_no">Druckluft : nein</string>
<string name="poi_compressed_air_yes">ja</string>
<string name="poi_compressed_air_no">Druckluft: nein</string>
<string name="poi_car_wash_yes">Ja</string>
<string name="poi_car_wash_yes">ja</string>
<string name="poi_vacuum_cleaner_yes">Ja</string>
<string name="poi_vacuum_cleaner_yes">ja</string>
<string name="poi_vacuum_cleaner_no">Staubsauger: nein</string>
<string name="poi_amenity_vacuum_cleaner">Staubsauger</string>
@ -2750,7 +2750,7 @@
<string name="poi_health_person_type_technician">Funktion im Gesundheitssektor: Techniker</string>
<string name="poi_health_person_type_witchdoctor">Funktion im Gesundheitssektor: Medizinmann</string>
<string name="poi_counselling_type_addiction_yes">"Beratung (Sucht): ja"</string>
<string name="poi_counselling_type_addiction_yes">Beratung (Sucht): ja</string>
<string name="poi_counselling_type_addiction_no">Beratung (Sucht): nein</string>
<string name="poi_counselling_type_antenatal_yes">Beratung (Schwangerschaft): ja</string>
<string name="poi_counselling_type_antenatal_no">Beratung (Schwangerschaft): nein</string>
@ -2766,8 +2766,8 @@
<string name="poi_counselling_type_education_no">Beratung (Bildung): nein</string>
<string name="poi_counselling_type_family_yes">Beratung (Familie): ja</string>
<string name="poi_counselling_type_family_no">Beratung (Familie): nein</string>
<string name="poi_counselling_type_homeless_yes">Beratung (Obdachlosigkeit): ja</string>
<string name="poi_counselling_type_homeless_no">Beratung (Obdachlosigkeit): nein</string>
<string name="poi_counselling_type_homeless_yes">Beratung (Obdachlose): ja</string>
<string name="poi_counselling_type_homeless_no">Beratung (Obdachlose): nein</string>
<string name="poi_counselling_type_immigrant_yes">Beratung (Einwanderer): ja</string>
<string name="poi_counselling_type_immigrant_no">Beratung (Einwanderer): nein</string>
<string name="poi_counselling_type_marriage_yes">Beratung (Ehe): ja</string>
@ -2813,7 +2813,7 @@
<string name="poi_counselling_no">Beratung: nein</string>
<string name="poi_emergency_yes">Notfall: ja</string>
<string name="poi_emergency_no">Notfall: nein</string>
<string name="poi_home_visit_yes">Ja</string>
<string name="poi_home_visit_yes">ja</string>
<string name="poi_home_visit_no">Hausbesuch: nein</string>
<string name="poi_disease_ebola_no">Ebola: nein</string>
@ -2979,8 +2979,8 @@
<string name="poi_aquaculture_mussels">Aquakultur: Muscheln</string>
<string name="poi_mdf">Hauptverteiler</string>
<string name="poi_organic_yes">Ja</string>
<string name="poi_organic_no">Nein</string>
<string name="poi_organic_yes">ja</string>
<string name="poi_organic_no">nein</string>
<string name="poi_organic_only">Ausschließlich</string>
<string name="poi_diplomatic_consulate">Konsulat</string>
@ -3274,16 +3274,16 @@
<string name="poi_payment_transport_type">Zahlungsart (Transport)</string>
<string name="poi_outdoor_seating_filter_yes">Ja</string>
<string name="poi_delivery_filter_yes">Ja</string>
<string name="poi_outdoor_seating_filter_yes">ja</string>
<string name="poi_delivery_filter_yes">ja</string>
<string name="poi_diet_vegetarian_filter_yes">Vegetarisch</string>
<string name="poi_diet_vegan_filter_yes">Vegan</string>
<string name="poi_diet_gluten_free_filter_yes">Glutenfrei</string>
<string name="poi_diet_kosher_filter_yes">Koscher</string>
<string name="poi_diet_halal_filter_yes">Halal</string>
<string name="poi_diet_lactose_free_filter_yes">Laktosefrei</string>
<string name="poi_takeaway_filter_yes">Ja</string>
<string name="poi_shower_filter_yes">Ja</string>
<string name="poi_takeaway_filter_yes">ja</string>
<string name="poi_shower_filter_yes">ja</string>
<string name="poi_social_facility_for">Zielgruppe</string>
<string name="poi_compressed_air_filter">Druckluft</string>
@ -3349,7 +3349,7 @@
<string name="poi_cafeteria">Cafeteria</string>
<string name="poi_fast_food_cafeteria">Ja</string>
<string name="poi_fast_food_cafeteria">ja</string>
<string name="poi_drink_wine_yes">Wein: ja</string>
<string name="poi_drink_wine_retail">Wein: Einzelhandel</string>

View file

@ -1592,7 +1592,7 @@ Mit Neuanmeldung fortfahren?</string>
<string name="gpx_tags_txt">Tags</string>
<string name="gpx_description_txt">Beschreibung</string>
<string name="gpx_monitoring_disabled_warn">Aufzeichnung mit der GPX-Taste oder unter \'Einstellungen\' → \'Streckenaufzeichnung\' aktivieren.</string>
<string name="gpx_navigation">GPX-Route wählen</string>
<string name="gpx_navigation">GPX-Route</string>
<string name="gpx_option_reverse_route">GPX-Route umkehren</string>
<string name="gpx_option_destination_point">Derzeitiges Ziel verwenden</string>
<string name="gpx_option_from_start_point">Gesamten Track durchlaufen</string>
@ -1615,7 +1615,7 @@ Mit Neuanmeldung fortfahren?</string>
<string name="targets">Ziele</string>
<string name="way_alarms">Verkehrswarnungen</string>
<string name="record_plugin_description">Diese Erweiterung ermöglicht es, Tracks durch Drücken der GPX-Aufnahme-Schaltfläche auf dem Kartenbildschirm aufzunehmen bzw. alle navigierten Routen automatisch zu protokollieren und sie als lokale GPX-Datei (oder auch online über Web-Dienste) abzuspeichern.
\n
\n
\nAufgenommene Tracks können z. B. mit Bekannten geteilt oder als Beiträge zu OSM verwendet werden. Sportler können gespeicherte Tracks zur Überwachung ihres Trainings verwenden. Einige Basisauswertungen sind direkt in OsmAnd enthalten, wie Rundenzeiten, Durchschnittsgeschwindigkeit, usw.. Die Aufzeichnungen können natürlich auch mit speziellen Analyse-Tools von Drittanbietern nachbearbeitet werden.</string>
<string name="route_descr_destination">Ziel</string>
<string name="local_index_description">Um Einzelheiten zu einem Eintrag zu sehen, auf einen beliebigen Eintrag drücken. Um ihn zu deaktivieren oder zu löschen, lang drücken. Aktuell auf dem Gerät vorhandene Daten (%1$s frei):</string>
@ -1655,7 +1655,7 @@ Mit Neuanmeldung fortfahren?</string>
<string name="wake_on_voice_descr">Bildschirm bei Navigationsanweisung aktivieren (falls aus)</string>
<string name="shared_string_never">Niemals</string>
<string name="impassable_road">Straßen vermeiden </string>
<string name="impassable_road">Straßen vermeiden…</string>
<string name="rendering_attr_tramTrainRoutes_name">Straßen- und Eisenbahnlinien</string>
<string name="rendering_attr_trainLightrailRoutes_name">Stadtbahnlinien</string>
<string name="rendering_attr_shareTaxiRoutes_name">Sammeltaxi-Linien</string>
@ -2629,7 +2629,7 @@ Abgedeckte Fläche: %1$s x %2$s</string>
<string name="routing_attr_relief_smoothness_factor_name">Steigung wählen</string>
<string name="driving_region_automatic">Automatisch</string>
<string name="osmand_extended_description_part1">OsmAnd (OSM Automated Navigation Directions) ist eine Karten- und Navigationsanwendung mit Zugriff auf die kostenlosen, weltweiten und qualitativ hochwertigen Daten von OpenStreetMap (OSM). Erfreuen Sie sich an der akustischen und visuellen Navigation, der Betrachtung von POIs (points of interest), der Erstellung und Verwaltung von GPX-Tracks, der Visualisierung von Höhenlinien und -angaben (über ein Erweiterungsmodul), den Auswahlmöglichkeiten zwischen Auto-, Fahrrad- und Fußgänger-Betriebsart, der Möglichkeit an OSM mitzuarbeiten und vielem mehr.</string>
<string name="osmand_extended_description_part2">" GPS-Navigation • Sie haben die Wahl zwischen dem Offline-Betrieb (ohne Roaming-Gebühren, wenn Sie im Ausland sind) oder dem (schnelleren) Online-Betrieb • Die Sprachführung (mit aufgenommenen oder synthetischen Stimmen) begleitet Sie Schritt für Schritt auf Ihrem Weg • Ihre Route wird neu berechnet, sobald Sie von ihr abweichen • Fahrspurassistent, Straßennamen und voraussichtliche Ankunftszeit helfen Ihnen auf der Strecke • Zur Erhöhung Ihrer Reisesicherheit erfolgt ein automatischer Wechsel zwischen Tag- und Nachtmodus • Sie können wählen, ob Tempolimits angezeigt werden sollen, und ob Sie bei deren Überschreitung darauf hingewiesen werden wollen • Die Kartenvergrößerung passt sich Ihrer Geschwindigkeit an • Sie können Ziele nach Adresse, Typ (z. B.: Parkplatz, Restaurant, Hotel, Tankstelle, Museum) oder geographischen Koordinaten suchen • Die Festlegung von Zwischenstopps entlang Ihrer Reiseroute ist möglich • Sie können Ihre GPX-Tracks aufzeichnen, einspielen und ihnen folgen "</string>
<string name="osmand_extended_description_part2">GPS-Navigation • Sie haben die Wahl zwischen dem Offline-Betrieb (ohne Roaming-Gebühren, wenn Sie im Ausland sind) oder dem (schnelleren) Online-Betrieb • Die Sprachführung (mit aufgenommenen oder synthetischen Stimmen) begleitet Sie Schritt für Schritt auf Ihrem Weg • Ihre Route wird neu berechnet, sobald Sie von ihr abweichen • Fahrspurassistent, Straßennamen und voraussichtliche Ankunftszeit helfen Ihnen auf der Strecke • Zur Erhöhung Ihrer Reisesicherheit erfolgt ein automatischer Wechsel zwischen Tag- und Nachtmodus • Sie können wählen, ob Tempolimits angezeigt werden sollen, und ob Sie bei deren Überschreitung darauf hingewiesen werden wollen • Die Kartenvergrößerung passt sich Ihrer Geschwindigkeit an • Sie können Ziele nach Adresse, Typ (z. B.: Parkplatz, Restaurant, Hotel, Tankstelle, Museum) oder geographischen Koordinaten suchen • Die Festlegung von Zwischenstopps entlang Ihrer Reiseroute ist möglich • Sie können Ihre GPX-Tracks aufzeichnen, einspielen und ihnen folgen</string>
<string name="osmand_extended_description_part3">Karten • zeigen POIs (point of interests) in Ihrer Umgebung an • richten sich nach Ihrer Bewegungsrichtung (oder dem Kompass) aus • zeigen an, wo Sie sind und worauf Sie sehen • übermitteln Ihre Position, damit Ihre Freunde Sie finden können • speichern Ihre wichtigsten Orte als Favoriten • lassen Ihnen die Wahl, wie Bezeichnungen auf der Karte angezeigt werden sollen: in Englisch, Landessprache oder in phonetischer Schreibweise • stellen spezielle Online-Karten, Satellitenansichten (von Bing), verschiedene Overlays, wie GPX-Tracks zu Touren-/Routenverläufen, und zusätzliche Ebenen mit einstellbarer Transparenz dar</string>
<string name="osmand_extended_description_part4">Ski-Sport - das OsmAnd-Skikarten-Modul ermöglicht Ihnen das Betrachten von Skirouten, deren Schwierigkeitsgrad und einiger zusätzlicher Informationen, wie die Lage von Liften und weiterer Einrichtungen.</string>
<string name="osmand_extended_description_part5">Radfahren • Sie finden Radwege auf der Karte • Die GPS-Navigation im Fahrrad-Modus errechnet Ihre Route anhand von Radwegen • Sie können Ihre Geschwindigkeit und Höhe verfolgen • Die Möglichkeit der GPX-Aufzeichnung versetzt Sie in die Lage, Ihre Fahrt zu protokollieren und sie mit anderen zu teilen • Über ein Zusatzmodul können Sie sich Höhenlinien und das Geländerelief darstellen lassen</string>

View file

@ -3533,4 +3533,13 @@
<string name="poi_network">Red</string>
<string name="poi_government_archive">Archivo</string>
<string name="poi_government_ministry">Ministerio</string>
<string name="poi_government_public_service">Servicio público</string>
<string name="poi_government_social_security">Seguridad social</string>
<string name="poi_government_social_services">Servicios sociales</string>
<string name="poi_government_treasury">Tesorería</string>
<string name="poi_government_transportation">Institución de transporte</string>
<string name="poi_government_legislative">Institución legislativa</string>
</resources>

View file

@ -3295,4 +3295,13 @@
<string name="poi_network">Red</string>
<string name="poi_government_archive">Archivos gubernamentales</string>
<string name="poi_government_ministry">Ministerio</string>
<string name="poi_government_public_service">Servicio público</string>
<string name="poi_government_social_security">Seguridad social</string>
<string name="poi_government_social_services">Servicios sociales</string>
<string name="poi_government_treasury">Hacienda pública</string>
<string name="poi_government_transportation">Institución de transporte</string>
<string name="poi_government_legislative">Institución legislativa</string>
</resources>

View file

@ -1959,7 +1959,7 @@ Lon %2$s</string>
<string name="no_location_permission">La aplicación no tiene permiso para acceder a los datos de ubicación.</string>
<string name="no_camera_permission">La aplicación no tiene permiso para acceder a la cámara.</string>
<string name="no_microphone_permission">La aplicación no tiene permiso para acceder al micrófono.</string>
<string name="impassable_road_desc">Selecciona las carreteras que quieres evitar durante la navegación</string>
<string name="impassable_road_desc">Selecciona las carreteras a evitar durante la navegación</string>
<string name="shared_string_sound">Sonido</string>
<string name="select_voice_provider">Selecciona indicaciones por voz</string>
<string name="select_voice_provider_descr">Selecciona o descarga indicaciones de voz para tu idioma</string>
@ -2661,9 +2661,9 @@ Por favor proporciona un código completo</string>
<string name="add_point_before">Añadir punto anterior</string>
<string name="add_point_after">Añadir punto posterior</string>
<string name="shared_string_options">Opciones</string>
<string name="measurement_tool_snap_to_road_descr">OsmAnd añadirá puntos adicionales, según el tipo de navegación utilizado.</string>
<string name="measurement_tool_snap_to_road_descr">OsmAnd conectará los puntos con rutas para el perfil seleccionado.</string>
<string name="measurement_tool_save_as_new_track_descr">Puede guardar los puntos, ya sea como puntos de ruta o como una línea.</string>
<string name="choose_navigation_type">Elegir tipo de navegación</string>
<string name="choose_navigation_type">Seleccionar perfil de navegación</string>
<string name="add_route_points">Añadir puntos de ruta</string>
<string name="add_line">Añadir línea</string>
<string name="empty_state_my_tracks">Añadir y grabar trazas</string>

View file

@ -910,13 +910,19 @@ Mémoire proportionnelle %4$s Mo (limite Android %5$s Mo, Dalvik %6$s Mo).</stri
<string name="snap_to_road_descr">Déplacer la position sur la route pendant la navigation</string>
<string name="snap_to_road">Déplacer sur la route</string>
<string name="osmand_long_description_1000_chars">OsmAnd (OSM Automated Navigation Directions) OsmAnd est un logiciel libre de navigation exploitant une grande variété de données issues OpenStreetMap (OSM). Toutes les données (cartes vectorielles ou à base de tuiles) peuvent être stockées dans la mémoire du téléphone pour un usage hors-ligne. OsmAnd permet également le routage en ligne et hors-ligne avec des instructions vocales pas à pas. Fonctionnalités principales : - Fonctionne complètement hors-ligne (stockage des cartes téléchargées au format vectoriel ou tuile dans le périphérique de stockage) - Cartes hors-lignes compactes disponibles pour le monde entier - Téléchargement des cartes pour un pays ou une région directement depuis l\'application - Possibilité de superposer plusieurs couches, telles que des traces GPX ou de navigation, des points d\'intérêt (PI), des favoris, des courbes de niveau, les arrêts de transport public, et bien d\'autres cartes avec une transparence personnalisable - Recherche hors-ligne d\'adresses et de lieux (PI) - Navigation hors-ligne pour distances moyennes - Mode voiture, vélo et piéton avec : - Option de vue jour/nuit automatique - Option de zoom automatique lors des déplacements - Orientation automatique de la carte (fixe, boussole, cap) Limitations de la version gratuite de OsmAnd : - Nombre de téléchargement de cartes limité - Pas d\'accès aux points d\'intérêt Wikipédia hors-ligne. OsmAnd est activement développé et notre projet et ses progrès futurs dépendent des contributions financières pour financer le développement et le test de nouvelles fonctionnalités. Veuillez considérer l\'achat d\'OsmAnd+, le financement d\'une fonctionnalité spécifique ou une donation sur osmand.net.</string>
<string name="osmand_plus_long_description_1000_chars">OsmAnd+ (OSM Automated Navigation Directions)
<string name="osmand_plus_long_description_1000_chars">OsmAnd+ (OpenStreetMap Automated Navigation and Directions) est un logiciel open source de navigation basé sur les données cartographiques d\'OpenStreetMap. Toutes les données (cartes vectorielles ou à base de tuiles) peuvent être stockées sur l\'appareil pour un usage hors-ligne. En plus de la consultation des cartes, OsmAnd permet la navigation grâce à des instructions détaillées à l\'écran et à un guidage vocal.
\n
\nOsmAnd+ est un logiciel libre de navigation donnant accès à un grand nombre de données OpenStreetMap (OSM). Toutes les données (cartes vectorielles ou à base de tuiles) peuvent être stockées sur l\'appareil pour un usage hors-ligne. En plus de la consultation des cartes, OsmAnd permet également la navigation hors-ligne comme en ligne avec des instructions de guidage vocal.
\nOsmAnd+, version payante de l\'application, n\'est pas limitée en nombre de téléchargements et permet d\'obtenir de nouvelles cartes, des mises à jour de cartes existantes ou encore des greffons et d\'autres données (courbes de niveaux, ...). En achetant OsmAnd+ vous supportez le projet et financez le développement de nouvelles fonctionnalités.
\n
\nOsmAnd+ est la version payante de l\'application, en l\'achetant vous supportez le projet, financez le développement de nouvelles fonctionnalités, et recevez les dernières mises à jour.
\n
\nFonctionnalités principales : - Fonctionne complètement hors-ligne (après téléchargement des cartes) - Cartes compactes disponibles pour le monde entier - Téléchargement illimité des cartes pour un pays ou une région directement depuis l\'application - Points d\'intérêt Wikipédia hors-ligne, idéal pour les voyages touristiques - Possibilité de superposer plusieurs couches, telles que des traces, des points d\'intérêt, des favoris, des courbes de niveau, les transports public et bien d\'autres cartes (pistes de ski, chemin de randonnées, circuit à vélo, balisage maritime ...) avec une transparence personnalisable - Recherche hors-ligne d\'adresses et de points d\'intérêt - Navigation hors-ligne sur des itinéraires de moyenne distance - Modes : voiture, cycliste et piéton - Options : vue jour/nuit automatique, zoom automatique en fonction de la vitesse, plusieurs modes d\'orientation automatique de la carte (fixe, boussole, direction), affichage des limitations de vitesse, guidage vocal par voix enregistrées ou par synthèse vocale</string>
\nFonctionnalités principales :
\n- Fonctionne complètement hors-ligne (après téléchargement des cartes sur l\'appareil)
\n- Téléchargement illimité des cartes pour un pays ou une région directement depuis l\'application
\n- Points d\'intérêt Wikipédia hors-ligne, idéal pour les visites touristiques
\n- Possibilité de superposer plusieurs couches, telles que des traces, des points d\'intérêt, des favoris, des courbes de niveau, les transports public et bien d\'autres cartes (pistes de ski, chemins de randonnée, circuits à vélo, balisage maritime ...) avec une transparence personnalisable
\n- Recherche hors-ligne d\'adresses et de points d\'intérêt
\n- Navigation hors-ligne sur des itinéraires de moyenne distance
\n- Plusieurs modes de navigation : voiture, cycliste et piéton
\n- Options : vue jour/nuit automatique, zoom automatique en fonction de la vitesse, plusieurs modes d\'orientation de la carte (fixe ou suivant le déplacement), affichage des voies de circulation, guidage vocal par voix enregistrées ou par synthèse vocale.</string>
<string name="avoid_motorway">Éviter les autoroutes</string>
@ -2660,18 +2666,16 @@ représentant la zone : %1$s x %2$s</string>
\n • Partage de votre position afin qu\'on puisse vous rejoindre rapidement</string>
<string name="restore_purchases">Restaurer vos achats</string>
<string name="shared_string_visible">Visible</string>
<string name="osmand_plus_extended_description_part7">Améliorez OSM
\n • Signalez des erreurs sur les données
\n • Envoyez des traces GPX directement depuis l\'application
\n • Ajoutez des points d\'intérêt et envoyez les directement sur OSM (ou plus tard si hors-ligne)
\n • Enregistrez vos itinéraires en arrière-plan (pendant que votre appareil est en veille)
\n OsmAnd est une application open source très active. Toutes les contributions sont bienvenues que ce soit en signalant des bugs, en participant à la traduction ou en développant de nouvelles fonctionnalités. Grâce aux interactions entre les utilisateurs et les développeurs l\'application est en évolution permanente. Le projet est bien sûr ouvert à toute contribution financière pour accélérer encore son développement.</string>
<string name="osmand_plus_extended_description_part7">Contribuez facilement à l\'amélioration d\'OpenStreetMap :
\n • Signalez des erreurs de donnée
\n • Envoyez des traces GPX à OpenStreetMap depuis l\'application
\n • Ajoutez des points d\'intérêt et envoyez les à OpenStreetMap (immédiatement si vous êtes en ligne ou plus tard si vous êtes hors-ligne)
\n • Enregistrez vos itinéraires en arrière-plan (pendant que votre appareil est en veille).
\nOsmAnd est une application open source très active. Toutes les contributions sont bienvenues que ce soit en signalant des bugs, en participant à la traduction ou en développant de nouvelles fonctionnalités. Grâce aux interactions entre les utilisateurs et les développeurs l\'application est en évolution permanente. Le projet est bien sûr ouvert à toute contribution financière pour accélérer encore son développement.</string>
<string name="analyze_on_map">Analyser sur la carte</string>
<string name="osmand_plus_extended_description_part1">OsmAnd+ (OSM Automated Navigation Directions) est une application de visualisation de cartes et de navigation utilisant les données gratuites couvrant le monde entier du projet OpenStreetMap (OSM). Profitez d\'un guidage vocal comme visuel; Découvrez des points d\'intérêt; Créez et gérez des traces GPX; Installez des greffons pour visualiser l\'altitude et les courbes de niveaux; Utilisez les modes Conduite, Piéton, Cycliste; Contribuez à l\'amélioration des cartes OSM et bien plus encore !
<string name="osmand_plus_extended_description_part1">OsmAnd+ (OpenStreetMap Automated Navigation and Directions) est une application de visualisation de cartes et de navigation utilisant les données gratuites couvrant le monde entier du projet OpenStreetMap. Bénéficiez d\'un guidage vocal comme visuel; découvrez des points d\'intérêt; créez et gérez des traces GPX; installez des greffons pour visualiser l\'altitude et les courbes de niveaux; utilisez les modes Automobile, Piéton, Cycliste; contribuez à l\'amélioration des cartes et bien plus encore !
\n
\n OsmAnd+ est la version payante de l\'application, en l\'achetant vous supportez le projet, financez le développement de nouvelles fonctionnalités, et recevez les dernières mises à jour.
\n
\nFonctionnalités principales :</string>
\nOsmAnd+ est la version payante de l\'application, en l\'achetant vous supportez le projet, financez le développement de nouvelles fonctionnalités, et recevez les dernières mises à jour.</string>
<string name="sea_depth_thanks">Merci d\'avoir acheté le greffon Lignes de sonde marines !</string>
<string name="index_item_depth_contours_osmand_ext">Lignes de sonde marines</string>
<string name="index_item_depth_points_southern_hemisphere">Lignes de sonde marines pour l\'hémisphère sud</string>
@ -2848,7 +2852,7 @@ représentant la zone : %1$s x %2$s</string>
<string name="add_point_before">Ajouter un point avant</string>
<string name="add_point_after">Ajouter un point après</string>
<string name="shared_string_options">Options</string>
<string name="measurement_tool_snap_to_road_descr">OsmAnd va connecter les points avec les itinéraires pour le profil sélectionné</string>
<string name="measurement_tool_snap_to_road_descr">OsmAnd va relier les points pour établir un itinéraire adapté au profil sélectionné.</string>
<string name="measurement_tool_save_as_new_track_descr">Vous pouvez enregistrer les points soit comme points de passage soit comme ligne.</string>
<string name="choose_navigation_type">Sélectionnez le type de navigation</string>
<string name="add_route_points">Ajouter des points à la route</string>
@ -2876,8 +2880,40 @@ représentant la zone : %1$s x %2$s</string>
<string name="show_direction">Afficher les indications de direction</string>
<string name="sort_by">Trier par</string>
<string name="marker_options">Options de la marque</string>
<string name="osmand_extended_description_part8">OsmAnd est open-source et en développement actif. Tout le monde peut contribuer à l\'application en signalant des bugs, en améliorant les traductions ou en codant de nouvelles fonctionnalités. Le projet est dans un état d\'amélioration continue par toutes ces formes d\'interaction avec les développeurs et les utilisateurs. Les progrès du projet reposent également sur des contributions financières pour financer le codage et le test de nouvelles fonctionnalités. Couverture et qualité de carte approximative: • Europe de l\'Ouest: **** • Europe de l\'Est: *** • Russie: *** • Amérique du Nord: *** • Amérique du Sud: ** • Asie: ** • Japon et Corée: *** • Moyen-Orient: ** • Afrique: ** • Antarctique: * La plupart des pays du monde sont disponibles en téléchargement! Obtenez un navigateur fiable dans votre pays, qu\'il s\'agisse de la France, de l\'Allemagne, du Mexique, du Royaume-Uni, de l\'Espagne, des Pays-Bas, des États-Unis, de la Russie, du Brésil ou de tout autre pays.</string>
<string name="osmand_plus_extended_description_part2">Navigation • Fonctionne en ligne (rapide) ou hors ligne (pas de frais d\'itinérance lorsque vous êtes à l\'étranger) • Guide vocal étape par étape (voix enregistrées et synthétisées) • Guide de voie optionnel, affichage du nom de la rue et heure d\'arrivée estimée • Prise en charge des points intermédiaires sur votre itinéraire • Ré-routage automatique chaque fois que vous vous déviez de l\'itinéraire • Recherchez des lieux par adresse, par type (par exemple: restaurant, hôtel, station-service, musée) ou par coordonnées géographiques</string>
<string name="osmand_plus_extended_description_part3">Affichage de la carte • Affichez votre position et votre orientation • En option, alignez l\'image selon la boussole ou votre direction de mouvement • Enregistrez vos endroits les plus importants en tant que favoris • Affichez les POI (point d\'intérêts) autour de vous • Affichez des tuiles spécialisées en ligne, une vue satellite (de Bing ), différentes surcouches, comme les pistes GPX et les couches supplémentaires avec une transparence personnalisable. • Possibilité d\'afficher les noms de lieux en anglais, local ou phonétique</string>
<string name="osmand_plus_extended_description_part4">Utilisez les données OSM et Wikipedia • Des informations de haute qualité provenant des meilleurs projets collaboratifs du monde • Données OSM disponibles par pays ou région • POI de Wikipédia, idéal pour les visites • Téléchargements gratuits illimités, directement à partir de l\'application • Des cartes vectorielles compactes et mises à jour au moins une fois par mois • Sélection entre les données régionales complètes et le réseau routier uniquement (Exemple: l\'intégralité du Japon représente 700 Mo ou 200 Mo pour le réseau routier uniquement)</string>
<string name="osmand_extended_description_part8">OsmAnd est un projet open source très actif. Tout le monde peut contribuer à l\'application en signalant des bugs, en améliorant les traductions ou en développant de nouvelles fonctionnalités. Les nombreux échanges entre développeurs et utilisateurs permettent d\'améliorer régulièrement OsmAnd et les contributions financières permettent de développer de nouvelles fonctionnalités.
\n
\nCouverture et qualité approximative des cartes :
\n• Europe de l\'Ouest : **** (4)
\n• Europe de l\'Est : *** (3)
\n• Russie : *** (3)
\n• Amérique du Nord : *** (3)
\n• Amérique du Sud : ** (2)
\n• Asie : ** (2)
\n• Japon et Corée : *** (3)
\n• Moyen-Orient : ** (2)
\n• Afrique : ** (2)
\n• Antarctique : * (1).
\n
\nDes cartes sont disponibles en téléchargement pour la majorité des pays du monde autorisant une navigation fiable dans la plupart des pays dont le vôtre !</string>
<string name="osmand_plus_extended_description_part2">Navigation :
\n• Fonctionnement en ligne ou hors ligne (sans aucun frais de communication)
\n• Guidage vocal pas à pas (voix enregistrées ou synthèse vocale)
\n• En option : indication des voies, affichage du nom des rues et de l\'heure estimée d\'arrivée
\n• Ajout d\'étapes sur votre itinéraire
\n• Recalcule automatique de la route si vous vous écartez de l\'itinéraire
\n• Recherchez des lieux par adresse, par type (par exemple : restaurant, hôtel, station-service, musée) ou par coordonnées géographiques.</string>
<string name="osmand_plus_extended_description_part3">Affichage de la carte :
\n• Affichez votre position et votre orientation
\n• Orientez la carte au choix selon la boussole ou selon la direction de votre déplacement
\n• Enregistrez les lieux importants pour vous comme favoris
\n• Affichez les point d\'intérêts aux alentours
\n• Affichez des tuiles spécialisées en ligne, la vue satellite (source : Bing) et de nombreuses autres couches comme des traces GPX avec une transparence personnalisable
\n• Affichez les noms de lieux en anglais, en langue locale ou en phonétique.</string>
<string name="osmand_plus_extended_description_part4">Utilisez les données d\'OpenStreetMap et de Wikipedia :
\n• Informations de haute qualité provenant de l\'un des meilleurs projets collaboratifs au monde
\n• Données disponibles par pays ou région
\n• Points d\'intérêt de Wikipédia, idéal pour les visites
\n• Téléchargements gratuits illimités, directement à partir de l\'application
\n• Cartes vectorielles compactes et mises à jour au moins une fois par mois
\n• Sélection entre les données régionales complètes ou le réseau routier uniquement (par exemple: 700 Mo pour la carte intégrale du Japon et 200 Mo uniquement pour la carte du réseau routier japonnais).</string>
</resources>

View file

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources><string name="poi_shop_food">חנות מזון</string>
<resources><string name="poi_shop_food">חנות נוחות וסופרמרקט</string>
<string name="poi_shop">חנות</string>
<string name="poi_emergency">שרותי חירום</string>
<string name="poi_transportation">תחבורה</string>
@ -64,7 +64,7 @@
<string name="poi_pastry">חנות מאפים</string>
<string name="poi_dairy">חלביה</string>
<string name="poi_vending_machine">מכונת ממכר אוטומטית</string>
<string name="poi_wine">חנות יין</string>
<string name="poi_wine">חנות יינות</string>
<string name="poi_books">חנות ספרים</string>
<string name="poi_bicycle">חנות אופניים</string>
@ -114,7 +114,7 @@
<string name="poi_medical_supply">אספקה רפואית</string>
<string name="poi_mobile_phone">חנות טלפונים ניידים</string>
<string name="poi_motorcycle">חנות אופנועים</string>
<string name="poi_music">חנות מוסיקה</string>
<string name="poi_music">חנות מוזיקה</string>
<string name="poi_musical_instrument">חנות כלי נגינה</string>
<string name="poi_newsagent">סוכנות חדשות</string>
<string name="poi_optician">אופטומטריסט</string>
@ -150,4 +150,87 @@
<string name="poi_information_type">סוג</string>
<string name="poi_resort_type">סוג</string>
<string name="poi_smoking">עישון</string>
</resources>
<string name="poi_payment_fuel_type">כרטיסי דלק</string>
<string name="poi_internet_access_type">סוג גישה לאינטרנט</string>
<string name="poi_clothes_type">סוג</string>
<string name="poi_shoes_type">סוג</string>
<string name="poi_fire_hydrant_type">סוג</string>
<string name="poi_fire_hydrant_position">מיקום</string>
<string name="poi_payment_toll_type">סוג התשלום</string>
<string name="poi_traffic_signals_sound">קול</string>
<string name="poi_highway_crossing_type">סוג</string>
<string name="poi_tactile_paving">ריצוף מובלט</string>
<string name="poi_brushless">בראשלס</string>
<string name="poi_self_service">שירות עצמי</string>
<string name="poi_automated">אוטומטי</string>
<string name="poi_parking_type">סוג</string>
<string name="poi_covered">מכוסה</string>
<string name="poi_bicycle_parking_type">סוג</string>
<string name="poi_telescope_type">סוג</string>
<string name="poi_animal_training_type">סוג</string>
<string name="poi_embassy_type">סוג</string>
<string name="poi_city_capital">בירה</string>
<string name="poi_healthcare_alternative_types">מומחיות</string>
<string name="poi_free_flying_characteristics">מאפיינים</string>
<string name="poi_archaeological_site_type">סוג</string>
<string name="poi_star_rating">דירוג בכוכבים</string>
<string name="poi_religion_type">דת</string>
<string name="poi_information_contents">תכנים</string>
<string name="poi_clock_option">נוסף</string>
<string name="poi_piste_difficulty">קושי מסלול הסקי</string>
<string name="poi_theatre_genre">סוגה</string>
<string name="poi_outdoor_seating">ישיבה בחוץ</string>
<string name="poi_fee">עמלה</string>
<string name="poi_delivery">משלוח</string>
<string name="poi_cocktails">קוקטיילים</string>
<string name="poi_microbrewery">מבשלה קטנה</string>
<string name="poi_beauty_salon_service">שירות</string>
<string name="poi_recycling_type">סוג</string>
<string name="poi_zoo_type">סוג</string>
<string name="poi_direction_n">כיוון: צפון</string>
<string name="poi_direction_nne">כיוון: צפון - צפון מזרח</string>
<string name="poi_direction_ne">כיוון: צפון מזרח</string>
<string name="poi_direction_ene">כיוון: מזרח - צפון מזרח</string>
<string name="poi_direction_e">כיוון: מזרח</string>
<string name="poi_direction_ese">כיוון: מזרח - דרום מזרח</string>
<string name="poi_direction_se">כיוון: דרום מזרח</string>
<string name="poi_direction_sse">כיוון: דרום - דרום מזרח</string>
<string name="poi_direction_s">כיוון: דרום</string>
<string name="poi_reservation_required">הזמנה: נדרשת</string>
<string name="poi_reservation_recommended">הזמנה: מומלצת</string>
<string name="poi_reservation_yes">הזמנה: יש</string>
<string name="poi_reservation_no">הזמנה: אין</string>
<string name="poi_reservation_members_only">הזמנה: חברים בלבד</string>
<string name="poi_beds">מיטות</string>
<string name="poi_boat_rental">סירות להשכרה</string>
<string name="poi_boat_motorboat_rental_yes">סירות מנוע: יש</string>
<string name="poi_boat_motorboat_rental_no">סירות מנוע: אין</string>
<string name="poi_boat_houseboat_rental_yes">בתי סירה: יש</string>
<string name="poi_boat_houseboat_rental_no">בתי סירה: אין</string>
<string name="poi_boat_pedalboat_rental_yes">סירות פדלים: יש</string>
<string name="poi_boat_pedalboat_rental_no">סירות פדלים: אין</string>
<string name="poi_boat_jetski_rental_yes">אופנועי ים: יש</string>
<string name="poi_boat_jetski_rental_no">אופנועי ים: אין</string>
<string name="poi_boat_sailboat_rental_yes">מפרשיות: יש</string>
<string name="poi_boat_sailboat_rental_no">מפרשיות: אין</string>
<string name="poi_boat_dinghy_rental_rental_yes">דוגיות: יש</string>
<string name="poi_boat_dinghy_rental_rental_no">דוגיות: אין</string>
<string name="poi_boat_kayak_rental_rental_yes">קיאקים: יש</string>
<string name="poi_boat_kayak_rental_rental_no">קיאקים: אין</string>
<string name="poi_boat_canoe_rental_rental_yes">קאנו: יש</string>
<string name="poi_boat_canoe_rental_rental_no">קאנו: אין</string>
<string name="poi_network">רשת</string>
<string name="poi_government_archive">ארכיון</string>
<string name="poi_government_ministry">משרד ממשלתי</string>
<string name="poi_government_public_service">שירות ציבורי</string>
<string name="poi_government_social_security">ביטוח לאומי</string>
<string name="poi_government_social_services">שירותים סוציאליים</string>
<string name="poi_government_treasury">אוצר</string>
<string name="poi_government_transportation">מוסד תעבורתי</string>
<string name="poi_government_legislative">מוסד חוקתי</string>
</resources>

View file

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><resources><string name="address_search_desc">Mencari alamat</string>
<?xml version='1.0' encoding='UTF-8'?>
<resources><string name="address_search_desc">Mencari alamat</string>
<string name="navpoint_search_desc">Koordinat</string>
<string name="transport_search_desc">Mencari transportasi</string>
<string name="favourites_search_desc">Mencari favorit</string>
@ -72,4 +73,5 @@
<string name="osm_live_subscription_settings">Pengaturan berlangganan</string>
<string name="osm_live_ask_for_purchase">Harap beli berlangganan OSM Live terlebih dahulu</string>
</resources>
<string name="sort_by">Urutkan dengan</string>
</resources>

View file

@ -2654,7 +2654,7 @@ Rappresenta l\'area: %1$s x %2$s</string>
<string name="total_distance">Distanza totale</string>
<string name="routing_attr_height_relief_smoothness_factor_description">Più piatto o più colline</string>
<string name="routing_attr_height_obstacles_name">Utilizza dati di quota</string>
<string name="routing_attr_height_obstacles_name">Utilizza dati altitudine</string>
<string name="routing_attr_height_obstacles_description">Utilizza i dati di elevazione del terreno forniti da SRTM, ASTER e EU-DEM</string>
<string name="shared_string_time_span">Intervallo di tempo</string>
@ -2882,9 +2882,9 @@ Copertura e qualità approssimativamente:
<string name="add_point_before">Aggiungi un punto prima</string>
<string name="add_point_after">Aggiungi un punto dopo</string>
<string name="shared_string_options">Opzioni</string>
<string name="measurement_tool_snap_to_road_descr">OsmAnd aggiungerà dei punti, in base al tipo di navigazione.</string>
<string name="measurement_tool_snap_to_road_descr">OsmAnd aggiungerà i punti al percorso, in base al tipo di navigazione.</string>
<string name="measurement_tool_save_as_new_track_descr">Puoi salvare i punti sia come punti di un percorso che come linea.</string>
<string name="choose_navigation_type">Scegli la modalità di navigazione</string>
<string name="choose_navigation_type">Scegli il profilo di navigazione</string>
<string name="exit_without_saving">Uscire senza salvare?</string>
<string name="do_not_use_animations">Non utilizzare le animazioni</string>
<string name="do_not_use_animations_descr">Disabilita le animazioni nell\'app</string>

View file

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><resources>
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<string name="local_indexes_cat_av">زانیاری دەنگ/ڤیدیۆ</string>
<string name="stop_routing_confirm">دڵنیای له وەی که ئه ته وێت ناڤیگێشن راگریت</string>
@ -93,4 +94,10 @@
<string name="reports_for">Ji bo raporkirina</string>
<string name="update_now">Niha Rojaneyîke</string>
<string name="update">Hemû rojanekirî</string>
</resources>
<string name="sort_by">Tesnîfkirina gorî</string>
<string name="do_not_use_animations">Anîmasyonan bi kar neyîne</string>
<string name="do_not_use_animations_descr">Di sepanê de anîmasyonan disekinîne</string>
<string name="exit_without_saving">Derkeve û qeyd neke?</string>
<string name="line">Xet</string>
<string name="save_as_line">Wekê xetekê qeyd bike</string>
</resources>

View file

@ -91,14 +91,14 @@
<dimen name="my_places_empty_state_text_button_padding_right">90dp</dimen>
<dimen name="my_places_empty_state_text_button_padding_top">96dp</dimen>
<dimen name="measure_distance_bottom_sheet_cancel_button_height">72dp</dimen>
<dimen name="bottom_sheet_cancel_button_height">72dp</dimen>
<dimen name="landscape_bottom_sheet_dialog_fragment_width">540dp</dimen>
<dimen name="measurement_tool_select_radius">30dp</dimen>
<dimen name="measurement_tool_content_margin">24dp</dimen>
<dimen name="measurement_tool_content_margin_small">12dp</dimen>
<dimen name="measurement_tool_content_padding">24dp</dimen>
<dimen name="measurement_tool_content_padding_small">12dp</dimen>
<dimen name="bottom_sheet_content_margin">24dp</dimen>
<dimen name="bottom_sheet_content_margin_small">12dp</dimen>
<dimen name="bottom_sheet_content_padding">24dp</dimen>
<dimen name="bottom_sheet_content_padding_small">12dp</dimen>
<dimen name="measurement_tool_divider_margin">12dp</dimen>
<dimen name="measurement_tool_content_padding_medium">18dp</dimen>
<dimen name="measurement_tool_text_margin_small">6dp</dimen>
@ -113,14 +113,14 @@
<dimen name="measurement_tool_button_margin">12dp</dimen>
<dimen name="measurement_tool_button_padding">12dp</dimen>
<dimen name="measurement_tool_button_height">54dp</dimen>
<dimen name="measurement_tool_bottom_title_height">78dp</dimen>
<dimen name="measurement_tool_bottom_descr_height">66dp</dimen>
<dimen name="measurement_tool_bottom_list_item_height">72dp</dimen>
<dimen name="measurement_tool_bottom_icon_margin">36dp</dimen>
<dimen name="bottom_sheet_title_height">78dp</dimen>
<dimen name="bottom_sheet_descr_height">66dp</dimen>
<dimen name="bottom_sheet_list_item_height">72dp</dimen>
<dimen name="bottom_sheet_icon_margin">36dp</dimen>
<dimen name="measurement_tool_bottom_divider_margin_top">11dp</dimen>
<dimen name="measurement_tool_bottom_divider_margin_bottom">12dp</dimen>
<dimen name="measurement_tool_bottom_divider_margin_start">96dp</dimen>
<dimen name="measurement_tool_bottom_image_text_margin_start">15dp</dimen>
<dimen name="measurement_tool_selected_point_title_height">84dp</dimen>
<dimen name="bottom_sheet_image_text_margin_start">15dp</dimen>
<dimen name="bottom_sheet_selected_item_title_height">84dp</dimen>
</resources>

View file

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><resources>
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<string name="layer_map_appearance">Configureer scherm</string>
<string name="show_lanes">Rijstroken</string>
@ -2863,4 +2864,21 @@ Van bijna alle landen is een kaart te downloaden: van Afghanistan tot Zimbabwe,
<string name="mapillary_menu_title_dates">Data</string>
<string name="mapillary_menu_edit_text_hint">Geef gebruikersnaam</string>
<string name="mapillary_menu_title_username">Gebruikersnaam</string>
<string name="move_all_to_history">Alles naar geschiedenis verplaatsen</string>
<string name="build_route">Route maken</string>
<string name="show_direction">Toon richting</string>
<string name="sort_by">Sorteren op</string>
<string name="marker_options">Opties voor Markeervlaggetjes</string>
<string name="do_not_use_animations">Geen animaties gebruiken</string>
<string name="do_not_use_animations_descr">Zet alle animaties binnen OsmAnd uit</string>
<string name="keep_showing_on_map">Verder wel op de kaart blijven tonen</string>
<string name="exit_without_saving">Afsluiten zonder op te slaan?</string>
<string name="line">Lijn</string>
<string name="save_as_route_point">Opslaan als Routepunten</string>
<string name="save_as_line">Als lijn opslaan</string>
<string name="route_point">Routepunt</string>
<string name="edit_line">Lijn bewerken</string>
<string name="add_point_before">Punt ervoor toevoegen</string>
<string name="add_point_after">Punt erna toevoegen</string>
<string name="shared_string_options">Opties</string>
</resources>

View file

@ -3499,4 +3499,13 @@
<string name="poi_boat_canoe_rental_rental_yes">Каноэ: да</string>
<string name="poi_boat_canoe_rental_rental_no">Каноэ: нет</string>
<string name="poi_government_archive">Архив</string>
<string name="poi_government_ministry">Министерство</string>
<string name="poi_government_public_service">Государственная служба</string>
<string name="poi_government_social_security">Социальная защита</string>
<string name="poi_government_social_services">Социальные службы</string>
<string name="poi_government_treasury">Казначейство</string>
<string name="poi_government_transportation">Транспортное учреждение</string>
<string name="poi_government_legislative">Законодательное учреждение</string>
</resources>

View file

@ -2760,7 +2760,7 @@ Pro praghere iscrie su còdighe intreu</string>
<string name="exit_without_saving">Essire chene sarvare?</string>
<string name="do_not_use_animations">No imprees sas animatziones</string>
<string name="do_not_use_animations_descr">Disabilitat sas animatziones in s\'aplicatzione</string>
<string name="move_all_to_history">Pone totu in s\'istòria</string>
<string name="move_all_to_history">Pone totu in sa cronologia</string>
<string name="build_route">Càlcula s\'àndala</string>
<string name="show_direction">Ammustra sas indicatziones de diretzione</string>
<string name="sort_by">Òrdina pro</string>

View file

@ -2662,7 +2662,7 @@ Koda predstavlja območje: %1$s x %2$s</string>
<string name="do_not_send_anonymous_app_usage">Ne pošiljaj statističnih podatkov uporabe programa</string>
<string name="do_not_send_anonymous_app_usage_desc">Pošiljajo se le splošni podatki o načinu uporabe programa. Geolokacijski podatki, podatki shranjenih zemljevidov in vpisanih točk ter drugi podatki uporabnika se nikoli ne shranjujejo na strežnikih.</string>
<string name="do_not_show_startup_messages">Ne prikazuj sporočil ob zagunu</string>
<string name="do_not_show_startup_messages_desc">Pojavijo se lahko sporočila o popustih programa in posebna krajevna sporočila o dogodkih</string>
<string name="do_not_show_startup_messages_desc">Onemogoči prikazovanje sporočil o popustih programa in posebnih sporočila o dogodkih</string>
<string name="parking_options">Možnosti parkiranja</string>
<string name="full_version_thanks">Zahvaljujemo se vam za nakup polne različice programa OsmAnd!</string>
<string name="right_side_navigation">Promet po desni strani</string>
@ -2821,9 +2821,9 @@ Koda predstavlja območje: %1$s x %2$s</string>
<string name="edit_line">Uredi črto</string>
<string name="add_point_before">Dodaj točko pred</string>
<string name="add_point_after">Dodaj točko za</string>
<string name="measurement_tool_snap_to_road_descr">Program bo dodal točke glede na vrsto navigacije.</string>
<string name="measurement_tool_snap_to_road_descr">Program bo povezal točke s potmi za po izbranem profilu.</string>
<string name="measurement_tool_save_as_new_track_descr">Točke je mogoče shraniti kot točke poti ali kot črto.</string>
<string name="choose_navigation_type">Izbor vrste navigacije</string>
<string name="choose_navigation_type">Izbor profila navigacije</string>
<string name="measurement_tool_action_bar">Prebrskajte zemljevid in dodajte točke</string>
<string name="add_route_points">Dodaj točke poti</string>
<string name="add_waypoint">Dodaj vmesno točko</string>
@ -2838,4 +2838,18 @@ Koda predstavlja območje: %1$s x %2$s</string>
<string name="move_point">Premakni točko</string>
<string name="add_segment_to_the_track">Dodaj na sled GPX</string>
<string name="empty_state_favourites_desc">Dodaj priljubljene na zemljevid ali pa jih uvozi iz datoteke</string>
<string name="move_all_to_history">Premakni vse v zgodovino</string>
<string name="build_route">Preračunaj pot</string>
<string name="show_direction">Pokaži smer</string>
<string name="sort_by">Razvrsti po</string>
<string name="marker_options">Možnosti označb</string>
<string name="do_not_use_animations">Ne uporabljaj animacij</string>
<string name="do_not_use_animations_descr">Onemogoči predvajanje animacij v programu</string>
<string name="keep_showing_on_map">Prikazuj na zemljevidu</string>
<string name="exit_without_saving">Ali želite končati brez shranjevanja?</string>
<string name="osmand_plus_extended_description_part1">"OsmAnd+ (OSM Automated Navigation Directions) je navigacijski program, ki kot vir podatkov uporablja visoko kakovostne zemljevide OpenStreetMap (OSM). Program podpira glasovno in vizualno navigacijo, iskanje in ogledovanje točk POI (zanimive točke), ustvarjanje in upravljanje s sledmi GPX, izohipse in senčenje terena, podatke o poti, različne profile za pripravo poti in še veliko, veliko več. OsmAnd+ je plačljiva različica programa. Z nakupom podpirate projekt, omogočate razvoj novih zmožnosti in si pridobite možnost prejemanja najnovejših posodobitev. Glavne značilnosti programa so:"</string>
<string name="osmand_plus_extended_description_part2">Navigacija • Deluje prek širokopasovne povezave (hitro) ali brez povezave (ni dodatnih stroškov na poti) • Glasovno vodenje od zavoja-do-zavoja (posneti in sintetizirani glasovi) • Izbirno vodenje po pasovih, prikaz imen ulic in pričakovanega časa prihoda • Podpora vmesnim točkam na poti • Samodejno preusmerjanje in preračunavanje poti ob nepričakovani spremembi poti • Iskanje mest po naslovu, po vrsti (na primer: restavracija, hotel, bencinska črpalka, muzej) ali po koordinatah</string>
<string name="osmand_plus_extended_description_part3">Pregledovanje zemljevida • Prikaz trenutnega mesta in usmerjenost • Izbirno prilagajanje po kompasu oziroma po smeri gibanja • Shranjevanje priljubljenih točk • Prikaz točk POI (točke zanimivosti) v bližini • Prikaz spletnih satelitskih sličic (Bing), različne prekrivne plasti kot so potovalne/navigacijske sledi GPX • Izbirno prikazovanje imen v krajevnem zapisu, angleško ali fonetično</string>
<string name="osmand_plus_extended_description_part6">Možnosti za pešce in kolesarje • Pregledovanje pešpoti, kolesarskih poti in označenih kolovozov • Poseben način prikazovanja z dodatnimi pogledi • Izbirni prikaz postajališč javnega prometa (avtobus, trolejbus, vlak), vključno z imeni prog • Možnost beleženja poti v krajevno datoteko GPX ali pošiljanje na spletno mesto • Prikaz hitrosti in nadmorske višine • Prikaz izohips in senčenja hribovitosti pokrajine (prek dodatnega vstavka)</string>
<string name="osmand_plus_extended_description_part7">Neposredno objavljanje na OSM • Objavljanje poročil o hroščih • Pošiljanje sledi GPX neposredno na OSM • Dodajanje točk POI • Izbirno beleženje tudi v stanju pripravljenosti naprave Program OsmAnd je odprtokoden, zato lahko vsak sodeluje pri razvoju. Zaželena je pomoč pri objavljanju hroščev, pregledovanje prevodov in pri razvoju novih možnosti programa. Trenutno je skupnost zelo živa. Napredovanje projekta se zanaša tudi na finančne donacije za nove zmožnosti in preizkušanje delovanja.</string>
</resources>

View file

@ -2209,4 +2209,5 @@
<string name="mapillary_menu_title_dates">Tarih</string>
<string name="mapillary_menu_edit_text_hint">Kullanıcı adını yazın</string>
<string name="mapillary_menu_descr_username">Belirli bir kullanıcı tarafından eklenen görüntüleri görüntüleyin.</string>
<string name="route_point">Güzergah noktası</string>
</resources>

View file

@ -258,5 +258,8 @@
<color name="map_background_color_dark">#101821</color>
<color name="fab_green">#46bd2a</color>
<color name="map_markers_on_map_divider_color">#0d464a</color>
<color name="map_markers_on_map_color">#17828a</color>
<color name="show_direction_menu_selected_item_bg">#f2f4ff</color>
</resources>

View file

@ -3469,4 +3469,13 @@
<string name="poi_network">Network</string>
<string name="poi_government_archive">Archive</string>
<string name="poi_government_ministry">Ministry</string>
<string name="poi_government_public_service">Public service</string>
<string name="poi_government_social_security">Social security</string>
<string name="poi_government_social_services">Social services</string>
<string name="poi_government_treasury">Treasury</string>
<string name="poi_government_transportation">Transport institution</string>
<string name="poi_government_legislative">Legislative institution</string>
</resources>

View file

@ -156,14 +156,14 @@
<dimen name="my_places_empty_state_text_button_padding_right">60dp</dimen>
<dimen name="my_places_empty_state_text_button_padding_top">64dp</dimen>
<dimen name="measure_distance_bottom_sheet_cancel_button_height">48dp</dimen>
<dimen name="bottom_sheet_cancel_button_height">48dp</dimen>
<dimen name="landscape_bottom_sheet_dialog_fragment_width">360dp</dimen>
<dimen name="measurement_tool_select_radius">20dp</dimen>
<dimen name="measurement_tool_content_margin">16dp</dimen>
<dimen name="measurement_tool_content_margin_small">8dp</dimen>
<dimen name="measurement_tool_content_padding">16dp</dimen>
<dimen name="measurement_tool_content_padding_small">8dp</dimen>
<dimen name="bottom_sheet_content_margin">16dp</dimen>
<dimen name="bottom_sheet_content_margin_small">8dp</dimen>
<dimen name="bottom_sheet_content_padding">16dp</dimen>
<dimen name="bottom_sheet_content_padding_small">8dp</dimen>
<dimen name="measurement_tool_divider_margin">8dp</dimen>
<dimen name="measurement_tool_content_padding_medium">12dp</dimen>
<dimen name="measurement_tool_text_margin_small">4dp</dimen>
@ -178,13 +178,13 @@
<dimen name="measurement_tool_button_margin">8dp</dimen>
<dimen name="measurement_tool_button_padding">8dp</dimen>
<dimen name="measurement_tool_button_height">36dp</dimen>
<dimen name="measurement_tool_bottom_title_height">52dp</dimen>
<dimen name="measurement_tool_bottom_descr_height">44dp</dimen>
<dimen name="measurement_tool_bottom_list_item_height">48dp</dimen>
<dimen name="measurement_tool_bottom_icon_margin">24dp</dimen>
<dimen name="bottom_sheet_title_height">52dp</dimen>
<dimen name="bottom_sheet_descr_height">44dp</dimen>
<dimen name="bottom_sheet_list_item_height">48dp</dimen>
<dimen name="bottom_sheet_icon_margin">24dp</dimen>
<dimen name="measurement_tool_bottom_divider_margin_top">7dp</dimen>
<dimen name="measurement_tool_bottom_divider_margin_bottom">8dp</dimen>
<dimen name="measurement_tool_bottom_divider_margin_start">64dp</dimen>
<dimen name="measurement_tool_bottom_image_text_margin_start">10dp</dimen>
<dimen name="measurement_tool_selected_point_title_height">56dp</dimen>
<dimen name="bottom_sheet_image_text_margin_start">10dp</dimen>
<dimen name="bottom_sheet_selected_item_title_height">56dp</dimen>
</resources>

View file

@ -11,11 +11,23 @@
-->
<string name="map_orientation_change_in_accordance_with_speed">Map orientation change in accordance with speed</string>
<string name="map_orientation_change_in_accordance_with_speed_descr">Use built in compass instead of direction of movement to determine map orientation at low speed</string>
<string name="all_markers_moved_to_history">All markers moved to History</string>
<string name="marker_moved_to_history">Marker moved to History</string>
<string name="marker_moved_to_active">Marker moved to Active</string>
<string name="shared_string_list">List</string>
<string name="shared_string_groups">Groups</string>
<string name="passed">Passed: %1$s</string>
<string name="make_active">Make active</string>
<string name="today">Today</string>
<string name="yesterday">Yesterday</string>
<string name="last_seven_days">Last 7 days</string>
<string name="this_year">This year</string>
<string name="widget">Widget</string>
<string name="top_bar">Top bar</string>
<string name="move_all_to_history">Move all to history</string>
<string name="build_route">Build route</string>
<string name="show_direction">Show direction</string>
<string name="sort_by">Sort by</string>
<string name="marker_options">Marker options</string>
<string name="do_not_use_animations">Do not use animations</string>
<string name="do_not_use_animations_descr">Disables animations in the app</string>
<string name="keep_showing_on_map">Keep showing on map</string>

View file

@ -797,7 +797,7 @@ public class OsmandAidlApi {
List<MapMarker> mapMarkers = markersHelper.getMapMarkers();
for (MapMarker m : mapMarkers) {
if (m.getOnlyName().equals(marker.getName()) && latLon.equals(new LatLon(m.getLatitude(), m.getLongitude()))) {
markersHelper.removeMapMarker(m);
markersHelper.moveMapMarkerToHistory(m);
refreshMap();
return true;
}
@ -818,7 +818,10 @@ public class OsmandAidlApi {
if (m.getOnlyName().equals(markerPrev.getName()) && latLon.equals(new LatLon(m.getLatitude(), m.getLongitude()))) {
PointDescription pd = new PointDescription(
PointDescription.POINT_TYPE_MAP_MARKER, markerNew.getName() != null ? markerNew.getName() : "");
MapMarker marker = new MapMarker(m.point, pd, m.colorIndex, m.selected, m.creationDate, m.index);
MapMarker marker = new MapMarker(m.point, pd, m.colorIndex, m.selected, m.index);
marker.id = m.id;
marker.creationDate = m.creationDate;
marker.visitedDate = m.visitedDate;
markersHelper.moveMapMarker(marker, latLonNew);
refreshMap();
return true;

View file

@ -29,6 +29,7 @@ import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask;
import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.helpers.WaypointHelper;
import net.osmand.plus.liveupdates.LiveUpdatesHelper;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.monitoring.LiveMonitoringHelper;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.poi.PoiFiltersHelper;
@ -373,6 +374,7 @@ public class AppInitializer implements IProgress {
app.rendererRegistry = startupInit(new RendererRegistry(app), RendererRegistry.class);
app.geocodingLookupService = startupInit(new GeocodingLookupService(app), GeocodingLookupService.class);
app.targetPointsHelper = startupInit(new TargetPointsHelper(app), TargetPointsHelper.class);
app.mapMarkersDbHelper = startupInit(new MapMarkersDbHelper(app), MapMarkersDbHelper.class);
app.mapMarkersHelper = startupInit(new MapMarkersHelper(app), MapMarkersHelper.class);
app.searchUICore = startupInit(new QuickSearchHelper(app), QuickSearchHelper.class);
}
@ -499,6 +501,7 @@ public class AppInitializer implements IProgress {
startBgTime = System.currentTimeMillis();
app.favorites.loadFavorites();
notifyEvent(InitEvents.FAVORITES_INITIALIZED);
app.mapMarkersHelper.syncAllGroups();
// init poi types before indexes and before POI
initPoiTypes();
notifyEvent(InitEvents.POI_TYPES_INITIALIZED);

View file

@ -7,6 +7,7 @@ import net.osmand.PlatformUtil;
import net.osmand.data.FavouritePoint;
import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.MapMarkersHelper.MarkersSyncGroup;
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
import net.osmand.plus.api.SQLiteAPI.SQLiteCursor;
import net.osmand.util.Algorithms;
@ -20,6 +21,7 @@ import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -33,7 +35,7 @@ public class FavouritesDbHelper {
private static final org.apache.commons.logging.Log log = PlatformUtil.getLog(FavouritesDbHelper.class);
public static final String FILE_TO_SAVE = "favourites.gpx"; //$NON-NLS-1$
public static final String BACKUP_FOLDER = "backup"; //$NON-NLS-1$
public static final int BACKUP_CNT = 20; //$NON-NLS-1$
@ -45,27 +47,27 @@ public class FavouritesDbHelper {
private final OsmandApplication context;
protected static final String HIDDEN = "HIDDEN";
private static final String DELIMETER = "__";
public FavouritesDbHelper(OsmandApplication context) {
this.context = context;
}
public static class FavoriteGroup {
public String name;
public boolean visible = true;
public int color;
public List<FavouritePoint> points = new ArrayList<FavouritePoint>();
}
public void loadFavorites() {
flatGroups.clear();
favoriteGroups.clear();
File internalFile = getInternalFile();
if(!internalFile.exists()) {
if (!internalFile.exists()) {
File dbPath = context.getDatabasePath(FAVOURITE_DB_NAME);
if(dbPath.exists()) {
if (dbPath.exists()) {
loadAndCheckDatabasePoints();
saveCurrentPointsIntoFile();
}
@ -76,28 +78,28 @@ public class FavouritesDbHelper {
loadGPXFile(internalFile, points);
loadGPXFile(getExternalFile(), extPoints);
boolean changed = merge(extPoints, points);
for(FavouritePoint pns : points.values()) {
for (FavouritePoint pns : points.values()) {
FavoriteGroup group = getOrCreateGroup(pns, 0);
group.points.add(pns);
}
sortAll();
recalculateCachedFavPoints();
if(changed) {
if (changed) {
saveCurrentPointsIntoFile();
}
favouritesUpdated();
}
private void favouritesUpdated(){
private void favouritesUpdated() {
}
private boolean merge(Map<String, FavouritePoint> source, Map<String, FavouritePoint> destination) {
boolean changed = false;
for(String ks : source.keySet()) {
if(!destination.containsKey(ks)) {
for (String ks : source.keySet()) {
if (!destination.containsKey(ks)) {
changed = true;
destination.put(ks, source.get(ks));
}
@ -106,31 +108,36 @@ public class FavouritesDbHelper {
}
private File getInternalFile() {
return context.getFileStreamPath(FILE_TO_BACKUP);
}
public void delete(Set<FavoriteGroup> groupsToDelete, Set<FavouritePoint> favoritesSelected) {
if (favoritesSelected != null) {
Set<FavoriteGroup> groupsToSync = new HashSet<>();
for (FavouritePoint p : favoritesSelected) {
FavoriteGroup group = flatGroups.get(p.getCategory());
if (group != null) {
group.points.remove(p);
groupsToSync.add(group);
}
cachedFavoritePoints.remove(p);
}
for (FavoriteGroup gr : groupsToSync) {
context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(gr.name, gr.name, MarkersSyncGroup.FAVORITES_TYPE));
}
}
if (groupsToDelete != null) {
for (FavoriteGroup g : groupsToDelete) {
flatGroups.remove(g.name);
favoriteGroups.remove(g);
cachedFavoritePoints.removeAll(g.points);
context.getMapMarkersHelper().removeMarkersSyncGroup(g.name, true);
}
}
saveCurrentPointsIntoFile();
}
public boolean deleteFavourite(FavouritePoint p) {
return deleteFavourite(p, true);
}
@ -140,6 +147,7 @@ public class FavouritesDbHelper {
FavoriteGroup group = flatGroups.get(p.getCategory());
if (group != null) {
group.points.remove(p);
context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE));
}
cachedFavoritePoints.remove(p);
}
@ -148,7 +156,7 @@ public class FavouritesDbHelper {
}
return true;
}
public boolean addFavourite(FavouritePoint p) {
return addFavourite(p, true);
}
@ -169,10 +177,11 @@ public class FavouritesDbHelper {
sortAll();
saveCurrentPointsIntoFile();
}
context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE));
return true;
}
public static AlertDialog.Builder checkDuplicates(FavouritePoint p, FavouritesDbHelper fdb, Context uiContext) {
boolean emoticons = false;
String index = "";
@ -201,7 +210,7 @@ public class FavouritesDbHelper {
}
}
}
if ((index.length() > 0 || emoticons) ) {
if ((index.length() > 0 || emoticons)) {
AlertDialog.Builder builder = new AlertDialog.Builder(uiContext);
builder.setTitle(R.string.fav_point_dublicate);
if (emoticons) {
@ -215,7 +224,7 @@ public class FavouritesDbHelper {
return null;
}
public static String checkEmoticons(String name){
public static String checkEmoticons(String name) {
char[] chars = name.toCharArray();
int index;
char ch1;
@ -225,16 +234,15 @@ public class FavouritesDbHelper {
StringBuilder builder = new StringBuilder();
while (index < chars.length) {
ch1 = chars[index];
if ((int)ch1 == 0xD83C) {
ch2 = chars[index+1];
if ((int)ch2 >= 0xDF00 && (int)ch2 <= 0xDFFF) {
if ((int) ch1 == 0xD83C) {
ch2 = chars[index + 1];
if ((int) ch2 >= 0xDF00 && (int) ch2 <= 0xDFFF) {
index += 2;
continue;
}
}
else if ((int)ch1 == 0xD83D) {
ch2 = chars[index+1];
if ((int)ch2 >= 0xDC00 && (int)ch2 <= 0xDDFF) {
} else if ((int) ch1 == 0xD83D) {
ch2 = chars[index + 1];
if ((int) ch2 >= 0xDC00 && (int) ch2 <= 0xDDFF) {
index += 2;
continue;
}
@ -264,22 +272,23 @@ public class FavouritesDbHelper {
}
sortAll();
saveCurrentPointsIntoFile();
context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(category, category, MarkersSyncGroup.FAVORITES_TYPE));
return true;
}
public boolean editFavourite(FavouritePoint p, double lat, double lon) {
p.setLatitude(lat);
p.setLongitude(lon);
saveCurrentPointsIntoFile();
context.getMapMarkersHelper().syncGroup(new MarkersSyncGroup(p.getCategory(), p.getCategory(), MarkersSyncGroup.FAVORITES_TYPE));
return true;
}
public void saveCurrentPointsIntoFile() {
try {
Map<String, FavouritePoint> deletedInMemory = new LinkedHashMap<String, FavouritePoint>();
loadGPXFile(getInternalFile(), deletedInMemory);
for(FavouritePoint fp : cachedFavoritePoints) {
for (FavouritePoint fp : cachedFavoritePoints) {
deletedInMemory.remove(getKey(fp));
}
saveFile(cachedFavoritePoints, getInternalFile());
@ -289,7 +298,7 @@ public class FavouritesDbHelper {
log.error(e.getMessage(), e);
}
}
private void backup(File backupFile, File externalFile) {
try {
File f = new File(backupFile.getParentFile(), backupFile.getName());
@ -312,18 +321,17 @@ public class FavouritesDbHelper {
}
private String saveExternalFile(Set<String> deleted) {
Map<String, FavouritePoint> all = new LinkedHashMap<String, FavouritePoint>();
loadGPXFile(getExternalFile(), all);
List<FavouritePoint> favoritePoints = new ArrayList<FavouritePoint>(cachedFavoritePoints);
if(deleted != null) {
for(String key : deleted) {
if (deleted != null) {
for (String key : deleted) {
all.remove(key);
}
}
// remove already existing in memory
for(FavouritePoint p : favoritePoints) {
for (FavouritePoint p : favoritePoints) {
all.remove(getKey(p));
}
// save favoritePoints from memory in order to update existing
@ -332,18 +340,16 @@ public class FavouritesDbHelper {
}
private String getKey(FavouritePoint p) {
return p.getName() + DELIMETER + p.getCategory();
}
public boolean deleteGroup(FavoriteGroup group) {
boolean remove = favoriteGroups.remove(group);
if (remove) {
flatGroups.remove(group.name);
saveCurrentPointsIntoFile();
context.getMapMarkersHelper().removeMarkersSyncGroup(group.name, true);
return true;
}
return false;
@ -352,53 +358,53 @@ public class FavouritesDbHelper {
public File getExternalFile() {
return new File(context.getAppPath(null), FILE_TO_SAVE);
}
public File getBackupFile() {
File fld = new File(context.getAppPath(null), BACKUP_FOLDER);
if(!fld.exists()) {
if (!fld.exists()) {
fld.mkdirs();
}
int back = 1;
String backPrefix = "" + back;
File firstModified = null;
long firstModifiedMin = System.currentTimeMillis();
while(back <= BACKUP_CNT) {
while (back <= BACKUP_CNT) {
backPrefix = "" + back;
if(back < 10) {
backPrefix = "0"+backPrefix;
if (back < 10) {
backPrefix = "0" + backPrefix;
}
File bak = new File(fld, "favourites_bak_" + backPrefix +".gpx.bz2");
File bak = new File(fld, "favourites_bak_" + backPrefix + ".gpx.bz2");
if (!bak.exists()) {
return bak;
} else if (bak.lastModified() < firstModifiedMin) {
firstModified = bak;
firstModifiedMin = bak.lastModified();
}
back ++;
back++;
}
return firstModified;
}
public String saveFile(List<FavouritePoint> favoritePoints, File f) {
GPXFile gpx = asGpxFile(favoritePoints);
return GPXUtilities.writeGpxFile(f, gpx, context);
}
public GPXFile asGpxFile() {
return asGpxFile(cachedFavoritePoints);
}
private GPXFile asGpxFile(List<FavouritePoint> favoritePoints) {
GPXFile gpx = new GPXFile();
for (FavouritePoint p : favoritePoints) {
WptPt pt = new WptPt();
pt.lat = p.getLatitude();
pt.lon = p.getLongitude();
if(!p.isVisible()) {
if (!p.isVisible()) {
pt.getExtensionsToWrite().put(HIDDEN, "true");
}
if(p.getColor() != 0) {
if (p.getColor() != 0) {
pt.setColor(p.getColor());
}
pt.name = p.getName();
@ -413,7 +419,7 @@ public class FavouritesDbHelper {
return gpx;
}
public void addEmptyCategory(String name) {
addEmptyCategory(name, 0, true);
}
@ -434,17 +440,17 @@ public class FavouritesDbHelper {
public List<FavouritePoint> getFavouritePoints() {
return cachedFavoritePoints;
}
public List<FavouritePoint> getVisibleFavouritePoints() {
List<FavouritePoint> fp = new ArrayList<>();
for(FavouritePoint p : cachedFavoritePoints) {
if(p.isVisible()) {
for (FavouritePoint p : cachedFavoritePoints) {
if (p.isVisible()) {
fp.add(p);
}
}
return fp;
}
public List<FavoriteGroup> getFavoriteGroups() {
return favoriteGroups;
@ -476,7 +482,7 @@ public class FavouritesDbHelper {
}
}
private FavouritePoint findFavoriteByAllProperties(String category, String name, double lat, double lon){
private FavouritePoint findFavoriteByAllProperties(String category, String name, double lat, double lon) {
if (flatGroups.containsKey(category)) {
FavoriteGroup fg = flatGroups.get(category);
for (FavouritePoint fv : fg.points) {
@ -488,16 +494,15 @@ public class FavouritesDbHelper {
return null;
}
public void recalculateCachedFavPoints(){
public void recalculateCachedFavPoints() {
ArrayList<FavouritePoint> temp = new ArrayList<FavouritePoint>();
for(FavoriteGroup f : favoriteGroups){
for (FavoriteGroup f : favoriteGroups) {
temp.addAll(f.points);
}
cachedFavoritePoints = temp;
}
public void sortAll() {
final Collator collator = Collator.getInstance();
collator.setStrength(Collator.SECONDARY);
@ -550,10 +555,10 @@ public class FavouritesDbHelper {
};
return favoritesComparator;
}
private boolean loadGPXFile(File file, Map<String, FavouritePoint> points) {
if(!file.exists()) {
if (!file.exists()) {
return false;
}
GPXFile res = GPXUtilities.loadGPXFile(context, file);
@ -583,39 +588,45 @@ public class FavouritesDbHelper {
}
return true;
}
public void editFavouriteGroup(FavoriteGroup group, String newName, int color, boolean visible) {
if(color != 0 && group.color != color) {
MapMarkersHelper markersHelper = context.getMapMarkersHelper();
if (color != 0 && group.color != color) {
FavoriteGroup gr = flatGroups.get(group.name);
group.color = color;
for(FavouritePoint p : gr.points) {
for (FavouritePoint p : gr.points) {
p.setColor(color);
}
}
}
if(group.visible != visible) {
if (group.visible != visible) {
FavoriteGroup gr = flatGroups.get(group.name);
group.visible = visible;
for(FavouritePoint p : gr.points) {
for (FavouritePoint p : gr.points) {
p.setVisible(visible);
}
}
markersHelper.syncGroup(new MarkersSyncGroup(gr.name, gr.name, MarkersSyncGroup.FAVORITES_TYPE));
}
if (!group.name.equals(newName)) {
FavoriteGroup gr = flatGroups.remove(group.name);
markersHelper.removeMarkersSyncGroup(group.name, true);
gr.name = newName;
FavoriteGroup renamedGroup = flatGroups.get(gr.name);
boolean existing = renamedGroup != null;
if(renamedGroup == null) {
if (renamedGroup == null) {
renamedGroup = gr;
flatGroups.put(gr.name, gr);
} else {
favoriteGroups.remove(gr);
}
for(FavouritePoint p : gr.points) {
for (FavouritePoint p : gr.points) {
p.setCategory(newName);
if(existing) {
if (existing) {
renamedGroup.points.add(p);
}
}
MarkersSyncGroup syncGroup = new MarkersSyncGroup(renamedGroup.name, renamedGroup.name, MarkersSyncGroup.FAVORITES_TYPE);
markersHelper.addMarkersSyncGroup(syncGroup);
markersHelper.syncGroup(syncGroup);
}
saveCurrentPointsIntoFile();
}
@ -643,7 +654,7 @@ public class FavouritesDbHelper {
return group;
}
/// Deprecated sqlite db
private static final int DATABASE_VERSION = 2;
public static final String FAVOURITE_DB_NAME = "favourite"; //$NON-NLS-1$
@ -656,8 +667,8 @@ public class FavouritesDbHelper {
FAVOURITE_COL_NAME + " TEXT, " + FAVOURITE_COL_CATEGORY + " TEXT, " + //$NON-NLS-1$ //$NON-NLS-2$
FAVOURITE_COL_LAT + " double, " + FAVOURITE_COL_LON + " double);"; //$NON-NLS-1$ //$NON-NLS-2$
private SQLiteConnection conn;
private SQLiteConnection openConnection(boolean readonly) {
conn = context.getSQLiteAPI().getOrCreateDatabase(FAVOURITE_DB_NAME, readonly);
if (conn.getVersion() == 0 || DATABASE_VERSION != conn.getVersion()) {
@ -674,19 +685,19 @@ public class FavouritesDbHelper {
}
return conn;
}
public void onCreate(SQLiteConnection db) {
db.execSQL(FAVOURITE_TABLE_CREATE);
}
public void onUpgrade(SQLiteConnection db, int oldVersion, int newVersion) {
if(oldVersion == 1){
db.execSQL("ALTER TABLE " + FAVOURITE_TABLE_NAME + " ADD " + FAVOURITE_COL_CATEGORY + " text");
db.execSQL("UPDATE " + FAVOURITE_TABLE_NAME + " SET category = ?", new Object[] { "" }); //$NON-NLS-1$ //$NON-NLS-2$
if (oldVersion == 1) {
db.execSQL("ALTER TABLE " + FAVOURITE_TABLE_NAME + " ADD " + FAVOURITE_COL_CATEGORY + " text");
db.execSQL("UPDATE " + FAVOURITE_TABLE_NAME + " SET category = ?", new Object[]{""}); //$NON-NLS-1$ //$NON-NLS-2$
}
}
private void loadAndCheckDatabasePoints(){
private void loadAndCheckDatabasePoints() {
if (favoriteGroups == null) {
SQLiteConnection db = openConnection(true);
if (db != null) {
@ -715,29 +726,29 @@ public class FavouritesDbHelper {
query.close();
} finally {
db.close();
}
}
sortAll();
}
recalculateCachedFavPoints();
}
}
public boolean deleteFavouriteDB(FavouritePoint p) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL(
"DELETE FROM " + FAVOURITE_TABLE_NAME + " WHERE category = ? AND " + whereNameLatLon(), new Object[] { p.getCategory(), p.getName(), p.getLatitude(), p.getLongitude() }); //$NON-NLS-1$ //$NON-NLS-2$
"DELETE FROM " + FAVOURITE_TABLE_NAME + " WHERE category = ? AND " + whereNameLatLon(), new Object[]{p.getCategory(), p.getName(), p.getLatitude(), p.getLongitude()}); //$NON-NLS-1$ //$NON-NLS-2$
FavouritePoint fp = findFavoriteByAllProperties(p.getCategory(), p.getName(), p.getLatitude(), p.getLongitude());
if (fp != null) {
FavoriteGroup group = flatGroups.get(p.getCategory());
if(group != null) {
if (group != null) {
group.points.remove(fp);
}
cachedFavoritePoints.remove(fp);
}
saveCurrentPointsIntoFile();
} finally{
} finally {
db.close();
}
return true;
@ -747,7 +758,7 @@ public class FavouritesDbHelper {
public boolean addFavouriteDB(FavouritePoint p) {
if(p.getName().equals("") && flatGroups.containsKey(p.getCategory())){
if (p.getName().equals("") && flatGroups.containsKey(p.getCategory())) {
return true;
}
SQLiteConnection db = openConnection(false);
@ -755,8 +766,8 @@ public class FavouritesDbHelper {
try {
db.execSQL(
"INSERT INTO " + FAVOURITE_TABLE_NAME + " (" + FAVOURITE_COL_NAME + ", " + FAVOURITE_COL_CATEGORY + ", "
+ FAVOURITE_COL_LAT + ", " + FAVOURITE_COL_LON + ")" + " VALUES (?, ?, ?, ?)", new Object[] { p.getName(), p.getCategory(), p.getLatitude(), p.getLongitude() }); //$NON-NLS-1$ //$NON-NLS-2$
FavoriteGroup group = getOrCreateGroup(p, 0);
+ FAVOURITE_COL_LAT + ", " + FAVOURITE_COL_LON + ")" + " VALUES (?, ?, ?, ?)", new Object[]{p.getName(), p.getCategory(), p.getLatitude(), p.getLongitude()}); //$NON-NLS-1$ //$NON-NLS-2$
FavoriteGroup group = getOrCreateGroup(p, 0);
if (!p.getName().equals("")) {
p.setVisible(group.visible);
p.setColor(group.color);
@ -771,8 +782,7 @@ public class FavouritesDbHelper {
}
return false;
}
public boolean editFavouriteNameDB(FavouritePoint p, String newName, String category) {
SQLiteConnection db = openConnection(false);
@ -780,7 +790,7 @@ public class FavouritesDbHelper {
try {
String oldCategory = p.getCategory();
db.execSQL(
"UPDATE " + FAVOURITE_TABLE_NAME + " SET " + FAVOURITE_COL_NAME + " = ?, " + FAVOURITE_COL_CATEGORY + "= ? WHERE " + whereNameLatLon(), new Object[] { newName, category, p.getName(), p.getLatitude(), p.getLongitude() }); //$NON-NLS-1$ //$NON-NLS-2$
"UPDATE " + FAVOURITE_TABLE_NAME + " SET " + FAVOURITE_COL_NAME + " = ?, " + FAVOURITE_COL_CATEGORY + "= ? WHERE " + whereNameLatLon(), new Object[]{newName, category, p.getName(), p.getLatitude(), p.getLongitude()}); //$NON-NLS-1$ //$NON-NLS-2$
p.setName(newName);
p.setCategory(category);
if (!oldCategory.equals(category)) {
@ -801,14 +811,14 @@ public class FavouritesDbHelper {
}
return false;
}
public boolean editFavouriteDB(FavouritePoint p, double lat, double lon) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL(
"UPDATE " + FAVOURITE_TABLE_NAME + " SET latitude = ?, longitude = ? WHERE " + whereNameLatLon(), new Object[] { lat, lon, p.getName(), p.getLatitude(), p.getLongitude() }); //$NON-NLS-1$ //$NON-NLS-2$
"UPDATE " + FAVOURITE_TABLE_NAME + " SET latitude = ?, longitude = ? WHERE " + whereNameLatLon(), new Object[]{lat, lon, p.getName(), p.getLatitude(), p.getLongitude()}); //$NON-NLS-1$ //$NON-NLS-2$
p.setLatitude(lat);
p.setLongitude(lon);
saveCurrentPointsIntoFile();
@ -826,6 +836,4 @@ public class FavouritesDbHelper {
}
}

View file

@ -1,24 +1,40 @@
package net.osmand.plus;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.format.DateFormat;
import net.osmand.IndexConstants;
import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon;
import net.osmand.data.LocationPoint;
import net.osmand.data.PointDescription;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.util.Algorithms;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import static net.osmand.data.PointDescription.POINT_TYPE_MAP_MARKER;
public class MapMarkersHelper {
public static final int MAP_MARKERS_COLORS_COUNT = 7;
private List<MapMarker> mapMarkers = new ArrayList<>();
private List<MapMarker> mapMarkersHistory = new ArrayList<>();
private List<MapMarker> mapMarkers = new LinkedList<>();
private List<MapMarker> mapMarkersHistory = new LinkedList<>();
private OsmandSettings settings;
private List<MapMarkerChangedListener> listeners = new ArrayList<>();
private OsmandApplication ctx;
private MapMarkersDbHelper markersDbHelper;
private boolean startFromMyLocation;
public interface MapMarkerChangedListener {
@ -28,6 +44,7 @@ public class MapMarkersHelper {
}
public static class MapMarker implements LocationPoint {
public String id;
public LatLon point;
private PointDescription pointDescription;
public int colorIndex;
@ -36,19 +53,22 @@ public class MapMarkersHelper {
public boolean selected;
public int dist;
public long creationDate;
public long visitedDate;
public String nextKey;
public String groupKey;
public String groupName;
public MapMarker(LatLon point, PointDescription name, int colorIndex,
boolean selected, long creationDate, int index) {
boolean selected, int index) {
this.point = point;
this.pointDescription = name;
this.colorIndex = colorIndex;
this.selected = selected;
this.creationDate = creationDate;
this.index = index;
}
public PointDescription getPointDescription(Context ctx) {
return new PointDescription(PointDescription.POINT_TYPE_MAP_MARKER, ctx.getString(R.string.map_marker),
return new PointDescription(POINT_TYPE_MAP_MARKER, ctx.getString(R.string.map_marker),
getOnlyName());
}
@ -139,11 +159,40 @@ public class MapMarkersHelper {
}
}
public static class MarkersSyncGroup {
public static final int FAVORITES_TYPE = 0;
public static final int GPX_TYPE = 1;
private String id;
private String name;
private int type;
public MarkersSyncGroup(@NonNull String id, @NonNull String name, int type) {
this.id = id;
this.name = name;
this.type = type;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public int getType() {
return type;
}
}
public MapMarkersHelper(OsmandApplication ctx) {
this.ctx = ctx;
settings = ctx.getSettings();
markersDbHelper = ctx.getMapMarkersDbHelper();
startFromMyLocation = settings.ROUTE_MAP_MARKERS_START_MY_LOC.get();
readFromSettings();
loadMarkers();
}
public boolean isStartFromMyLocation() {
@ -157,86 +206,212 @@ public class MapMarkersHelper {
public void lookupAddressAll() {
for (MapMarker mapMarker : mapMarkers) {
lookupAddress(mapMarker, false);
lookupAddress(mapMarker);
}
for (MapMarker mapMarker : mapMarkersHistory) {
lookupAddress(mapMarker, true);
lookupAddress(mapMarker);
}
}
private void readFromSettings() {
private void loadMarkers() {
mapMarkers.clear();
mapMarkersHistory.clear();
List<LatLon> ips = settings.getMapMarkersPoints();
List<String> desc = settings.getMapMarkersPointDescriptions(ips.size());
List<Integer> colors = settings.getMapMarkersColors(ips.size());
List<Boolean> selections = settings.getMapMarkersSelections(ips.size());
List<Long> creationDates = settings.getMapMarkersCreationDates(ips.size());
int colorIndex = 0;
for (int i = 0; i < ips.size(); i++) {
if (colors.size() > i) {
colorIndex = colors.get(i);
}
MapMarker mapMarker = new MapMarker(ips.get(i),
PointDescription.deserializeFromString(desc.get(i), ips.get(i)), colorIndex,
selections.get(i), creationDates.get(i), i);
mapMarkers.add(mapMarker);
}
ips = settings.getMapMarkersHistoryPoints();
desc = settings.getMapMarkersHistoryPointDescriptions(ips.size());
colors = settings.getMapMarkersHistoryColors(ips.size());
creationDates = settings.getMapMarkersHistoryCreationDates(ips.size());
for (int i = 0; i < ips.size(); i++) {
if (colors.size() > i) {
colorIndex = colors.get(i);
}
MapMarker mapMarker = new MapMarker(ips.get(i),
PointDescription.deserializeFromString(desc.get(i), ips.get(i)),
colorIndex, false, creationDates.get(i), i);
mapMarker.history = true;
mapMarkersHistory.add(mapMarker);
}
List<MapMarker> activeMarkers = markersDbHelper.getActiveMarkers();
mapMarkers.addAll(activeMarkers);
checkAndFixActiveMarkersOrderIfNeeded();
List<MapMarker> markersHistory = markersDbHelper.getMarkersHistory();
sortMarkers(markersHistory, true);
mapMarkersHistory.addAll(markersHistory);
if (!ctx.isApplicationInitializing()) {
lookupAddressAll();
}
}
private void lookupAddress(final MapMarker mapMarker, final boolean history) {
public void checkAndFixActiveMarkersOrderIfNeeded() {
if (!mapMarkers.isEmpty()) {
if (mapMarkers.size() > 1) {
for (int i = 0; i < mapMarkers.size() - 1; i++) {
MapMarker first = mapMarkers.get(i);
MapMarker second = mapMarkers.get(i + 1);
if (!first.nextKey.equals(second.id)) {
markersDbHelper.changeActiveMarkerPosition(first, second);
first.nextKey = second.id;
}
}
}
MapMarker tail = mapMarkers.get(mapMarkers.size() - 1);
if (!tail.nextKey.equals(MapMarkersDbHelper.TAIL_NEXT_VALUE)) {
markersDbHelper.changeActiveMarkerPosition(tail, null);
}
}
}
private void sortMarkers(List<MapMarker> markers, final boolean history) {
Collections.sort(markers, new Comparator<MapMarker>() {
@Override
public int compare(MapMarker mapMarker1, MapMarker mapMarker2) {
long firstMarkerDate = history ? mapMarker1.visitedDate : mapMarker1.creationDate;
long secondMarkerDate = history ? mapMarker2.visitedDate : mapMarker2.creationDate;
if (firstMarkerDate > secondMarkerDate) {
return -1;
} else if (firstMarkerDate == secondMarkerDate) {
return 0;
} else {
return 1;
}
}
});
}
private void lookupAddress(final MapMarker mapMarker) {
if (mapMarker != null && mapMarker.pointDescription.isSearchingAddress(ctx)) {
cancelPointAddressRequests(mapMarker.point);
GeocodingLookupService.AddressLookupRequest lookupRequest = new GeocodingLookupService.AddressLookupRequest(mapMarker.point, new GeocodingLookupService.OnAddressLookupResult() {
@Override
public void geocodingDone(String address) {
if (Algorithms.isEmpty(address)) {
mapMarker.pointDescription.setName(PointDescription.getAddressNotFoundStr(ctx));
} else {
mapMarker.pointDescription.setName(address);
}
if (history) {
settings.updateMapMarkerHistory(mapMarker.point.getLatitude(), mapMarker.point.getLongitude(),
mapMarker.pointDescription, mapMarker.colorIndex, mapMarker.creationDate);
} else {
settings.updateMapMarker(mapMarker.point.getLatitude(), mapMarker.point.getLongitude(),
mapMarker.pointDescription, mapMarker.colorIndex, mapMarker.selected, mapMarker.creationDate);
}
updateMarker(mapMarker);
}
}, null);
GeocodingLookupService.AddressLookupRequest lookupRequest =
new GeocodingLookupService.AddressLookupRequest(mapMarker.point, new GeocodingLookupService.OnAddressLookupResult() {
@Override
public void geocodingDone(String address) {
if (Algorithms.isEmpty(address)) {
mapMarker.pointDescription.setName(PointDescription.getAddressNotFoundStr(ctx));
} else {
mapMarker.pointDescription.setName(address);
}
markersDbHelper.updateMarker(mapMarker);
updateMarker(mapMarker);
}
}, null);
ctx.getGeocodingLookupService().lookupAddress(lookupRequest);
}
}
public void removeMapMarker(int index) {
settings.deleteMapMarker(index);
MapMarker mapMarker = mapMarkers.remove(index);
cancelPointAddressRequests(mapMarker.point);
int ind = 0;
for (MapMarker marker : mapMarkers) {
marker.index = ind++;
public void syncAllGroups() {
List<MarkersSyncGroup> groups = markersDbHelper.getAllGroups();
for (MarkersSyncGroup gr : groups) {
syncGroup(gr);
}
}
public void syncGroup(MarkersSyncGroup group) {
if (markersDbHelper.getGroup(group.getId()) == null) {
return;
}
List<MapMarker> dbMarkers = markersDbHelper.getMarkersFromGroup(group);
if (group.getType() == MarkersSyncGroup.FAVORITES_TYPE) {
FavouritesDbHelper.FavoriteGroup favGroup = ctx.getFavorites().getGroup(group.name);
if (favGroup == null) {
return;
}
if (!favGroup.visible) {
removeActiveMarkersFromSyncGroup(group.id);
return;
}
List<FavouritePoint> favPoints = favGroup.points;
for (FavouritePoint fp : favPoints) {
LatLon fpLatLon = new LatLon(fp.getLatitude(), fp.getLongitude());
boolean exists = false;
for (MapMarker marker : dbMarkers) {
if (marker.id.equals(group.getId() + fp.getName(ctx))) {
exists = true;
if (!marker.history && !marker.point.equals(fpLatLon)) {
for (MapMarker m : mapMarkers) {
if (m.id.equals(marker.id)) {
m.point = fpLatLon;
updateMapMarker(m, true);
break;
}
}
}
dbMarkers.remove(marker);
break;
}
}
if (!exists) {
addMarkers(Collections.singletonList(fpLatLon),
Collections.singletonList(new PointDescription(POINT_TYPE_MAP_MARKER, fp.getName())), group);
}
}
if (!dbMarkers.isEmpty()) {
for (MapMarker marker : dbMarkers) {
if (!marker.history) {
markersDbHelper.removeMarker(marker, false);
mapMarkers.remove(marker);
checkAndFixActiveMarkersOrderIfNeeded();
refresh();
}
}
}
} else {
}
}
public void moveMapMarkerToHistory(MapMarker marker) {
if (marker != null) {
cancelPointAddressRequests(marker.point);
markersDbHelper.moveMarkerToHistory(marker);
mapMarkers.remove(marker);
marker.history = true;
marker.nextKey = MapMarkersDbHelper.HISTORY_NEXT_VALUE;
mapMarkersHistory.add(marker);
checkAndFixActiveMarkersOrderIfNeeded();
sortMarkers(mapMarkersHistory, true);
refresh();
}
}
public void addMarker(MapMarker marker) {
if (marker != null) {
markersDbHelper.addMarker(marker);
if (marker.history) {
mapMarkersHistory.add(marker);
sortMarkers(mapMarkersHistory, true);
} else {
mapMarkers.add(marker);
checkAndFixActiveMarkersOrderIfNeeded();
}
refresh();
}
}
public void restoreMarkerFromHistory(MapMarker marker, int position) {
if (marker != null) {
markersDbHelper.restoreMapMarkerFromHistory(marker);
mapMarkersHistory.remove(marker);
marker.history = false;
mapMarkers.add(position, marker);
checkAndFixActiveMarkersOrderIfNeeded();
sortMarkers(mapMarkersHistory, true);
refresh();
}
}
public void restoreMarkersFromHistory(List<MapMarker> markers) {
if (markers != null) {
for (MapMarker marker : markers) {
markersDbHelper.restoreMapMarkerFromHistory(marker);
mapMarkersHistory.remove(marker);
marker.history = false;
mapMarkers.add(marker);
}
checkAndFixActiveMarkersOrderIfNeeded();
sortMarkers(mapMarkersHistory, true);
refresh();
}
}
public void removeMarkerFromHistory(MapMarker marker) {
if (marker != null) {
markersDbHelper.removeMarker(marker, true);
mapMarkersHistory.remove(marker);
refresh();
}
refresh();
}
public List<MapMarker> getMapMarkers() {
@ -293,58 +468,73 @@ public class MapMarkersHelper {
public void reverseActiveMarkersOrder() {
cancelAddressRequests();
List<MapMarker> markers = new ArrayList<>(mapMarkers.size());
for (int i = mapMarkers.size() - 1; i >= 0; i--) {
MapMarker marker = mapMarkers.get(i);
markers.add(marker);
}
mapMarkers = markers;
saveMapMarkers(mapMarkers, null);
Collections.reverse(mapMarkers);
checkAndFixActiveMarkersOrderIfNeeded();
}
public void removeActiveMarkers() {
public void moveAllActiveMarkersToHistory() {
cancelAddressRequests();
for (int i = mapMarkers.size() - 1; i>= 0; i--) {
MapMarker marker = mapMarkers.get(i);
addMapMarkerHistory(marker);
long timestamp = System.currentTimeMillis();
markersDbHelper.moveAllActiveMarkersToHistory(timestamp);
for (MapMarker marker : mapMarkers) {
marker.visitedDate = timestamp;
marker.history = true;
marker.nextKey = MapMarkersDbHelper.HISTORY_NEXT_VALUE;
}
settings.clearActiveMapMarkers();
readFromSettings();
mapMarkersHistory.addAll(mapMarkers);
mapMarkers.clear();
sortMarkers(mapMarkersHistory, true);
refresh();
}
public void removeMarkersHistory() {
cancelAddressRequests();
settings.clearMapMarkersHistory();
readFromSettings();
markersDbHelper.clearAllMarkersHistory();
mapMarkersHistory.clear();
refresh();
}
public void addMapMarker(MapMarker marker, int index) {
settings.insertMapMarker(marker.getLatitude(), marker.getLongitude(), marker.pointDescription,
marker.colorIndex, marker.selected, marker.creationDate, index);
readFromSettings();
public void addMarkersSyncGroup(MarkersSyncGroup group) {
if (group != null) {
if (markersDbHelper.getGroup(group.getId()) == null) {
markersDbHelper.addGroup(group.getId(), group.getName(), group.getType());
}
}
}
public void removeMarkersSyncGroup(String id, boolean removeActiveMarkers) {
if (id != null) {
markersDbHelper.removeMarkersSyncGroup(id);
if (removeActiveMarkers) {
removeActiveMarkersFromSyncGroup(id);
}
}
}
public void removeActiveMarkersFromSyncGroup(String syncGroupId) {
if (syncGroupId != null) {
markersDbHelper.removeActiveMarkersFromSyncGroup(syncGroupId);
for (Iterator<MapMarker> iterator = mapMarkers.iterator(); iterator.hasNext(); ) {
if (iterator.next().groupKey.equals(syncGroupId)) {
iterator.remove();
}
}
checkAndFixActiveMarkersOrderIfNeeded();
refresh();
}
}
public void addMapMarker(LatLon point, PointDescription historyName) {
List<LatLon> points = new ArrayList<>(1);
List<PointDescription> historyNames = new ArrayList<>(1);
points.add(point);
historyNames.add(historyName);
addMapMarkers(points, historyNames);
addMarkers(Collections.singletonList(point), Collections.singletonList(historyName), null);
}
public void addMapMarkers(List<LatLon> points, List<PointDescription> historyNames) {
public void addMapMarkers(List<LatLon> points, List<PointDescription> historyNames, @Nullable MarkersSyncGroup group) {
addMarkers(points, historyNames, group);
}
private void addMarkers(List<LatLon> points, List<PointDescription> historyNames, @Nullable MarkersSyncGroup group) {
if (points.size() > 0) {
int colorIndex = -1;
double[] latitudes = new double[points.size()];
double[] longitudes = new double[points.size()];
List<PointDescription> pointDescriptions = new ArrayList<>();
int[] colorIndexes = new int[points.size()];
int[] positions = new int[points.size()];
boolean[] selections = new boolean[points.size()];
int[] indexes = new int[points.size()];
for (int i = 0; i < points.size(); i++) {
LatLon point = points.get(i);
PointDescription historyName = historyNames.get(i);
@ -359,7 +549,7 @@ public class MapMarkersHelper {
}
if (colorIndex == -1) {
if (mapMarkers.size() > 0) {
colorIndex = (mapMarkers.get(0).colorIndex + 1) % MAP_MARKERS_COLORS_COUNT;
colorIndex = (mapMarkers.get(mapMarkers.size() - 1).colorIndex + 1) % MAP_MARKERS_COLORS_COUNT;
} else {
colorIndex = 0;
}
@ -367,33 +557,28 @@ public class MapMarkersHelper {
colorIndex = (colorIndex + 1) % MAP_MARKERS_COLORS_COUNT;
}
latitudes[i] = point.getLatitude();
longitudes[i] = point.getLongitude();
pointDescriptions.add(pointDescription);
colorIndexes[i] = colorIndex;
positions[i] = -1 - i;
selections[i] = false;
indexes[i] = 0;
MapMarker marker = new MapMarker(point, pointDescription, colorIndex, false, 0);
if (group != null) {
marker.id = group.getId() + marker.getName(ctx);
if (markersDbHelper.getMarker(marker.id) != null) {
continue;
}
marker.groupName = group.getName();
marker.groupKey = group.getId();
}
marker.history = false;
marker.nextKey = MapMarkersDbHelper.TAIL_NEXT_VALUE;
markersDbHelper.addMarker(marker);
mapMarkers.add(marker);
checkAndFixActiveMarkersOrderIfNeeded();
}
/* adding map marker to second topbar's row
if (sortedMapMarkers.size() > 0) {
MapMarker firstMarker = sortedMapMarkers.get(0);
settings.updateMapMarker(firstMarker.getLatitude(), firstMarker.getLongitude(),
firstMarker.pointDescription, firstMarker.colorIndex, -points.size(), firstMarker.selected);
}
*/
settings.insertMapMarkers(latitudes, longitudes, pointDescriptions, colorIndexes, positions,
selections, indexes);
readFromSettings();
}
}
public void updateMapMarker(MapMarker marker, boolean refresh) {
if (marker != null) {
settings.updateMapMarker(marker.getLatitude(), marker.getLongitude(),
marker.pointDescription, marker.colorIndex, marker.selected, marker.creationDate);
markersDbHelper.updateMarker(marker);
if (refresh) {
readFromSettings();
refresh();
}
}
@ -401,35 +586,24 @@ public class MapMarkersHelper {
public void moveMapMarker(@Nullable MapMarker marker, LatLon latLon) {
if (marker != null) {
settings.moveMapMarker(new LatLon(marker.getLatitude(), marker.getLongitude()), latLon,
marker.pointDescription, marker.colorIndex, marker.selected, marker.creationDate);
marker.point = new LatLon(latLon.getLatitude(), latLon.getLongitude());
readFromSettings();
LatLon point = new LatLon(latLon.getLatitude(), latLon.getLongitude());
int index = mapMarkers.indexOf(marker);
if (index != -1) {
mapMarkers.get(index).point = point;
}
marker.point = point;
markersDbHelper.updateMarker(marker);
checkAndFixActiveMarkersOrderIfNeeded();
refresh();
}
}
public void removeMapMarker(MapMarker marker) {
if (marker != null) {
settings.deleteMapMarker(marker.index);
readFromSettings();
refresh();
}
}
public void addMapMarkerHistory(MapMarker marker) {
if (marker != null) {
settings.insertMapMarkerHistory(marker.getLatitude(), marker.getLongitude(),
marker.pointDescription, marker.colorIndex, marker.creationDate, 0);
readFromSettings();
refresh();
}
}
public void removeMapMarkerHistory(MapMarker marker) {
if (marker != null) {
settings.deleteMapMarkerHistory(marker.index);
readFromSettings();
public void moveMarkerToTop(MapMarker marker) {
int i = mapMarkers.indexOf(marker);
if (i != -1 && mapMarkers.size() > 1) {
mapMarkers.remove(i);
mapMarkers.add(0, marker);
checkAndFixActiveMarkersOrderIfNeeded();
refresh();
}
}
@ -466,7 +640,7 @@ public class MapMarkersHelper {
}
if (markers != null || markersHistory != null) {
readFromSettings();
loadMarkers();
refresh();
}
}
@ -513,4 +687,28 @@ public class MapMarkersHelper {
ctx.getGeocodingLookupService().cancel(latLon);
}
}
public void generateGpx() {
final File dir = ctx.getAppPath(IndexConstants.GPX_INDEX_DIR + "/map markers");
if (!dir.exists()) {
dir.mkdirs();
}
Date date = new Date();
String fileName = DateFormat.format("yyyy-MM-dd", date).toString() + "_" + new SimpleDateFormat("HH-mm_EEE", Locale.US).format(date);
File fout = new File(dir, fileName + ".gpx");
int ind = 1;
while (fout.exists()) {
fout = new File(dir, fileName + "_" + (++ind) + ".gpx");
}
GPXUtilities.GPXFile file = new GPXUtilities.GPXFile();
for (MapMarker marker : markersDbHelper.getActiveMarkers()) {
GPXUtilities.WptPt wpt = new GPXUtilities.WptPt();
wpt.lat = marker.getLatitude();
wpt.lon = marker.getLongitude();
wpt.setColor(ctx.getResources().getColor(MapMarker.getColorId(marker.colorIndex)));
wpt.name = marker.getOnlyName();
file.points.add(wpt);
}
GPXUtilities.writeGpxFile(fout, file, ctx);
}
}

View file

@ -47,6 +47,7 @@ import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.helpers.WaypointHelper;
import net.osmand.plus.inapp.InAppHelper;
import net.osmand.plus.mapcontextmenu.other.RoutePreferencesMenu;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.monitoring.LiveMonitoringHelper;
import net.osmand.plus.poi.PoiFiltersHelper;
import net.osmand.plus.render.RendererRegistry;
@ -107,6 +108,7 @@ public class OsmandApplication extends MultiDexApplication {
LiveMonitoringHelper liveMonitoringHelper;
TargetPointsHelper targetPointsHelper;
MapMarkersHelper mapMarkersHelper;
MapMarkersDbHelper mapMarkersDbHelper;
WaypointHelper waypointHelper;
DownloadIndexesThread downloadIndexesThread;
AvoidSpecificRoads avoidSpecificRoads;
@ -615,6 +617,10 @@ public class OsmandApplication extends MultiDexApplication {
return mapMarkersHelper;
}
public MapMarkersDbHelper getMapMarkersDbHelper() {
return mapMarkersDbHelper;
}
public void showShortToastMessage(final int msgId, final Object... args) {
uiHandler.post(new Runnable() {
@Override

View file

@ -6,6 +6,8 @@ import android.app.backup.BackupAgentHelper;
import android.app.backup.FileBackupHelper;
import android.app.backup.SharedPreferencesBackupHelper;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
/**
* Requires android API from android-8
*/
@ -25,7 +27,7 @@ public class OsmandBackupAgent extends BackupAgentHelper {
SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, prefs);
addHelper("osmand.settings", helper);
FileBackupHelper fileBackupHelper = new FileBackupHelper(this, FavouritesDbHelper.FILE_TO_BACKUP);
addHelper(FavouritesDbHelper.FILE_TO_BACKUP, fileBackupHelper);
FileBackupHelper fileBackupHelper = new FileBackupHelper(this, FavouritesDbHelper.FILE_TO_BACKUP, "../databases/" + MapMarkersDbHelper.DB_NAME);
addHelper("osmand.files", fileBackupHelper);
}
}

View file

@ -30,6 +30,7 @@ import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.FavouritesDbHelper.FavoriteGroup;
import net.osmand.plus.IconsCache;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MarkersSyncGroup;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment;
@ -188,7 +189,9 @@ public class EditFavoriteGroupDialogFragment extends BottomSheetDialogFragment {
points.add(new LatLon(fp.getLatitude(), fp.getLongitude()));
names.add(new PointDescription(PointDescription.POINT_TYPE_MAP_MARKER, fp.getName()));
}
markersHelper.addMapMarkers(points, names);
MarkersSyncGroup syncGroup = new MarkersSyncGroup(group.name, group.name, MarkersSyncGroup.FAVORITES_TYPE);
markersHelper.addMarkersSyncGroup(syncGroup);
markersHelper.addMapMarkers(points, names, syncGroup);
dismiss();
MapActivity.launchMapActivityMoveToTop(getActivity());
}

View file

@ -36,6 +36,7 @@ import net.osmand.data.PointDescription;
import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.FavouritesDbHelper.FavoriteGroup;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MarkersSyncGroup;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
@ -57,6 +58,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -80,7 +82,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
private OsmandApplication app;
private boolean selectionMode = false;
private Set<FavouritePoint> favoritesSelected = new LinkedHashSet<>();
private LinkedHashMap<String, Set<FavouritePoint>> favoritesSelected = new LinkedHashMap<>();
private Set<FavoriteGroup> groupsToDelete = new LinkedHashSet<>();
private ActionMode actionMode;
Drawable arrowImage;
@ -127,7 +129,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
@Override
protected String doInBackground(Void... params) {
helper.delete(groupsToDelete, favoritesSelected);
helper.delete(groupsToDelete, getSelectedFavorites());
favoritesSelected.clear();
groupsToDelete.clear();
return getString(R.string.favourites_delete_multiple_succesful);
@ -206,14 +208,35 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
initListExpandedState();
}
private int getSelectedFavoritesCount() {
int count = 0;
for (Set<FavouritePoint> set : favoritesSelected.values()) {
if (set != null) {
count += set.size();
}
}
return count;
}
private Set<FavouritePoint> getSelectedFavorites() {
Set<FavouritePoint> result = new LinkedHashSet<>();
for (Set<FavouritePoint> set : favoritesSelected.values()) {
if (set != null) {
result.addAll(set);
}
}
return result;
}
public void reloadData() {
favouritesAdapter.synchronizeGroups();
favouritesAdapter.notifyDataSetInvalidated();
}
private void updateSelectionMode(ActionMode m) {
if (favoritesSelected.size() > 0) {
m.setTitle(favoritesSelected.size() + " " + getMyApplication().getString(R.string.shared_string_selected_lowercase));
int size = getSelectedFavoritesCount();
if (size > 0) {
m.setTitle(size + " " + getMyApplication().getString(R.string.shared_string_selected_lowercase));
} else {
m.setTitle("");
}
@ -224,11 +247,22 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
if (selectionMode) {
CheckBox ch = (CheckBox) v.findViewById(R.id.toggle_item);
FavouritePoint model = favouritesAdapter.getChild(groupPosition, childPosition);
FavoriteGroup group = favouritesAdapter.getGroup(groupPosition);
ch.setChecked(!ch.isChecked());
if (ch.isChecked()) {
favoritesSelected.add(model);
Set<FavouritePoint> set = favoritesSelected.get(group.name);
if (set != null) {
set.add(model);
} else {
set = new LinkedHashSet<>();
set.add(model);
favoritesSelected.put(group.name, set);
}
} else {
favoritesSelected.remove(model);
Set<FavouritePoint> set = favoritesSelected.get(group.name);
if (set != null) {
set.remove(model);
}
}
updateSelectionMode(actionMode);
} else {
@ -308,14 +342,14 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
public void showProgressBar() {
OsmandActionBarActivity activity = getActionBarActivity();
if(activity != null) {
if (activity != null) {
activity.setSupportProgressBarIndeterminateVisibility(true);
}
}
public void hideProgressBar() {
OsmandActionBarActivity activity = getActionBarActivity();
if(activity != null) {
if (activity != null) {
activity.setSupportProgressBarIndeterminateVisibility(false);
}
}
@ -366,20 +400,29 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
}
private void selectMapMarkersImpl() {
if(!favoritesSelected.isEmpty()) {
if (getSelectedFavoritesCount() > 0) {
if (getSettings().USE_MAP_MARKERS.get()) {
MapMarkersHelper markersHelper = getMyApplication().getMapMarkersHelper();
List<LatLon> points = new ArrayList<>(favoritesSelected.size());
List<PointDescription> names = new ArrayList<>(favoritesSelected.size());
for (FavouritePoint fp : favoritesSelected) {
points.add(new LatLon(fp.getLatitude(), fp.getLongitude()));
names.add(new PointDescription(PointDescription.POINT_TYPE_MAP_MARKER, fp.getName()));
List<LatLon> points = new LinkedList<>();
List<PointDescription> names = new LinkedList<>();
for (Map.Entry<String, Set<FavouritePoint>> entry : favoritesSelected.entrySet()) {
FavoriteGroup favGr = helper.getGroup(entry.getKey());
MarkersSyncGroup syncGr = new MarkersSyncGroup(favGr.name, favGr.name, MarkersSyncGroup.FAVORITES_TYPE);
if (entry.getValue().size() == favGr.points.size()) {
markersHelper.addMarkersSyncGroup(syncGr);
}
for (FavouritePoint fp : entry.getValue()) {
points.add(new LatLon(fp.getLatitude(), fp.getLongitude()));
names.add(new PointDescription(PointDescription.POINT_TYPE_MAP_MARKER, fp.getName()));
}
markersHelper.addMapMarkers(points, names, syncGr);
points.clear();
names.clear();
}
markersHelper.addMapMarkers(points, names);
MapActivity.launchMapActivityMoveToTop(getActivity());
} else {
final TargetPointsHelper targetPointsHelper = getMyApplication().getTargetPointsHelper();
for (FavouritePoint fp : favoritesSelected) {
for (FavouritePoint fp : getSelectedFavorites()) {
targetPointsHelper.navigateToPoint(new LatLon(fp.getLatitude(), fp.getLongitude()), false,
targetPointsHelper.getIntermediatePoints().size() + 1,
new PointDescription(PointDescription.POINT_TYPE_FAVORITE, fp.getName()));
@ -441,10 +484,11 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
}
private void deleteFavoritesAction() {
if (groupsToDelete.size() + favoritesSelected.size() > 0) {
int size = getSelectedFavoritesCount();
if (groupsToDelete.size() + size > 0) {
AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
b.setMessage(getString(R.string.favorite_delete_multiple, favoritesSelected.size(), groupsToDelete.size()));
b.setMessage(getString(R.string.favorite_delete_multiple, size, groupsToDelete.size()));
b.setPositiveButton(R.string.shared_string_delete, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
@ -458,18 +502,18 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
b.show();
}
}
private StringBuilder generateHtmlPrint(List<FavoriteGroup> groups) {
StringBuilder html = new StringBuilder();
html.append("<h1>My Favorites</h1>");
for (FavoriteGroup group : groups) {
html.append("<h3>"+group.name+"</h3>");
for(FavouritePoint fp : group.points) {
String url = "geo:"+((float)fp.getLatitude())+","+((float)fp.getLongitude())+"?m="+fp.getName();
html.append("<h3>" + group.name + "</h3>");
for (FavouritePoint fp : group.points) {
String url = "geo:" + ((float) fp.getLatitude()) + "," + ((float) fp.getLongitude()) + "?m=" + fp.getName();
html.append("<p>" + fp.getName() + " - " + "<a href=\"" + url + "\">geo:"
+ ((float) fp.getLatitude()) + "," + ((float) fp.getLongitude()) + "</a><br>");
if(!Algorithms.isEmpty(fp.getDescription())) {
if (!Algorithms.isEmpty(fp.getDescription())) {
html.append(": " + fp.getDescription());
}
html.append("</p>");
@ -521,7 +565,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
@Override
protected void onPostExecute(Void res) {
hideProgressBar();
if(getActivity() == null) {
if (getActivity() == null) {
// user quit application
return;
}
@ -763,13 +807,17 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
if (ch.isChecked()) {
groupsToDelete.add(model);
if (fvs != null) {
favoritesSelected.addAll(fvs);
Set<FavouritePoint> set = favoritesSelected.get(model.name);
if (set != null) {
set.addAll(model.points);
} else {
set = new LinkedHashSet<>(model.points);
favoritesSelected.put(model.name, set);
}
}
} else {
groupsToDelete.remove(model);
if (fvs != null) {
favoritesSelected.removeAll(fvs);
}
favoritesSelected.remove(model.name);
}
favouritesAdapter.notifyDataSetInvalidated();
updateSelectionMode(actionMode);
@ -820,6 +868,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
ImageView icon = (ImageView) row.findViewById(R.id.favourite_icon);
final FavouritePoint model = getChild(groupPosition, childPosition);
final FavoriteGroup group = getGroup(groupPosition);
boolean visible = model.isVisible();
row.setTag(model);
@ -864,16 +913,26 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment {
final CheckBox ch = (CheckBox) row.findViewById(R.id.toggle_item);
if (selectionMode) {
ch.setVisibility(View.VISIBLE);
ch.setChecked(favoritesSelected.contains(model));
ch.setChecked(favoritesSelected.get(group.name) != null && favoritesSelected.get(group.name).contains(model));
row.findViewById(R.id.favourite_icon).setVisibility(View.GONE);
ch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ch.isChecked()) {
favoritesSelected.add(model);
Set<FavouritePoint> set = favoritesSelected.get(group.name);
if (set != null) {
set.add(model);
} else {
set = new LinkedHashSet<>();
set.add(model);
favoritesSelected.put(group.name, set);
}
} else {
favoritesSelected.remove(model);
Set<FavouritePoint> set = favoritesSelected.get(group.name);
if (set != null) {
set.remove(model);
}
}
updateSelectionMode(actionMode);
}

View file

@ -614,18 +614,6 @@ public class MapActivityActions implements DialogProvider {
}).createItem());
if (settings.USE_MAP_MARKERS.get()) {
optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.map_markers, mapActivity)
.setIcon(R.drawable.ic_action_flag_dark)
.setListener(new ContextMenuAdapter.ItemClickListener() {
@Override
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked) {
app.logEvent(mapActivity, "drawer_markers_open");
MapActivity.clearPrevActivityIntent();
mapActivity.getDashboard().setDashboardVisibility(true, DashboardType.MAP_MARKERS);
return false;
}
}).createItem());
optionsMenuHelper.addItem(new ItemBuilder().setTitle("New map markers")
.setIcon(R.drawable.ic_action_flag_dark)
.setListener(new ContextMenuAdapter.ItemClickListener() {
@Override

View file

@ -120,6 +120,12 @@ public abstract class DashLocationFragment extends DashBaseFragment {
public static void updateLocationView(boolean useCenter, LatLon fromLoc, Float h,
ImageView arrow, int arrowResId, TextView txt, LatLon toLoc,
int screenOrientation, OsmandApplication app, Context ctx, boolean paint) {
updateLocationView(useCenter, fromLoc, h, arrow, arrowResId, 0, txt, toLoc, screenOrientation, app, ctx, paint);
}
public static void updateLocationView(boolean useCenter, LatLon fromLoc, Float h,
ImageView arrow, int arrowResId, int color, TextView txt, LatLon toLoc,
int screenOrientation, OsmandApplication app, Context ctx, boolean paint) {
float[] mes = new float[2];
if (fromLoc != null && toLoc != null) {
Location.distanceBetween(toLoc.getLatitude(), toLoc.getLongitude(), fromLoc.getLatitude(), fromLoc.getLongitude(), mes);
@ -136,7 +142,7 @@ public abstract class DashLocationFragment extends DashBaseFragment {
} else {
dd = (DirectionDrawable) arrow.getDrawable();
}
dd.setImage(arrowResId, useCenter ? R.color.color_distance : R.color.color_myloc_distance);
dd.setImage(arrowResId, color == 0 ? useCenter ? R.color.color_distance : R.color.color_myloc_distance : color);
if (fromLoc == null || h == null || toLoc == null) {
dd.setAngle(0);
} else {

View file

@ -354,7 +354,7 @@ public class MapMarkerDialogHelper {
@Override
public void onClick(DialogInterface dialog, int which) {
listAdapter.notifyDataSetInvalidated();
markersHelper.removeActiveMarkers();
markersHelper.moveAllActiveMarkersToHistory();
if (markersHelper.getMapMarkersHistory().size() == 0) {
mapActivity.getDashboard().hideDashboard();
} else if (helperCallbacks != null) {

View file

@ -10,7 +10,6 @@ import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.MapMarkerDialogHelper;
import net.osmand.plus.mapcontextmenu.MenuBuilder;
import net.osmand.plus.mapcontextmenu.MenuController;
import net.osmand.plus.mapillary.MapillaryPlugin;
import net.osmand.util.Algorithms;
public class MapMarkerMenuController extends MenuController {
@ -25,8 +24,7 @@ public class MapMarkerMenuController extends MenuController {
leftTitleButtonController = new TitleButtonController() {
@Override
public void buttonPressed() {
markersHelper.removeMapMarker(getMapMarker().index);
markersHelper.addMapMarkerHistory(getMapMarker());
markersHelper.moveMapMarkerToHistory(getMapMarker());
getMapActivity().getContextMenu().close();
}
};

View file

@ -190,11 +190,14 @@ public class MapillaryImageDialog extends ContextMenuCardDialog {
}
public View getContentView() {
return getWebView();
/*
if (getMapActivity().getMyApplication().getSettings().WEBGL_SUPPORTED.get()) {
return getWebView();
} else {
return getStaticImageView();
}
*/
}
@Override
@ -239,6 +242,7 @@ public class MapillaryImageDialog extends ContextMenuCardDialog {
noInternetView.setVisibility(View.VISIBLE);
}
});
/*
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
@ -249,6 +253,7 @@ public class MapillaryImageDialog extends ContextMenuCardDialog {
return false;
}
});
*/
noInternetView.findViewById(R.id.retry_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

View file

@ -0,0 +1,149 @@
package net.osmand.plus.mapmarkers;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class HistoryMarkerMenuBottomSheetDialogFragment extends BottomSheetDialogFragment {
public final static String TAG = "HistoryMarkerMenuBottomSheetDialogFragment";
public static final String MARKER_POSITION = "marker_position";
public static final String MARKER_NAME = "marker_name";
public static final String MARKER_COLOR_INDEX = "marker_color_index";
public static final String MARKER_VISITED_DATE = "marker_visited_date";
private HistoryMarkerMenuFragmentListener listener;
private boolean portrait;
public void setListener(HistoryMarkerMenuFragmentListener listener) {
this.listener = listener;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
portrait = AndroidUiHelper.isOrientationPortrait(getActivity());
boolean nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls();
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
final View mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_history_bottom_sheet_dialog, container);
if (portrait) {
AndroidUtils.setBackground(getActivity(), mainView, nightMode, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
}
Bundle arguments = getArguments();
if (arguments != null) {
final int pos = arguments.getInt(MARKER_POSITION);
String markerName = arguments.getString(MARKER_NAME);
int markerColorIndex = arguments.getInt(MARKER_COLOR_INDEX);
long markerVisitedDate = arguments.getLong(MARKER_VISITED_DATE);
((TextView) mainView.findViewById(R.id.map_marker_title)).setText(markerName);
((ImageView) mainView.findViewById(R.id.map_marker_icon)).setImageDrawable(getIcon(R.drawable.ic_action_flag_dark, MapMarker.getColorId(markerColorIndex)));
((TextView) mainView.findViewById(R.id.map_marker_passed_info)).setText(getString(R.string.passed, new SimpleDateFormat("MMM dd", Locale.getDefault()).format(new Date(markerVisitedDate))));
mainView.findViewById(R.id.make_active_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.onMakeMarkerActive(pos);
}
dismiss();
}
});
mainView.findViewById(R.id.delete_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.onDeleteMarker(pos);
}
dismiss();
}
});
}
((ImageView) mainView.findViewById(R.id.make_active_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_reset_to_default_dark));
((ImageView) mainView.findViewById(R.id.delete_icon)).setImageDrawable(getContentIcon(R.drawable.ic_action_delete_dark));
mainView.findViewById(R.id.cancel_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
}
});
final int screenHeight = AndroidUtils.getScreenHeight(getActivity());
final int statusBarHeight = AndroidUtils.getStatusBarHeight(getActivity());
final int navBarHeight = AndroidUtils.getNavBarHeight(getActivity());
mainView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final View scrollView = mainView.findViewById(R.id.history_marker_scroll_view);
int scrollViewHeight = scrollView.getHeight();
int dividerHeight = AndroidUtils.dpToPx(getContext(), 1);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height);
int spaceForScrollView = screenHeight - statusBarHeight - navBarHeight - dividerHeight - cancelButtonHeight;
if (scrollViewHeight > spaceForScrollView) {
scrollView.getLayoutParams().height = spaceForScrollView;
scrollView.requestLayout();
}
if (!portrait) {
if (screenHeight - statusBarHeight - mainView.getHeight()
>= AndroidUtils.dpToPx(getActivity(), 8)) {
AndroidUtils.setBackground(getActivity(), mainView, false,
R.drawable.bg_bottom_sheet_topsides_landscape_light, R.drawable.bg_bottom_sheet_topsides_landscape_dark);
} else {
AndroidUtils.setBackground(getActivity(), mainView, false,
R.drawable.bg_bottom_sheet_sides_landscape_light, R.drawable.bg_bottom_sheet_sides_landscape_dark);
}
}
ViewTreeObserver obs = mainView.getViewTreeObserver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
}
});
return mainView;
}
@Override
public void onStart() {
super.onStart();
if (!portrait) {
final Window window = getDialog().getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.width = getActivity().getResources().getDimensionPixelSize(R.dimen.landscape_bottom_sheet_dialog_fragment_width);
window.setAttributes(params);
}
}
interface HistoryMarkerMenuFragmentListener {
void onMakeMarkerActive(int pos);
void onDeleteMarker(int pos);
}
}

View file

@ -49,7 +49,7 @@ public class MapMarkersActiveFragment extends Fragment implements OsmAndCompassL
@Override
public void onItemClick(View view) {
int pos = recyclerView.indexOfChild(view);
int pos = recyclerView.getChildAdapterPosition(view);
MapMarker marker = adapter.getItem(pos);
mapActivity.getMyApplication().getSettings().setMapLocationToShow(marker.getLatitude(), marker.getLongitude(),
15, marker.getPointDescription(mapActivity), true, marker);
@ -67,7 +67,9 @@ public class MapMarkersActiveFragment extends Fragment implements OsmAndCompassL
public void onDragEnded(RecyclerView.ViewHolder holder) {
toPosition = holder.getAdapterPosition();
if (toPosition >= 0 && fromPosition >= 0 && toPosition != fromPosition) {
mapActivity.getMyApplication().getMapMarkersHelper().saveMapMarkers(adapter.getItems(), null);
hideSnackbar();
mapActivity.getMyApplication().getMapMarkersHelper().checkAndFixActiveMarkersOrderIfNeeded();
adapter.notifyDataSetChanged();
}
}
});
@ -121,15 +123,27 @@ public class MapMarkersActiveFragment extends Fragment implements OsmAndCompassL
return null;
}
void setShowDirectionEnabled(boolean showDirectionEnabled) {
if (adapter != null) {
adapter.setShowDirectionEnabled(showDirectionEnabled);
}
}
void updateAdapter() {
if (adapter != null) {
adapter.notifyDataSetChanged();
}
}
void hideSnackbar() {
if (adapter != null) {
adapter.hideSnackbar();
}
}
private void updateLocationUi() {
final MapActivity mapActivity = (MapActivity) getActivity();
if (mapActivity != null) {
if (mapActivity != null && adapter != null) {
mapActivity.getMyApplication().runInUIThread(new Runnable() {
@Override
public void run() {
@ -141,7 +155,7 @@ public class MapMarkersActiveFragment extends Fragment implements OsmAndCompassL
adapter.setUseCenter(useCenter);
adapter.setLocation(useCenter ? mapActivity.getMapLocation() : new LatLon(location.getLatitude(), location.getLongitude()));
adapter.setHeading(useCenter ? -mapActivity.getMapRotate() : heading);
adapter.setHeading(useCenter ? -mapActivity.getMapRotate() : heading != null ? heading : 99);
adapter.notifyDataSetChanged();
}
});

View file

@ -0,0 +1,509 @@
package net.osmand.plus.mapmarkers;
import android.support.annotation.Nullable;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.MapMarkersHelper.MarkersSyncGroup;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
import net.osmand.plus.api.SQLiteAPI.SQLiteCursor;
import net.osmand.plus.helpers.SearchHistoryHelper;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
public class MapMarkersDbHelper {
private static final int DB_VERSION = 2;
public static final String DB_NAME = "map_markers_db";
private static final String MARKERS_TABLE_NAME = "map_markers";
private static final String MARKERS_COL_ID = "marker_id";
private static final String MARKERS_COL_LAT = "marker_lat";
private static final String MARKERS_COL_LON = "marker_lon";
private static final String MARKERS_COL_DESCRIPTION = "marker_description";
private static final String MARKERS_COL_ACTIVE = "marker_active";
private static final String MARKERS_COL_ADDED = "marker_added";
private static final String MARKERS_COL_VISITED = "marker_visited";
private static final String MARKERS_COL_GROUP_NAME = "group_name";
private static final String MARKERS_COL_GROUP_KEY = "group_key";
private static final String MARKERS_COL_COLOR = "marker_color";
private static final String MARKERS_COL_NEXT_KEY = "marker_next_key";
private static final String MARKERS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " +
MARKERS_TABLE_NAME + " (" +
MARKERS_COL_ID + " TEXT PRIMARY KEY, " +
MARKERS_COL_LAT + " double, " +
MARKERS_COL_LON + " double, " +
MARKERS_COL_DESCRIPTION + " TEXT, " +
MARKERS_COL_ACTIVE + " int, " + // 1 = true, 0 = false
MARKERS_COL_ADDED + " long, " +
MARKERS_COL_VISITED + " long, " +
MARKERS_COL_GROUP_NAME + " TEXT, " +
MARKERS_COL_GROUP_KEY + " TEXT, " +
MARKERS_COL_COLOR + " int, " +
MARKERS_COL_NEXT_KEY + " TEXT);";
private static final String MARKERS_TABLE_SELECT = "SELECT " +
MARKERS_COL_ID + ", " +
MARKERS_COL_LAT + ", " +
MARKERS_COL_LON + ", " +
MARKERS_COL_DESCRIPTION + ", " +
MARKERS_COL_ACTIVE + ", " +
MARKERS_COL_ADDED + ", " +
MARKERS_COL_VISITED + ", " +
MARKERS_COL_GROUP_NAME + ", " +
MARKERS_COL_GROUP_KEY + ", " +
MARKERS_COL_COLOR + ", " +
MARKERS_COL_NEXT_KEY +
" FROM " + MARKERS_TABLE_NAME;
private static final String GROUPS_TABLE_NAME = "map_markers_groups";
private static final String GROUPS_COL_ID = "group_id";
private static final String GROUPS_COL_NAME = "group_name";
private static final String GROUPS_COL_TYPE = "group_type";
private static final String GROUPS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " +
GROUPS_TABLE_NAME + " (" +
GROUPS_COL_ID + " TEXT PRIMARY KEY, " +
GROUPS_COL_NAME + " TEXT, " +
GROUPS_COL_TYPE + " int);";
private static final String GROUPS_TABLE_SELECT = "SELECT " +
GROUPS_COL_ID + ", " +
GROUPS_COL_NAME + ", " +
GROUPS_COL_TYPE +
" FROM " + GROUPS_TABLE_NAME;
public static final String TAIL_NEXT_VALUE = "tail_next";
public static final String HISTORY_NEXT_VALUE = "history_next";
private final OsmandApplication context;
public MapMarkersDbHelper(OsmandApplication context) {
this.context = context;
}
private SQLiteConnection openConnection(boolean readonly) {
SQLiteConnection conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, readonly);
int version = conn.getVersion();
if (version == 0 || DB_VERSION != version) {
if (readonly) {
conn.close();
conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, false);
}
version = conn.getVersion();
conn.setVersion(DB_VERSION);
if (version == 0) {
onCreate(conn);
} else {
onUpgrade(conn, version, DB_VERSION);
}
}
return conn;
}
private void onCreate(SQLiteConnection db) {
db.execSQL(MARKERS_TABLE_CREATE);
db.execSQL(GROUPS_TABLE_CREATE);
saveExistingMarkersToDb();
}
private void onUpgrade(SQLiteConnection db, int oldVersion, int newVersion) {
}
private void saveExistingMarkersToDb() {
OsmandSettings settings = context.getSettings();
List<LatLon> ips = settings.getMapMarkersPoints();
List<String> desc = settings.getMapMarkersPointDescriptions(ips.size());
List<Integer> colors = settings.getMapMarkersColors(ips.size());
int colorIndex = 0;
for (int i = 0; i < ips.size(); i++) {
if (colors.size() > i) {
colorIndex = colors.get(i);
}
MapMarker marker = new MapMarker(ips.get(i), PointDescription.deserializeFromString(desc.get(i), ips.get(i)),
colorIndex, false, i);
marker.history = false;
addMarker(marker, true);
}
ips = settings.getMapMarkersHistoryPoints();
desc = settings.getMapMarkersHistoryPointDescriptions(ips.size());
colors = settings.getMapMarkersHistoryColors(ips.size());
for (int i = 0; i < ips.size(); i++) {
if (colors.size() > i) {
colorIndex = colors.get(i);
}
MapMarker marker = new MapMarker(ips.get(i), PointDescription.deserializeFromString(desc.get(i), ips.get(i)),
colorIndex, false, i);
marker.history = true;
addMarker(marker, true);
}
}
public void addGroup(String id, String name, int type) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("INSERT INTO " + GROUPS_TABLE_NAME + " VALUES (?, ?, ?)", new Object[]{id, name, type});
} finally {
db.close();
}
}
}
public List<MarkersSyncGroup> getAllGroups() {
List<MarkersSyncGroup> res = new LinkedList<>();
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
SQLiteCursor query = db.rawQuery(GROUPS_TABLE_SELECT, null);
if (query.moveToFirst()) {
do {
res.add(readSyncGroup(query));
} while (query.moveToNext());
}
query.close();
} finally {
db.close();
}
}
return res;
}
@Nullable
public MarkersSyncGroup getGroup(String id) {
MarkersSyncGroup res = null;
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
SQLiteCursor query = db.rawQuery(GROUPS_TABLE_SELECT + " WHERE " + GROUPS_COL_ID + " = ?", new String[]{id});
if (query.moveToFirst()) {
res = readSyncGroup(query);
}
query.close();
} finally {
db.close();
}
}
return res;
}
private MarkersSyncGroup readSyncGroup(SQLiteCursor query) {
String id = query.getString(0);
String name = query.getString(1);
int type = query.getInt(2);
return new MarkersSyncGroup(id, name, type);
}
public void removeMarkersSyncGroup(String id) {
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
db.execSQL("DELETE FROM " + GROUPS_TABLE_NAME + " WHERE " + GROUPS_COL_ID + " = ?", new Object[]{id});
} finally {
db.close();
}
}
}
public void removeActiveMarkersFromSyncGroup(String syncGroupId) {
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
db.execSQL("DELETE FROM " + MARKERS_TABLE_NAME +
" WHERE " + MARKERS_COL_GROUP_KEY + " = ?" +
" AND " + MARKERS_COL_ACTIVE + " = ?",
new Object[]{syncGroupId, 1});
} finally {
db.close();
}
}
}
public void addMarker(MapMarker marker) {
addMarker(marker, false);
}
private void addMarker(MapMarker marker, boolean saveExisting) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
insertLast(db, marker, saveExisting);
} finally {
db.close();
}
}
}
private void insertLast(SQLiteConnection db, MapMarker marker, boolean saveExisting) {
long currentTime;
if (saveExisting) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MONTH, -1);
currentTime = cal.getTimeInMillis();
} else {
currentTime = System.currentTimeMillis();
}
if (marker.id == null) {
marker.id = String.valueOf(currentTime) + String.valueOf(new Random().nextInt(900) + 100);
}
marker.creationDate = currentTime;
String descr = PointDescription.serializeToString(marker.getOriginalPointDescription());
int active = marker.history ? 0 : 1;
long visited = saveExisting ? currentTime : 0;
PointDescription pointDescription = marker.getOriginalPointDescription();
if (pointDescription != null && !pointDescription.isSearchingAddress(context)) {
SearchHistoryHelper.getInstance(context)
.addNewItemToHistory(marker.getLatitude(), marker.getLongitude(), pointDescription);
}
if (!marker.history) {
db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " + MARKERS_COL_NEXT_KEY + " = ? " +
"WHERE " + MARKERS_COL_NEXT_KEY + " = ?", new Object[]{marker.id, TAIL_NEXT_VALUE});
}
db.execSQL("INSERT INTO " + MARKERS_TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
new Object[]{marker.id, marker.getLatitude(), marker.getLongitude(), descr, active,
currentTime, visited, marker.groupName, marker.groupKey, marker.colorIndex,
marker.history ? HISTORY_NEXT_VALUE : TAIL_NEXT_VALUE});
}
public List<MapMarker> getMarkersFromGroup(MarkersSyncGroup group) {
List<MapMarker> res = new LinkedList<>();
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
SQLiteCursor query = db.rawQuery(MARKERS_TABLE_SELECT + " WHERE " + MARKERS_COL_GROUP_KEY + " = ?",
new String[]{group.getId()});
if (query.moveToFirst()) {
do {
res.add(readItem(query));
} while (query.moveToNext());
}
query.close();
} finally {
db.close();
}
}
return res;
}
@Nullable
public MapMarker getMarker(String id) {
MapMarker res = null;
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
SQLiteCursor query = db.rawQuery(MARKERS_TABLE_SELECT + " WHERE " + MARKERS_COL_ID + " = ?", new String[]{id});
if (query.moveToFirst()) {
res = readItem(query);
}
query.close();
} finally {
db.close();
}
}
return res;
}
public List<MapMarker> getActiveMarkers() {
List<MapMarker> res = new LinkedList<>();
HashMap<String, MapMarker> markers = new LinkedHashMap<>();
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
SQLiteCursor query = db.rawQuery(MARKERS_TABLE_SELECT + " WHERE " + MARKERS_COL_ACTIVE + " = ?",
new String[]{String.valueOf(1)});
if (query.moveToFirst()) {
do {
MapMarker marker = readItem(query);
markers.put(marker.id, marker);
} while (query.moveToNext());
}
query.close();
} finally {
db.close();
}
buildLinkedList(markers, res);
}
return res;
}
private MapMarker readItem(SQLiteCursor query) {
String id = query.getString(0);
double lat = query.getDouble(1);
double lon = query.getDouble(2);
String desc = query.getString(3);
boolean active = query.getInt(4) == 1;
long added = query.getLong(5);
long visited = query.getLong(6);
String groupName = query.getString(7);
String groupKey = query.getString(8);
int colorIndex = query.getInt(9);
String nextKey = query.getString(10);
LatLon latLon = new LatLon(lat, lon);
MapMarker marker = new MapMarker(latLon, PointDescription.deserializeFromString(desc, latLon),
colorIndex, false, 0);
marker.id = id;
marker.history = !active;
marker.creationDate = added;
marker.visitedDate = visited;
marker.groupName = groupName;
marker.groupKey = groupKey;
marker.nextKey = nextKey;
return marker;
}
private void buildLinkedList(HashMap<String, MapMarker> markers, List<MapMarker> res) {
if (!markers.isEmpty()) {
int count = 1;
for (MapMarker marker : markers.values()) {
if (!markers.keySet().contains(marker.nextKey) || count == markers.size()) {
res.add(0, marker);
markers.remove(marker.id);
break;
}
count++;
}
buildLinkedList(markers, res);
}
}
public void updateMarker(MapMarker marker) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
String descr = PointDescription.serializeToString(marker.getOriginalPointDescription());
db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " +
MARKERS_COL_LAT + " = ?, " +
MARKERS_COL_LON + " = ?, " +
MARKERS_COL_DESCRIPTION + " = ?, " +
MARKERS_COL_COLOR + " = ? " +
"WHERE " + MARKERS_COL_ID + " = ?",
new Object[]{marker.getLatitude(), marker.getLongitude(), descr, marker.colorIndex, marker.id});
} finally {
db.close();
}
}
}
public void changeActiveMarkerPosition(MapMarker moved, @Nullable MapMarker next) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " + MARKERS_COL_NEXT_KEY + " = ? " +
"WHERE " + MARKERS_COL_ID + " = ?", new Object[]{next == null ? TAIL_NEXT_VALUE : next.id, moved.id});
} finally {
db.close();
}
}
}
public void moveMarkerToHistory(MapMarker marker) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
marker.visitedDate = System.currentTimeMillis();
db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " +
MARKERS_COL_ACTIVE + " = ?, " +
MARKERS_COL_VISITED + " = ?, " +
MARKERS_COL_NEXT_KEY + " = ? " +
"WHERE " + MARKERS_COL_ID + " = ?", new Object[]{0, marker.visitedDate, HISTORY_NEXT_VALUE, marker.id});
} finally {
db.close();
}
}
}
public void moveAllActiveMarkersToHistory(long timestamp) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " +
MARKERS_COL_ACTIVE + " = ?, " +
MARKERS_COL_VISITED + " = ?, " +
MARKERS_COL_NEXT_KEY + " = ? " +
"WHERE " + MARKERS_COL_ACTIVE + " = ?", new Object[]{0, timestamp, HISTORY_NEXT_VALUE, 1});
} finally {
db.close();
}
}
}
public void restoreMapMarkerFromHistory(MapMarker marker) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("UPDATE " + MARKERS_TABLE_NAME + " SET " +
MARKERS_COL_ACTIVE + " = ? " +
"WHERE " + MARKERS_COL_ID + " = ? " +
"AND " + MARKERS_COL_ACTIVE + " = ?",
new Object[]{1, marker.id, 0});
} finally {
db.close();
}
}
}
public List<MapMarker> getMarkersHistory() {
List<MapMarker> markers = new LinkedList<>();
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
SQLiteCursor query = db.rawQuery(MARKERS_TABLE_SELECT + " WHERE " + MARKERS_COL_ACTIVE + " = ?",
new String[]{String.valueOf(0)});
if (query.moveToFirst()) {
do {
markers.add(readItem(query));
} while (query.moveToNext());
}
query.close();
} finally {
db.close();
}
}
return markers;
}
public void removeMarker(MapMarker marker, boolean history) {
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
db.execSQL("DELETE FROM " + MARKERS_TABLE_NAME +
" WHERE " + MARKERS_COL_ID + " = ?" +
" AND " + MARKERS_COL_ACTIVE + " = ?",
new Object[]{marker.id, history ? 0 : 1});
} finally {
db.close();
}
}
}
public void clearAllMarkersHistory() {
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
db.execSQL("DELETE FROM " + MARKERS_TABLE_NAME + " WHERE " + MARKERS_COL_ACTIVE + " = ?",
new Object[]{0});
} finally {
db.close();
}
}
}
}

View file

@ -4,30 +4,47 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomNavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.Toolbar;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import net.osmand.plus.LockableViewPager;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.mapmarkers.ShowDirectionBottomSheetDialogFragment.ShowDirectionFragmentListener;
import net.osmand.plus.mapmarkers.MarkerOptionsBottomSheetDialogFragment.MarkerOptionsFragmentListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragment {
public static final String TAG = "MapMarkersDialogFragment";
private MapMarkersActiveFragment activeFragment;
private MapMarkersGroupsFragment groupsFragment;
private MapMarkersHistoryFragment historyFragment;
private Snackbar snackbar;
private LockableViewPager viewPager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -40,11 +57,37 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
List<Fragment> fragments = getChildFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
if (fragment instanceof MapMarkersActiveFragment) {
activeFragment = (MapMarkersActiveFragment) fragment;
} else if (fragment instanceof MapMarkersGroupsFragment) {
groupsFragment = (MapMarkersGroupsFragment) fragment;
} else if (fragment instanceof MapMarkersHistoryFragment) {
historyFragment = (MapMarkersHistoryFragment) fragment;
}
}
}
if (activeFragment == null) {
activeFragment = new MapMarkersActiveFragment();
}
if (groupsFragment == null) {
groupsFragment = new MapMarkersGroupsFragment();
}
if (historyFragment == null) {
historyFragment = new MapMarkersHistoryFragment();
}
FragmentManager fragmentManager = getChildFragmentManager();
Fragment markerOptionsFragment = fragmentManager.findFragmentByTag(MarkerOptionsBottomSheetDialogFragment.TAG);
if (markerOptionsFragment != null) {
((MarkerOptionsBottomSheetDialogFragment) markerOptionsFragment).setListener(createMarkerOptionsFragmentListener());
}
Fragment showDirectionFragment = fragmentManager.findFragmentByTag(ShowDirectionBottomSheetDialogFragment.TAG);
if (showDirectionFragment != null) {
((ShowDirectionBottomSheetDialogFragment) showDirectionFragment).setListener(createShowDirectionFragmentListener());
}
View mainView = inflater.inflate(R.layout.fragment_map_markers_dialog, container);
@ -66,7 +109,7 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
}
});
final LockableViewPager viewPager = mainView.findViewById(R.id.map_markers_view_pager);
viewPager = mainView.findViewById(R.id.map_markers_view_pager);
viewPager.setSwipeLocked(true);
final MapMarkersViewPagerAdapter adapter = new MapMarkersViewPagerAdapter(getChildFragmentManager());
viewPager.setAdapter(adapter);
@ -77,21 +120,33 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_active:
((MapMarkersActiveFragment) adapter.getItem(0)).startLocationUpdate();
activeFragment.startLocationUpdate();
if (viewPager.getCurrentItem() != 0) {
((MapMarkersActiveFragment) adapter.getItem(0)).updateAdapter();
activeFragment.updateAdapter();
historyFragment.hideSnackbar();
}
viewPager.setCurrentItem(0);
optionsButton.setVisibility(View.VISIBLE);
return true;
case R.id.action_history:
((MapMarkersActiveFragment) adapter.getItem(0)).stopLocationUpdate();
case R.id.action_groups:
activeFragment.stopLocationUpdate();
if (viewPager.getCurrentItem() != 1) {
((MapMarkersHistoryFragment) adapter.getItem(1)).updateAdapter();
groupsFragment.updateAdapter();
activeFragment.hideSnackbar();
historyFragment.hideSnackbar();
}
viewPager.setCurrentItem(1);
optionsButton.setVisibility(View.GONE);
return true;
case R.id.action_history:
activeFragment.stopLocationUpdate();
if (viewPager.getCurrentItem() != 2) {
historyFragment.updateAdapter();
activeFragment.hideSnackbar();
}
viewPager.setCurrentItem(2);
optionsButton.setVisibility(View.GONE);
return true;
}
return false;
}
@ -106,6 +161,9 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
private MarkerOptionsFragmentListener createMarkerOptionsFragmentListener() {
return new MarkerOptionsFragmentListener() {
final MapActivity mapActivity = getMapActivity();
@Override
public void sortByOnClick() {
Toast.makeText(getContext(), "Sort by", Toast.LENGTH_SHORT).show();
@ -113,26 +171,61 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
@Override
public void showDirectionOnClick() {
Toast.makeText(getContext(), "Show direction", Toast.LENGTH_SHORT).show();
ShowDirectionBottomSheetDialogFragment fragment = new ShowDirectionBottomSheetDialogFragment();
fragment.setListener(createShowDirectionFragmentListener());
fragment.show(mapActivity.getSupportFragmentManager(), ShowDirectionBottomSheetDialogFragment.TAG);
}
@Override
public void buildRouteOnClick() {
Toast.makeText(getContext(), "Build route", Toast.LENGTH_SHORT).show();
mapActivity.getDashboard().setDashboardVisibility(true, DashboardOnMap.DashboardType.MAP_MARKERS_SELECTION);
dismiss();
}
@Override
public void saveAsNewTrackOnClick() {
Toast.makeText(getContext(), "Save as new track", Toast.LENGTH_SHORT).show();
mapActivity.getMyApplication().getMapMarkersHelper().generateGpx();
}
@Override
public void moveAllToHistoryOnClick() {
Toast.makeText(getContext(), "Move all to history", Toast.LENGTH_SHORT).show();
final MapMarkersHelper helper = mapActivity.getMyApplication().getMapMarkersHelper();
final List<MapMarkersHelper.MapMarker> markers = new ArrayList<>(helper.getMapMarkers());
helper.moveAllActiveMarkersToHistory();
activeFragment.updateAdapter();
snackbar = Snackbar.make(viewPager, R.string.all_markers_moved_to_history, Snackbar.LENGTH_LONG)
.setAction(R.string.shared_string_undo, new View.OnClickListener() {
@Override
public void onClick(View view) {
helper.restoreMarkersFromHistory(markers);
activeFragment.updateAdapter();
}
});
View snackBarView = snackbar.getView();
TextView tv = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action);
tv.setTextColor(ContextCompat.getColor(mapActivity, R.color.color_dialog_buttons_dark));
snackbar.show();
}
};
}
private ShowDirectionFragmentListener createShowDirectionFragmentListener() {
return new ShowDirectionFragmentListener() {
final MapActivity mapActivity = getMapActivity();
@Override
public void onMapMarkersModeChanged(boolean showDirectionEnabled) {
mapActivity.getMapLayers().getMapWidgetRegistry().updateMapMarkersMode(mapActivity);
activeFragment.setShowDirectionEnabled(showDirectionEnabled);
activeFragment.updateAdapter();
}
};
}
private MapActivity getMapActivity() {
return (MapActivity) getActivity();
}
public static boolean showInstance(@NonNull MapActivity mapActivity) {
try {
@ -153,7 +246,7 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
MapMarkersViewPagerAdapter(FragmentManager fm) {
super(fm);
fragments = Arrays.asList(new MapMarkersActiveFragment(), new MapMarkersHistoryFragment());
fragments = Arrays.asList(activeFragment, groupsFragment, historyFragment);
}
@Override

View file

@ -0,0 +1,37 @@
package net.osmand.plus.mapmarkers;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapmarkers.adapters.MapMarkersGroupsAdapter;
public class MapMarkersGroupsFragment extends Fragment {
public static final String TAG = "MapMarkersGroupsFragment";
private MapMarkersGroupsAdapter adapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final RecyclerView recyclerView = new RecyclerView(getContext());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
final MapActivity mapActivity = (MapActivity) getActivity();
adapter = new MapMarkersGroupsAdapter(mapActivity);
return recyclerView;
}
void updateAdapter() {
if (adapter != null) {
adapter.notifyDataSetChanged();
}
}
}

View file

@ -1,52 +1,261 @@
package net.osmand.plus.mapmarkers;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import net.osmand.data.PointDescription;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapmarkers.adapters.MapMarkerDateViewHolder;
import net.osmand.plus.mapmarkers.adapters.MapMarkerItemViewHolder;
import net.osmand.plus.mapmarkers.adapters.MapMarkersHistoryAdapter;
public class MapMarkersHistoryFragment extends Fragment {
public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHelper.MapMarkerChangedListener {
MapMarkersHistoryAdapter adapter;
private MapMarkersHistoryAdapter adapter;
private OsmandApplication app;
private Paint backgroundPaint = new Paint();
private Paint iconPaint = new Paint();
private Paint textPaint = new Paint();
private Snackbar snackbar;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = getMyApplication();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final boolean night = !app.getSettings().isLightContent();
final MapActivity mapActivity = (MapActivity) getActivity();
backgroundPaint.setColor(ContextCompat.getColor(getActivity(), night ? R.color.dashboard_divider_dark : R.color.dashboard_divider_light));
backgroundPaint.setStyle(Paint.Style.FILL_AND_STROKE);
backgroundPaint.setAntiAlias(true);
iconPaint.setAntiAlias(true);
iconPaint.setFilterBitmap(true);
iconPaint.setDither(true);
textPaint.setTextSize(getResources().getDimension(R.dimen.default_desc_text_size));
textPaint.setFakeBoldText(true);
textPaint.setAntiAlias(true);
final String delStr = getString(R.string.shared_string_delete).toUpperCase();
final String activateStr = getString(R.string.local_index_mi_restore).toUpperCase();
Rect bounds = new Rect();
textPaint.getTextBounds(activateStr, 0, activateStr.length(), bounds);
final int activateStrWidth = bounds.width();
final int textHeight = bounds.height();
Fragment historyMarkerMenuFragment = mapActivity.getSupportFragmentManager().findFragmentByTag(HistoryMarkerMenuBottomSheetDialogFragment.TAG);
if (historyMarkerMenuFragment != null) {
((HistoryMarkerMenuBottomSheetDialogFragment) historyMarkerMenuFragment).setListener(createHistoryMarkerMenuListener());
}
final RecyclerView recyclerView = new RecyclerView(getContext());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
final MapActivity mapActivity = (MapActivity) getActivity();
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
private float marginSides = getResources().getDimension(R.dimen.list_content_padding);
private Bitmap deleteBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_action_delete_dark);
private Bitmap resetBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_action_reset_to_default_dark);
private boolean iconHidden;
@Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (viewHolder instanceof MapMarkerDateViewHolder) {
return 0;
}
return super.getSwipeDirs(recyclerView, viewHolder);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE && viewHolder instanceof MapMarkerItemViewHolder) {
if (!iconHidden && isCurrentlyActive) {
((MapMarkerItemViewHolder) viewHolder).optionsBtn.setVisibility(View.GONE);
iconHidden = true;
}
View itemView = viewHolder.itemView;
int colorIcon;
int colorText;
if (Math.abs(dX) > itemView.getWidth() / 2) {
colorIcon = R.color.map_widget_blue;
colorText = R.color.map_widget_blue;
} else {
colorIcon = night ? 0 : R.color.icon_color;
colorText = R.color.dashboard_subheader_text_light;
}
if (colorIcon != 0) {
iconPaint.setColorFilter(new PorterDuffColorFilter(ContextCompat.getColor(getActivity(), colorIcon), PorterDuff.Mode.SRC_IN));
}
textPaint.setColor(ContextCompat.getColor(getActivity(), colorText));
float textMarginTop = ((float) itemView.getHeight() - (float) textHeight) / 2;
if (dX > 0) {
c.drawRect(itemView.getLeft(), itemView.getTop(), dX, itemView.getBottom(), backgroundPaint);
float iconMarginTop = ((float) itemView.getHeight() - (float) deleteBitmap.getHeight()) / 2;
c.drawBitmap(deleteBitmap, itemView.getLeft() + marginSides, itemView.getTop() + iconMarginTop, iconPaint);
c.drawText(delStr, itemView.getLeft() + 2 * marginSides + deleteBitmap.getWidth(), itemView.getTop() + textMarginTop + textHeight, textPaint);
} else {
c.drawRect(itemView.getRight() + dX, itemView.getTop(), itemView.getRight(), itemView.getBottom(), backgroundPaint);
float iconMarginTop = ((float) itemView.getHeight() - (float) resetBitmap.getHeight()) / 2;
c.drawBitmap(resetBitmap, itemView.getRight() - resetBitmap.getWidth() - marginSides, itemView.getTop() + iconMarginTop, iconPaint);
c.drawText(activateStr, itemView.getRight() - resetBitmap.getWidth() - 2 * marginSides - activateStrWidth, itemView.getTop() + textMarginTop + textHeight, textPaint);
}
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (viewHolder instanceof MapMarkerItemViewHolder) {
((MapMarkerItemViewHolder) viewHolder).optionsBtn.setVisibility(View.VISIBLE);
iconHidden = false;
}
super.clearView(recyclerView, viewHolder);
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, final int direction) {
final int pos = viewHolder.getAdapterPosition();
Object item = adapter.getItem(pos);
if (item instanceof MapMarker) {
final MapMarker marker = (MapMarker) item;
int snackbarStringRes;
if (direction == ItemTouchHelper.LEFT) {
app.getMapMarkersHelper().restoreMarkerFromHistory((MapMarker) item, 0);
snackbarStringRes = R.string.marker_moved_to_active;
} else {
app.getMapMarkersHelper().removeMarkerFromHistory((MapMarker) item);
snackbarStringRes = R.string.item_removed;
}
adapter.notifyItemRemoved(pos);
snackbar = Snackbar.make(viewHolder.itemView, snackbarStringRes, Snackbar.LENGTH_LONG)
.setAction(R.string.shared_string_undo, new View.OnClickListener() {
@Override
public void onClick(View view) {
if (direction == ItemTouchHelper.LEFT) {
app.getMapMarkersHelper().moveMapMarkerToHistory(marker);
} else {
app.getMapMarkersHelper().addMarker(marker);
}
}
});
View snackBarView = snackbar.getView();
TextView tv = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action);
tv.setTextColor(ContextCompat.getColor(mapActivity, R.color.color_dialog_buttons_dark));
snackbar.show();
}
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);
adapter = new MapMarkersHistoryAdapter(mapActivity.getMyApplication());
adapter.setAdapterListener(new MapMarkersHistoryAdapter.MapMarkersHistoryAdapterListener() {
@Override
public void onItemClick(View view) {
int pos = recyclerView.indexOfChild(view);
MapMarker marker = adapter.getItem(pos);
mapActivity.getMyApplication().getSettings().setMapLocationToShow(marker.getLatitude(), marker.getLongitude(),
15, new PointDescription(PointDescription.POINT_TYPE_LOCATION, marker.getPointDescription(mapActivity).getName()),
false, null);
MapActivity.launchMapActivityMoveToTop(mapActivity);
((DialogFragment) getParentFragment()).dismiss();
int pos = recyclerView.getChildAdapterPosition(view);
Object item = adapter.getItem(pos);
if (item instanceof MapMarker) {
MapMarker marker = (MapMarker) item;
HistoryMarkerMenuBottomSheetDialogFragment fragment = new HistoryMarkerMenuBottomSheetDialogFragment();
Bundle arguments = new Bundle();
arguments.putInt(HistoryMarkerMenuBottomSheetDialogFragment.MARKER_POSITION, pos);
arguments.putString(HistoryMarkerMenuBottomSheetDialogFragment.MARKER_NAME, marker.getName(mapActivity));
arguments.putInt(HistoryMarkerMenuBottomSheetDialogFragment.MARKER_COLOR_INDEX, marker.colorIndex);
arguments.putLong(HistoryMarkerMenuBottomSheetDialogFragment.MARKER_VISITED_DATE, marker.visitedDate);
fragment.setArguments(arguments);
fragment.setListener(createHistoryMarkerMenuListener());
fragment.show(mapActivity.getSupportFragmentManager(), HistoryMarkerMenuBottomSheetDialogFragment.TAG);
}
}
});
recyclerView.setAdapter(adapter);
app.getMapMarkersHelper().addListener(this);
return recyclerView;
}
void hideSnackbar() {
if (snackbar != null && snackbar.isShown()) {
snackbar.dismiss();
}
}
private HistoryMarkerMenuBottomSheetDialogFragment.HistoryMarkerMenuFragmentListener createHistoryMarkerMenuListener() {
return new HistoryMarkerMenuBottomSheetDialogFragment.HistoryMarkerMenuFragmentListener() {
@Override
public void onMakeMarkerActive(int pos) {
Object item = adapter.getItem(pos);
if (item instanceof MapMarker) {
app.getMapMarkersHelper().restoreMarkerFromHistory((MapMarker) item, 0);
adapter.notifyItemRemoved(pos);
}
}
@Override
public void onDeleteMarker(int pos) {
Object item = adapter.getItem(pos);
if (item instanceof MapMarker) {
app.getMapMarkersHelper().removeMarkerFromHistory((MapMarker) item);
adapter.notifyItemRemoved(pos);
}
}
};
}
@Override
public void onDestroy() {
app.getMapMarkersHelper().removeListener(this);
super.onDestroy();
}
void updateAdapter() {
if (adapter != null) {
adapter.createHeaders();
adapter.notifyDataSetChanged();
}
}
public OsmandApplication getMyApplication() {
return (OsmandApplication) getActivity().getApplication();
}
@Override
public void onMapMarkerChanged(MapMarker mapMarker) {
updateAdapter();
}
@Override
public void onMapMarkersChanged() {
updateAdapter();
}
}

View file

@ -3,6 +3,7 @@ package net.osmand.plus.mapmarkers;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -13,6 +14,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
@ -32,16 +34,31 @@ public class MarkerOptionsBottomSheetDialogFragment extends BottomSheetDialogFra
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
portrait = AndroidUiHelper.isOrientationPortrait(getActivity());
boolean nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls();
final int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
final View mainView = inflater.inflate(R.layout.fragment_marker_options_bottom_sheet_dialog, container);
final View mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_options_bottom_sheet_dialog, container);
if (portrait) {
AndroidUtils.setBackground(getActivity(), mainView, false, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
AndroidUtils.setBackground(getActivity(), mainView, nightMode, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
}
((ImageView) mainView.findViewById(R.id.sort_by_icon))
.setImageDrawable(getIcon(R.drawable.ic_sort_waypoint_dark, R.color.on_map_icon_color));
((ImageView) mainView.findViewById(R.id.show_direction_icon))
.setImageDrawable(getIcon(R.drawable.ic_sort_waypoint_dark, R.color.on_map_icon_color));
OsmandSettings.MapMarkersMode mode = getMyApplication().getSettings().MAP_MARKERS_MODE.get();
ImageView showDirectionIcon = (ImageView) mainView.findViewById(R.id.show_direction_icon);
int imageResId = 0;
switch (mode) {
case TOOLBAR:
imageResId = R.drawable.ic_action_device_topbar;
break;
case WIDGETS:
imageResId = R.drawable.ic_action_device_widget;
break;
}
showDirectionIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, R.color.on_map_icon_color));
if (imageResId != 0) {
showDirectionIcon.setImageDrawable(getIcon(imageResId, R.color.dashboard_blue));
}
((ImageView) mainView.findViewById(R.id.build_route_icon))
.setImageDrawable(getIcon(R.drawable.map_directions, R.color.on_map_icon_color));
((ImageView) mainView.findViewById(R.id.save_as_new_track_icon))
@ -49,7 +66,7 @@ public class MarkerOptionsBottomSheetDialogFragment extends BottomSheetDialogFra
((ImageView) mainView.findViewById(R.id.move_all_to_history_icon))
.setImageDrawable(getIcon(R.drawable.ic_action_history2, R.color.on_map_icon_color));
((TextView) mainView.findViewById(R.id.show_direction_text_view)).setText("Top bar");
((TextView) mainView.findViewById(R.id.show_direction_text_view)).setText(getMyApplication().getSettings().MAP_MARKERS_MODE.get().toHumanString(getActivity()));
mainView.findViewById(R.id.sort_by_row).setOnClickListener(new View.OnClickListener() {
@Override
@ -113,7 +130,7 @@ public class MarkerOptionsBottomSheetDialogFragment extends BottomSheetDialogFra
final View scrollView = mainView.findViewById(R.id.marker_options_scroll_view);
int scrollViewHeight = scrollView.getHeight();
int dividerHeight = AndroidUtils.dpToPx(getContext(), 1);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.measure_distance_bottom_sheet_cancel_button_height);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height);
int spaceForScrollView = screenHeight - statusBarHeight - navBarHeight - dividerHeight - cancelButtonHeight;
if (scrollViewHeight > spaceForScrollView) {
scrollView.getLayoutParams().height = spaceForScrollView;

View file

@ -0,0 +1,239 @@
package net.osmand.plus.mapmarkers;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
public class ShowDirectionBottomSheetDialogFragment extends BottomSheetDialogFragment {
public final static String TAG = "ShowDirectionBottomSheetDialogFragment";
private ShowDirectionFragmentListener listener;
private boolean portrait;
private View mainView;
private boolean night;
public void setListener(ShowDirectionFragmentListener listener) {
this.listener = listener;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
portrait = AndroidUiHelper.isOrientationPortrait(getActivity());
night = !getMyApplication().getSettings().isLightContent();
final int themeRes = night ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
mainView = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_marker_show_direction_bottom_sheet_dialog, container);
if (portrait) {
AndroidUtils.setBackground(getActivity(), mainView, night, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
}
OsmandSettings.MapMarkersMode mode = getMyApplication().getSettings().MAP_MARKERS_MODE.get();
highlightSelectedItem(mode, true);
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
mainView.findViewById(R.id.images_row).setVisibility(View.GONE);
} else {
ImageView topBarImage = (ImageView) mainView.findViewById(R.id.top_bar_image);
ImageView widgetImage = (ImageView) mainView.findViewById(R.id.widget_image);
if (night) {
topBarImage.setImageResource(R.drawable.img_help_markers_topbar_night);
widgetImage.setImageResource(R.drawable.img_help_markers_widgets_night);
} else {
topBarImage.setImageResource(R.drawable.img_help_markers_topbar_day);
widgetImage.setImageResource(R.drawable.img_help_markers_widgets_day);
}
mainView.findViewById(R.id.top_bar_image_text).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return false;
}
});
topBarImage.setOnClickListener(showDirectionOnClickListener);
mainView.findViewById(R.id.widget_image_text).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return false;
}
});
widgetImage.setOnClickListener(showDirectionOnClickListener);
}
if (night) {
((TextView) mainView.findViewById(R.id.show_direction_title)).setTextColor(getResources().getColor(R.color.ctx_menu_info_text_dark));
}
ImageView topBarIcon = (ImageView) mainView.findViewById(R.id.top_bar_icon);
topBarIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, R.color.on_map_icon_color));
topBarIcon.setImageDrawable(getIcon(R.drawable.ic_action_device_topbar, R.color.dashboard_blue));
ImageView widgetIcon = (ImageView) mainView.findViewById(R.id.widget_icon);
widgetIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, R.color.on_map_icon_color));
widgetIcon.setImageDrawable(getIcon(R.drawable.ic_action_device_widget, R.color.dashboard_blue));
ImageView noneIcon = (ImageView) mainView.findViewById(R.id.none_icon);
noneIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, R.color.on_map_icon_color));
mainView.findViewById(R.id.top_bar_row).setOnClickListener(showDirectionOnClickListener);
mainView.findViewById(R.id.widget_row).setOnClickListener(showDirectionOnClickListener);
mainView.findViewById(R.id.none_row).setOnClickListener(showDirectionOnClickListener);
mainView.findViewById(R.id.cancel_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
}
});
final int screenHeight = AndroidUtils.getScreenHeight(getActivity());
final int statusBarHeight = AndroidUtils.getStatusBarHeight(getActivity());
final int navBarHeight = AndroidUtils.getNavBarHeight(getActivity());
mainView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final View scrollView = mainView.findViewById(R.id.marker_show_direction_scroll_view);
int scrollViewHeight = scrollView.getHeight();
int dividerHeight = AndroidUtils.dpToPx(getContext(), 1);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height);
int spaceForScrollView = screenHeight - statusBarHeight - navBarHeight - dividerHeight - cancelButtonHeight;
if (scrollViewHeight > spaceForScrollView) {
scrollView.getLayoutParams().height = spaceForScrollView;
scrollView.requestLayout();
}
if (!portrait) {
if (screenHeight - statusBarHeight - mainView.getHeight()
>= AndroidUtils.dpToPx(getActivity(), 8)) {
AndroidUtils.setBackground(getActivity(), mainView, false,
R.drawable.bg_bottom_sheet_topsides_landscape_light, R.drawable.bg_bottom_sheet_topsides_landscape_dark);
} else {
AndroidUtils.setBackground(getActivity(), mainView, false,
R.drawable.bg_bottom_sheet_sides_landscape_light, R.drawable.bg_bottom_sheet_sides_landscape_dark);
}
}
ViewTreeObserver obs = mainView.getViewTreeObserver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
}
});
return mainView;
}
@Override
public void onStart() {
super.onStart();
if (!portrait) {
final Window window = getDialog().getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.width = getActivity().getResources().getDimensionPixelSize(R.dimen.landscape_bottom_sheet_dialog_fragment_width);
window.setAttributes(params);
}
}
private void highlightSelectedItem(OsmandSettings.MapMarkersMode mode, boolean check) {
int iconBgColor = check ? R.color.dashboard_blue : R.color.on_map_icon_color;
int iconColor = check ? R.color.color_dialog_buttons_dark : R.color.dashboard_blue;
int textColor = ContextCompat.getColor(getContext(), check ? R.color.dashboard_blue : night ? R.color.color_white : R.color.color_black);
switch (mode) {
case TOOLBAR:
((RadioButton) mainView.findViewById(R.id.top_bar_radio_button)).setChecked(check);
ImageView topBarIcon = (ImageView) mainView.findViewById(R.id.top_bar_icon);
if (check) {
mainView.findViewById(R.id.top_bar_row).setBackgroundColor(ContextCompat.getColor(getContext(), R.color.show_direction_menu_selected_item_bg));
} else {
mainView.findViewById(R.id.top_bar_row).setBackgroundResource(0);
}
((TextView) mainView.findViewById(R.id.top_bar_text)).setTextColor(textColor);
topBarIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, iconBgColor));
topBarIcon.setImageDrawable(getIcon(R.drawable.ic_action_device_topbar, iconColor));
break;
case WIDGETS:
((RadioButton) mainView.findViewById(R.id.widget_radio_button)).setChecked(check);
ImageView widgetIcon = (ImageView) mainView.findViewById(R.id.widget_icon);
if (check) {
mainView.findViewById(R.id.widget_row).setBackgroundColor(ContextCompat.getColor(getContext(), R.color.show_direction_menu_selected_item_bg));
} else {
mainView.findViewById(R.id.widget_row).setBackgroundResource(0);
}
((TextView) mainView.findViewById(R.id.widget_text)).setTextColor(textColor);
widgetIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, iconBgColor));
widgetIcon.setImageDrawable(getIcon(R.drawable.ic_action_device_widget, iconColor));
break;
case NONE:
((RadioButton) mainView.findViewById(R.id.none_radio_button)).setChecked(check);
ImageView noneIcon = (ImageView) mainView.findViewById(R.id.none_icon);
if (check) {
mainView.findViewById(R.id.none_row).setBackgroundColor(ContextCompat.getColor(getContext(), R.color.show_direction_menu_selected_item_bg));
} else {
mainView.findViewById(R.id.none_row).setBackgroundResource(0);
}
((TextView) mainView.findViewById(R.id.none_text)).setTextColor(textColor);
noneIcon.setBackgroundDrawable(getIcon(R.drawable.ic_action_device_top, iconBgColor));
break;
}
}
private View.OnClickListener showDirectionOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
OsmandSettings.MapMarkersMode previousMode = getMyApplication().getSettings().MAP_MARKERS_MODE.get();
highlightSelectedItem(previousMode, false);
boolean showDirectionEnabled = false;
switch (view.getId()) {
case R.id.top_bar_image:
case R.id.top_bar_row:
getMyApplication().getSettings().MAP_MARKERS_MODE.set(OsmandSettings.MapMarkersMode.TOOLBAR);
highlightSelectedItem(OsmandSettings.MapMarkersMode.TOOLBAR, true);
showDirectionEnabled = true;
break;
case R.id.widget_image:
case R.id.widget_row:
getMyApplication().getSettings().MAP_MARKERS_MODE.set(OsmandSettings.MapMarkersMode.WIDGETS);
highlightSelectedItem(OsmandSettings.MapMarkersMode.WIDGETS, true);
showDirectionEnabled = true;
break;
case R.id.none_row:
getMyApplication().getSettings().MAP_MARKERS_MODE.set(OsmandSettings.MapMarkersMode.NONE);
highlightSelectedItem(OsmandSettings.MapMarkersMode.NONE, true);
showDirectionEnabled = false;
break;
}
if (listener != null) {
listener.onMapMarkersModeChanged(showDirectionEnabled);
}
dismiss();
}
};
interface ShowDirectionFragmentListener {
void onMapMarkersModeChanged(boolean showDirectionEnabled);
}
}

View file

@ -0,0 +1,20 @@
package net.osmand.plus.mapmarkers.adapters;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import net.osmand.plus.R;
public class MapMarkerDateViewHolder extends RecyclerView.ViewHolder {
final TextView date;
final ImageButton optionsBtn;
public MapMarkerDateViewHolder(View itemView) {
super(itemView);
date = itemView.findViewById(R.id.date_title);
optionsBtn = itemView.findViewById(R.id.date_options_button);
}
}

View file

@ -10,24 +10,36 @@ import net.osmand.plus.R;
public class MapMarkerItemViewHolder extends RecyclerView.ViewHolder {
final View mainLayout;
final ImageView iconDirection;
final ImageView iconReorder;
final ImageView icon;
final TextView title;
final TextView distance;
final View flagIconLeftSpace;
final View leftPointSpace;
final TextView point;
final View rightPointSpace;
final TextView description;
final ImageButton optionsBtn;
public final ImageButton optionsBtn;
final View divider;
final View bottomShadow;
public MapMarkerItemViewHolder(View view) {
super(view);
mainLayout = view.findViewById(R.id.main_layout);
iconDirection = (ImageView) view.findViewById(R.id.map_marker_direction_icon);
iconReorder = (ImageView) view.findViewById(R.id.map_marker_reorder_icon);
icon = (ImageView) view.findViewById(R.id.map_marker_icon);
title = (TextView) view.findViewById(R.id.map_marker_title);
distance = (TextView) view.findViewById(R.id.map_marker_distance);
flagIconLeftSpace = view.findViewById(R.id.flag_icon_left_space);
leftPointSpace = view.findViewById(R.id.map_marker_left_point_space);
point = (TextView) view.findViewById(R.id.map_marker_point_text_view);
rightPointSpace = view.findViewById(R.id.map_marker_right_point_space);
description = (TextView) view.findViewById(R.id.map_marker_description);
optionsBtn = (ImageButton) view.findViewById(R.id.map_marker_options_button);
divider = view.findViewById(R.id.divider);
bottomShadow = view.findViewById(R.id.bottom_shadow);
}
}

View file

@ -1,22 +1,29 @@
package net.osmand.plus.mapmarkers.adapters;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.data.LatLon;
import net.osmand.plus.IconsCache;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.dashboard.DashLocationFragment;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemViewHolder>
implements MapMarkersItemTouchHelperCallback.ItemTouchHelperAdapter {
@ -24,15 +31,24 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
private MapActivity mapActivity;
private List<MapMarker> markers;
private MapMarkersActiveAdapterListener listener;
private Snackbar snackbar;
private boolean showDirectionEnabled;
private LatLon location;
private Float heading;
private boolean useCenter;
private int screenOrientation;
private boolean night;
public MapMarkersActiveAdapter(MapActivity mapActivity) {
this.mapActivity = mapActivity;
markers = mapActivity.getMyApplication().getMapMarkersHelper().getMapMarkers();
night = !mapActivity.getMyApplication().getSettings().isLightContent();
showDirectionEnabled = mapActivity.getMyApplication().getSettings().MAP_MARKERS_MODE.get() != OsmandSettings.MapMarkersMode.NONE;
}
public void setShowDirectionEnabled(boolean showDirectionEnabled) {
this.showDirectionEnabled = showDirectionEnabled;
}
public void setAdapterListener(MapMarkersActiveAdapterListener listener) {
@ -56,7 +72,7 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
}
@Override
public MapMarkerItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
public MapMarkerItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.map_marker_item_new, viewGroup, false);
view.setOnClickListener(new View.OnClickListener() {
@Override
@ -68,11 +84,51 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
}
@Override
public void onBindViewHolder(final MapMarkerItemViewHolder holder, int pos) {
public void onBindViewHolder(final MapMarkerItemViewHolder holder, final int pos) {
IconsCache iconsCache = mapActivity.getMyApplication().getIconsCache();
MapMarker marker = markers.get(pos);
holder.iconReorder.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_reorder));
ImageView markerImageViewToUpdate;
int drawableResToUpdate;
int markerColor = MapMarker.getColorId(marker.colorIndex);
LatLon markerLatLon = new LatLon(marker.getLatitude(), marker.getLongitude());
if (showDirectionEnabled && pos < 2) {
holder.iconDirection.setVisibility(View.GONE);
holder.icon.setImageDrawable(iconsCache.getIcon(R.drawable.ic_arrow_marker_diretion, markerColor));
holder.mainLayout.setBackgroundColor(ContextCompat.getColor(mapActivity, R.color.markers_top_bar_background));
holder.title.setTextColor(ContextCompat.getColor(mapActivity, R.color.color_white));
holder.divider.setBackgroundColor(ContextCompat.getColor(mapActivity, R.color.map_markers_on_map_divider_color));
holder.optionsBtn.setBackgroundDrawable(mapActivity.getResources().getDrawable(R.drawable.marker_circle_background_on_map_with_inset));
holder.optionsBtn.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_marker_passed, R.color.color_white));
holder.iconReorder.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_reorder, R.color.dashboard_subheader_text_dark));
holder.description.setTextColor(ContextCompat.getColor(mapActivity, R.color.map_markers_on_map_color));
drawableResToUpdate = R.drawable.ic_arrow_marker_diretion;
markerImageViewToUpdate = holder.icon;
} else {
holder.iconDirection.setVisibility(View.VISIBLE);
holder.icon.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_flag_dark, markerColor));
holder.mainLayout.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.bg_color_dark : R.color.bg_color_light));
holder.title.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.color_white : R.color.color_black));
holder.divider.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.dashboard_divider_dark : R.color.dashboard_divider_light));
holder.optionsBtn.setBackgroundDrawable(mapActivity.getResources().getDrawable(R.drawable.marker_circle_background_light_with_inset));
holder.optionsBtn.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_marker_passed));
holder.iconReorder.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_reorder));
holder.description.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.dash_search_icon_dark : R.color.icon_color));
drawableResToUpdate = R.drawable.ic_direction_arrow;
markerImageViewToUpdate = holder.iconDirection;
}
if (pos == getItemCount() - 1) {
holder.bottomShadow.setVisibility(View.VISIBLE);
holder.divider.setVisibility(View.GONE);
} else {
holder.bottomShadow.setVisibility(View.GONE);
holder.divider.setVisibility(View.VISIBLE);
}
holder.iconReorder.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
@ -83,14 +139,18 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
}
});
int color = MapMarker.getColorId(marker.colorIndex);
holder.icon.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_flag_dark, color));
holder.title.setText(marker.getName(mapActivity));
holder.description.setText(marker.creationDate + "");
String descr;
if ((descr = marker.groupName) != null) {
if (descr.equals("")) {
descr = mapActivity.getString(R.string.shared_string_favorites);
}
} else {
descr = new SimpleDateFormat("MMM dd", Locale.getDefault()).format(new Date(marker.creationDate));
}
holder.description.setText(descr);
holder.optionsBtn.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_remove_dark));
holder.optionsBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
@ -99,35 +159,39 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
return;
}
final MapMarker marker = markers.get(position);
final boolean[] undone = new boolean[1];
mapActivity.getMyApplication().getMapMarkersHelper().removeMapMarker(marker.index);
mapActivity.getMyApplication().getMapMarkersHelper().moveMapMarkerToHistory(marker);
notifyItemRemoved(position);
if (showDirectionEnabled && position < 2 && getItemCount() > 1) {
notifyItemChanged(1);
} else if (position == getItemCount()) {
notifyItemChanged(position - 1);
}
Snackbar.make(holder.itemView, R.string.item_removed, Snackbar.LENGTH_LONG)
snackbar = Snackbar.make(holder.itemView, mapActivity.getString(R.string.marker_moved_to_history), Snackbar.LENGTH_LONG)
.setAction(R.string.shared_string_undo, new View.OnClickListener() {
@Override
public void onClick(View view) {
undone[0] = true;
mapActivity.getMyApplication().getMapMarkersHelper().addMapMarker(marker, position);
mapActivity.getMyApplication().getMapMarkersHelper().restoreMarkerFromHistory(marker, position);
notifyItemInserted(position);
}
})
.addCallback(new Snackbar.Callback() {
@Override
public void onDismissed(Snackbar transientBottomBar, int event) {
if (!undone[0]) {
mapActivity.getMyApplication().getMapMarkersHelper().addMapMarkerHistory(marker);
if (showDirectionEnabled && position < 2 && getItemCount() > 2) {
notifyItemChanged(2);
} else if (position == getItemCount() - 1) {
notifyItemChanged(position - 1);
}
}
}).show();
});
View snackBarView = snackbar.getView();
TextView tv = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action);
tv.setTextColor(ContextCompat.getColor(mapActivity, R.color.color_dialog_buttons_dark));
snackbar.show();
}
});
DashLocationFragment.updateLocationView(useCenter, location,
heading, holder.iconDirection, holder.distance,
marker.getLatitude(), marker.getLongitude(),
screenOrientation, mapActivity.getMyApplication(), mapActivity);
heading, markerImageViewToUpdate, drawableResToUpdate, pos < 2 ? markerColor : 0,
holder.distance, markerLatLon,
screenOrientation, mapActivity.getMyApplication(), mapActivity, true);
}
@Override
@ -143,6 +207,12 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
return markers;
}
public void hideSnackbar() {
if (snackbar != null && snackbar.isShown()) {
snackbar.dismiss();
}
}
@Override
public boolean onItemMove(int from, int to) {
Collections.swap(markers, from, to);

View file

@ -0,0 +1,51 @@
package net.osmand.plus.mapmarkers.adapters;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import net.osmand.plus.IconsCache;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import java.util.List;
public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<MapMarkerItemViewHolder> {
private MapActivity mapActivity;
private List<MapMarkersHelper.MapMarker> markers;
private boolean night;
public MapMarkersGroupsAdapter(MapActivity mapActivity) {
this.mapActivity = mapActivity;
markers = mapActivity.getMyApplication().getMapMarkersHelper().getMapMarkers();
night = !mapActivity.getMyApplication().getSettings().isLightContent();
}
@Override
public MapMarkerItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.map_marker_item_new, viewGroup, false);
return new MapMarkerItemViewHolder(view);
}
@Override
public void onBindViewHolder(MapMarkerItemViewHolder mapMarkerItemViewHolder, int i) {
IconsCache iconsCache = mapActivity.getMyApplication().getIconsCache();
MapMarkersHelper.MapMarker marker = markers.get(i);
}
@Override
public int getItemCount() {
return markers.size();
}
public MapMarkersHelper.MapMarker getItem(int position) {
return markers.get(position);
}
public List<MapMarkersHelper.MapMarker> getItems() {
return markers;
}
}

View file

@ -10,17 +10,76 @@ import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class MapMarkersHistoryAdapter extends RecyclerView.Adapter<MapMarkerItemViewHolder> {
public class MapMarkersHistoryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int DATE_TYPE = 1;
private static final int MARKER_TYPE = 2;
private static final int TODAY_HEADER = 56;
private static final int YESTERDAY_HEADER = 57;
private static final int LAST_SEVEN_DAYS_HEADER = 58;
private static final int THIS_YEAR_HEADER = 59;
private OsmandApplication app;
private List<MapMarker> markers;
private List<Object> items = new ArrayList<>();
private MapMarkersHistoryAdapterListener listener;
public MapMarkersHistoryAdapter(OsmandApplication app) {
this.app = app;
markers = app.getMapMarkersHelper().getMapMarkersHistory();
createHeaders();
}
public void createHeaders() {
items.clear();
List<MapMarker> markersHistory = app.getMapMarkersHelper().getMapMarkersHistory();
int previousHeader = -1;
int monthsDisplayed = 0;
Calendar currentDateCalendar = Calendar.getInstance();
currentDateCalendar.setTimeInMillis(System.currentTimeMillis());
int currentDay = currentDateCalendar.get(Calendar.DAY_OF_YEAR);
int currentMonth = currentDateCalendar.get(Calendar.MONTH);
int currentYear = currentDateCalendar.get(Calendar.YEAR);
Calendar markerCalendar = Calendar.getInstance();
for (int i = 0; i < markersHistory.size(); i++) {
MapMarker marker = markersHistory.get(i);
markerCalendar.setTimeInMillis(marker.visitedDate);
int markerDay = markerCalendar.get(Calendar.DAY_OF_YEAR);
int markerMonth = markerCalendar.get(Calendar.MONTH);
int markerYear = markerCalendar.get(Calendar.YEAR);
if (markerYear == currentYear) {
if (markerDay == currentDay && previousHeader != TODAY_HEADER) {
items.add(TODAY_HEADER);
previousHeader = TODAY_HEADER;
} else if (markerDay == currentDay - 1 && previousHeader != YESTERDAY_HEADER) {
items.add(YESTERDAY_HEADER);
previousHeader = YESTERDAY_HEADER;
} else if (currentDay - markerDay >= 2 && currentDay - markerDay <= 8 && previousHeader != LAST_SEVEN_DAYS_HEADER) {
items.add(LAST_SEVEN_DAYS_HEADER);
previousHeader = LAST_SEVEN_DAYS_HEADER;
} else if (currentDay - markerDay > 8 && monthsDisplayed < 3 && previousHeader != markerMonth) {
items.add(markerMonth);
previousHeader = markerMonth;
monthsDisplayed += 1;
} else if (currentMonth - markerMonth >= 4 && previousHeader != THIS_YEAR_HEADER) {
items.add(THIS_YEAR_HEADER);
previousHeader = THIS_YEAR_HEADER;
}
} else if (previousHeader != markerYear) {
items.add(markerYear);
previousHeader = markerYear;
}
items.add(marker);
}
}
public void setAdapterListener(MapMarkersHistoryAdapterListener listener) {
@ -28,52 +87,109 @@ public class MapMarkersHistoryAdapter extends RecyclerView.Adapter<MapMarkerItem
}
@Override
public MapMarkerItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.map_marker_item_new, viewGroup, false);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onItemClick(view);
}
});
return new MapMarkerItemViewHolder(view);
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
if (viewType == MARKER_TYPE) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.map_marker_item_new, viewGroup, false);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onItemClick(view);
}
});
return new MapMarkerItemViewHolder(view);
} else if (viewType == DATE_TYPE) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.map_marker_item_date, viewGroup, false);
return new MapMarkerDateViewHolder(view);
} else {
throw new IllegalArgumentException("Unsupported view type");
}
}
@Override
public void onBindViewHolder(final MapMarkerItemViewHolder holder, int pos) {
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
IconsCache iconsCache = app.getIconsCache();
MapMarker marker = markers.get(pos);
if (holder instanceof MapMarkerItemViewHolder) {
final MapMarkerItemViewHolder itemViewHolder = (MapMarkerItemViewHolder) holder;
final MapMarker marker = (MapMarker) getItem(position);
itemViewHolder.iconReorder.setVisibility(View.GONE);
holder.iconReorder.setVisibility(View.GONE);
int color = MapMarker.getColorId(marker.colorIndex);
itemViewHolder.icon.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_flag_dark, color));
int color = MapMarker.getColorId(marker.colorIndex);
holder.icon.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_flag_dark, color));
itemViewHolder.title.setText(marker.getName(app));
holder.title.setText(marker.getName(app));
itemViewHolder.description.setText(app.getString(R.string.passed, new SimpleDateFormat("MMM dd", Locale.getDefault()).format(new Date(marker.visitedDate))));
holder.optionsBtn.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_refresh_dark));
holder.optionsBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = holder.getAdapterPosition();
if (position < 0) {
return;
itemViewHolder.optionsBtn.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_reset_to_default_dark));
itemViewHolder.optionsBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = itemViewHolder.getAdapterPosition();
if (position < 0) {
return;
}
app.getMapMarkersHelper().restoreMarkerFromHistory(marker, 0);
notifyItemRemoved(position);
}
MapMarker marker = markers.get(position);
app.getMapMarkersHelper().removeMapMarkerHistory(marker);
app.getMapMarkersHelper().addMapMarker(marker, 0);
notifyItemRemoved(position);
});
itemViewHolder.flagIconLeftSpace.setVisibility(View.VISIBLE);
itemViewHolder.iconDirection.setVisibility(View.GONE);
itemViewHolder.leftPointSpace.setVisibility(View.GONE);
itemViewHolder.rightPointSpace.setVisibility(View.GONE);
if (position == getItemCount() - 1) {
itemViewHolder.bottomShadow.setVisibility(View.VISIBLE);
itemViewHolder.divider.setVisibility(View.GONE);
} else {
itemViewHolder.bottomShadow.setVisibility(View.GONE);
itemViewHolder.divider.setVisibility(View.VISIBLE);
}
});
} else if (holder instanceof MapMarkerDateViewHolder) {
final MapMarkerDateViewHolder dateViewHolder = (MapMarkerDateViewHolder) holder;
final Integer dateHeader = (Integer) getItem(position);
String dateString;
if (dateHeader == TODAY_HEADER) {
dateString = app.getString(R.string.today);
} else if (dateHeader == YESTERDAY_HEADER) {
dateString = app.getString(R.string.yesterday);
} else if (dateHeader == LAST_SEVEN_DAYS_HEADER) {
dateString = app.getString(R.string.last_seven_days);
} else if (dateHeader == THIS_YEAR_HEADER) {
dateString = app.getString(R.string.this_year);
} else if (dateHeader / 100 == 0) {
dateString = getMonth(dateHeader);
} else {
dateString = String.valueOf(dateHeader);
}
dateViewHolder.date.setText(dateString);
}
}
@Override
public int getItemViewType(int position) {
Object item = items.get(position);
if (item instanceof MapMarker) {
return MARKER_TYPE;
} else if (item instanceof Integer) {
return DATE_TYPE;
} else {
throw new IllegalArgumentException("Unsupported view type");
}
}
@Override
public int getItemCount() {
return markers.size();
return items.size();
}
public MapMarker getItem(int position) {
return markers.get(position);
public Object getItem(int position) {
return items.get(position);
}
private String getMonth(int month) {
SimpleDateFormat dateFormat = new SimpleDateFormat("LLLL", Locale.getDefault());
Date date = new Date();
date.setMonth(month);
return dateFormat.format(date);
}
public interface MapMarkersHistoryAdapterListener {

View file

@ -1435,11 +1435,7 @@ public class MeasurementToolFragment extends Fragment {
builder.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
GPXFile gpx = editingCtx.getNewGpxData().getGpxFile();
SelectedGpxFile selectedGpxFile = mapActivity.getMyApplication().getSelectedGpxHelper().getSelectedFileByPath(gpx.path);
boolean showOnMap = selectedGpxFile != null;
ActionType actionType = editingCtx.getNewGpxData().getActionType();
saveExistingGpx(gpx, showOnMap, actionType, true);
dismiss(mapActivity);
}
});
}

View file

@ -141,7 +141,7 @@ public class OptionsBottomSheetDialogFragment extends BottomSheetDialogFragment
final View scrollView = mainView.findViewById(R.id.measure_options_scroll_view);
int scrollViewHeight = scrollView.getHeight();
int dividerHeight = AndroidUtils.dpToPx(getContext(), 1);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.measure_distance_bottom_sheet_cancel_button_height);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height);
int spaceForScrollView = screenHeight - statusBarHeight - navBarHeight - dividerHeight - cancelButtonHeight;
if (scrollViewHeight > spaceForScrollView) {
scrollView.getLayoutParams().height = spaceForScrollView;

View file

@ -102,7 +102,7 @@ public class SaveAsNewTrackBottomSheetDialogFragment extends BottomSheetDialogFr
final View scrollView = mainView.findViewById(R.id.save_as_new_track_scroll_view);
int scrollViewHeight = scrollView.getHeight();
int dividerHeight = AndroidUtils.dpToPx(getContext(), 1);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.measure_distance_bottom_sheet_cancel_button_height);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height);
int spaceForScrollView = screenHeight - statusBarHeight - navBarHeight - dividerHeight - cancelButtonHeight;
if (scrollViewHeight > spaceForScrollView) {
scrollView.getLayoutParams().height = spaceForScrollView;

View file

@ -167,7 +167,7 @@ public class SelectedPointBottomSheetDialogFragment extends BottomSheetDialogFra
final View scrollView = mainView.findViewById(R.id.selected_point_options_scroll_view);
int scrollViewHeight = scrollView.getHeight();
int dividerHeight = AndroidUtils.dpToPx(getContext(), 1);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.measure_distance_bottom_sheet_cancel_button_height);
int cancelButtonHeight = getContext().getResources().getDimensionPixelSize(R.dimen.bottom_sheet_cancel_button_height);
int spaceForScrollView = screenHeight - statusBarHeight - navBarHeight - dividerHeight - cancelButtonHeight;
if (scrollViewHeight > spaceForScrollView) {
scrollView.getLayoutParams().height = spaceForScrollView;

View file

@ -44,6 +44,7 @@ import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
import net.osmand.plus.IconsCache;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MarkersSyncGroup;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
@ -607,7 +608,10 @@ public class TrackPointFragment extends OsmandExpandableListFragment {
names.add(new PointDescription(PointDescription.POINT_TYPE_MAP_MARKER, i.name));
}
}
markersHelper.addMapMarkers(points, names);
File gpx = getGpxDataItem().getFile();
MarkersSyncGroup syncGroup = new MarkersSyncGroup(gpx.getAbsolutePath(), trimExtension(gpx.getName()), MarkersSyncGroup.GPX_TYPE);
markersHelper.addMarkersSyncGroup(syncGroup);
markersHelper.addMapMarkers(points, names, syncGroup);
MapActivity.launchMapActivityMoveToTop(getActivity());
} else {
final TargetPointsHelper targetPointsHelper = getMyApplication().getTargetPointsHelper();
@ -626,6 +630,14 @@ public class TrackPointFragment extends OsmandExpandableListFragment {
}
}
private String trimExtension(String src) {
int index = src.lastIndexOf('.');
if (index != -1) {
return src.substring(0, index);
}
return src;
}
private void enterFavoritesMode() {
actionMode = getActionBarActivity().startSupportActionMode(new ActionMode.Callback() {

View file

@ -35,15 +35,6 @@ public class NativeOsmandLibrary extends NativeLibrary {
try {
log.debug("Loading native gnustl_shared..."); //$NON-NLS-1$
System.loadLibrary("gnustl_shared");
if (android.os.Build.VERSION.SDK_INT >= 8) {
log.debug("Loading jnigraphics, since Android >= 2.2 ..."); //$NON-NLS-1$
try {
System.loadLibrary("jnigraphics");
} catch( UnsatisfiedLinkError e ) {
// handle "Shared library already opened" error
log.debug("Failed to load jnigraphics: " + e); //$NON-NLS-1$
}
}
log.debug("Loading native libraries..."); //$NON-NLS-1$
System.loadLibrary("osmand");
log.debug("Creating NativeOsmandLibrary instance..."); //$NON-NLS-1$

View file

@ -1193,12 +1193,15 @@ public class MapControlsLayer extends OsmandMapLayer {
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_LOCATION_FOR_NAVIGATION_PERMISSION
&& grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
onNavigationClick();
} else if (requestCode == REQUEST_LOCATION_FOR_NAVIGATION_FAB_PERMISSION
&& grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
navigateFab();
} else if (requestCode == REQUEST_LOCATION_FOR_ADD_DESTINATION_PERMISSION
&& grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
addDestination(requestedLatLon);
}

View file

@ -493,16 +493,7 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
@Override
public void setSelectedObject(Object o) {
if (o instanceof MapMarker) {
MapMarkersHelper markersHelper = map.getMyApplication().getMapMarkersHelper();
MapMarker marker = (MapMarker) o;
List<MapMarker> mapMarkers = markersHelper.getMapMarkers();
int i = mapMarkers.indexOf(marker);
if (i != -1) {
mapMarkers.remove(i);
mapMarkers.add(0, marker);
markersHelper.saveMapMarkers(mapMarkers, null);
marker.index = 0;
}
map.getMyApplication().getMapMarkersHelper().moveMarkerToTop((MapMarker) o);
}
}

View file

@ -131,9 +131,7 @@ public class MapMarkersWidgetsFactory {
private void removeMarker(int index) {
if (helper.getMapMarkers().size() > index) {
MapMarker marker = helper.getMapMarkers().get(index);
helper.removeMapMarker(marker.index);
helper.addMapMarkerHistory(marker);
helper.moveMapMarkerToHistory(helper.getMapMarkers().get(index));
}
}

View file

@ -345,16 +345,7 @@ public class MapWidgetRegistry {
@Override
public void onClick(DialogInterface dialog, int which) {
settings.MAP_MARKERS_MODE.set(MapMarkersMode.values()[which]);
for (MapWidgetRegInfo info : rightWidgetSet) {
if ("map_marker_1st".equals(info.key) || "map_marker_2nd".equals(info.key)) {
setVisibility(info, settings.MAP_MARKERS_MODE.get().isWidgets(), false);
}
}
MapInfoLayer mil = map.getMapLayers().getMapInfoLayer();
if (mil != null) {
mil.recreateControls();
}
map.refreshMap();
updateMapMarkersMode(map);
dialog.dismiss();
cm.getItem(pos).setDescription(settings.MAP_MARKERS_MODE.get().toHumanString(map));
ad.notifyDataSetChanged();
@ -367,6 +358,19 @@ public class MapWidgetRegistry {
}
}
public void updateMapMarkersMode(MapActivity mapActivity) {
for (MapWidgetRegInfo info : rightWidgetSet) {
if ("map_marker_1st".equals(info.key) || "map_marker_2nd".equals(info.key)) {
setVisibility(info, settings.MAP_MARKERS_MODE.get().isWidgets(), false);
}
}
MapInfoLayer mil = mapActivity.getMapLayers().getMapInfoLayer();
if (mil != null) {
mil.recreateControls();
}
mapActivity.refreshMap();
}
private void addControlId(final MapActivity map, ContextMenuAdapter cm,
@StringRes int stringId, OsmandPreference<Boolean> pref) {
cm.addItem(new ContextMenuItem.ItemBuilder().setTitleId(stringId, map)