Compare commits

...

19 commits
master ... r2.4

Author SHA1 Message Date
Alexey Kulish
f4f3d2d5a1 Fix 2016-09-16 19:38:32 +03:00
Alexey Kulish
2794e4566f Fix 2016-09-16 19:35:32 +03:00
Alexey Kulish
15f71076f4 Merge 2016-09-16 19:27:17 +03:00
Alexey Kulish
26703154b1 Fix #3051 2016-09-13 18:13:42 +03:00
Victor Shcherb
4f3b58da9b Update search display 2016-09-02 19:59:25 +02:00
Victor Shcherb
0cb3914786 Add version to http requests, change post to get parameter 2016-08-24 11:49:31 +02:00
Victor Shcherb
77faa8d090 Fix show on map search by name filter 2016-08-22 18:17:38 +03:00
Victor Shcherb
237e385478 Update layout 2016-08-22 12:15:46 +03:00
Alexey Kulish
c584fcac94 Fix save changes button 2016-08-22 11:58:17 +03:00
Alexey Kulish
c9d1b96ff1 Fix permission for FAB. Fix icon. 2016-08-22 11:27:58 +03:00
Dmitriy Prodchenko
152e219def Payment icon 2016-08-22 11:06:14 +03:00
Victor Shcherb
b97c5ee0dc Update translation 2016-08-22 11:04:25 +03:00
Victor Shcherb
0f5f2503b2 Add new turns 2016-08-22 11:04:25 +03:00
Alexey Kulish
20f6d51526 Fix osm live fragment crash on 2.3 2016-08-20 21:27:26 +03:00
Alexey Kulish
9116cdb093 Changed osm live subscription form 2016-08-20 21:12:08 +03:00
xmd5a
09a7f13702 Update ru strings 2016-08-19 18:55:18 +03:00
Victor Shcherb
045f35c114 Merge branch 'r2.4' of github.com:osmandapp/Osmand into r2.4 2016-08-19 18:28:02 +03:00
Victor Shcherb
9d4ebbd363 Fix osm live 2016-08-19 18:26:28 +03:00
Alexey Kulish
6416764c7a Remove storage dialog from downloads 2016-08-19 18:06:47 +03:00
31 changed files with 829 additions and 667 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.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.3 KiB

View file

@ -10,13 +10,15 @@
<FrameLayout <FrameLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" > android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" >
<TextView <TextView
android:id="@+id/widget_top_icon_text" android:id="@+id/widget_top_icon_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:gravity="center"
android:layout_marginTop="2dp" android:layout_marginTop="2dp"
android:textColor="@color/color_black" android:textColor="@color/color_black"
android:textSize="@dimen/map_widget_text_size" android:textSize="@dimen/map_widget_text_size"
@ -28,6 +30,7 @@
android:layout_height="@dimen/map_widget_image" android:layout_height="@dimen/map_widget_image"
android:layout_marginTop="2dp" android:layout_marginTop="2dp"
android:layout_gravity="center" android:layout_gravity="center"
android:gravity="center"
android:src="@drawable/ic_action_test_light" android:src="@drawable/ic_action_test_light"
android:visibility="gone" /> android:visibility="gone" />
</FrameLayout> </FrameLayout>

View file

@ -15,17 +15,17 @@
<ImageButton <ImageButton
android:id="@+id/closeButton" android:id="@+id/closeButton"
android:contentDescription="@string/shared_string_close"
style="@style/Widget.AppCompat.Button.Borderless" style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="52dp" android:layout_width="52dp"
android:layout_height="52dp" android:layout_height="52dp"
android:contentDescription="@string/shared_string_close"
android:src="@drawable/ic_action_remove_dark"/> android:src="@drawable/ic_action_remove_dark"/>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/titleTextView" android:id="@+id/titleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="16dp" android:layout_marginLeft="20dp"
android:text="@string/osm_live_subscription" android:text="@string/osm_live_subscription"
android:textColor="@color/color_white" android:textColor="@color/color_white"
android:textSize="@dimen/default_list_text_size_large" android:textSize="@dimen/default_list_text_size_large"
@ -49,6 +49,143 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
android:orientation="vertical">
<LinearLayout
android:id="@+id/headerLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:orientation="vertical"
android:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:minHeight="56dp"
android:orientation="horizontal">
<android.support.v7.widget.AppCompatImageView
android:layout_width="56dp"
android:layout_height="48dp"
android:scaleType="center"
android:src="@drawable/ic_action_osm_live"
android:tint="@color/osmand_orange"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:paddingLeft="2dp"
android:text="@string/osm_live_subscription_desc"
android:textColor="?android:attr/textColorPrimary"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="4dp"
android:minHeight="56dp"
android:orientation="vertical">
<android.support.v7.widget.AppCompatCheckBox
android:id="@+id/donationCheckbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:paddingLeft="34dp"
android:text="@string/donation_to_osm"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="72dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:paddingLeft="2dp"
android:text="@string/donation_to_osm_desc"
android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/paramsLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginBottom="6dp"
android:background="?attr/dashboard_divider"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="4dp"
android:minHeight="56dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/countryIcon"
android:layout_width="56dp"
android:layout_height="48dp"
android:scaleType="center"
android:src="@drawable/ic_world_globe_dark"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="2dp"
android:text="@string/osm_live_support_region"
android:textColor="?android:attr/textColorSecondary"/>
<net.osmand.plus.widgets.AutoCompleteTextViewEx
android:id="@+id/selectCountryEdit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawableRight="@drawable/ic_action_arrow_drop_down"
android:editable="false"
android:paddingLeft="2dp"
android:paddingRight="0dp"
android:text="Ukraine"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:paddingLeft="2dp"
android:text="@string/osm_live_region_desc"
android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -126,61 +263,10 @@
android:layout_marginLeft="72dp" android:layout_marginLeft="72dp"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:paddingLeft="2dp" android:paddingLeft="4dp"
android:text="@string/osm_live_hide_user_name" android:text="@string/osm_live_hide_user_name"
android:textColor="?android:attr/textColorPrimary"/> android:textColor="?android:attr/textColorPrimary"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="4dp"
android:minHeight="56dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/countryIcon"
android:layout_width="56dp"
android:layout_height="48dp"
android:scaleType="center"
android:src="@drawable/ic_world_globe_dark"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="2dp"
android:text="@string/osm_live_support_region"
android:textColor="?android:attr/textColorSecondary"/>
<net.osmand.plus.widgets.AutoCompleteTextViewEx
android:id="@+id/selectCountryEdit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawableRight="@drawable/ic_action_arrow_drop_down"
android:editable="false"
android:paddingLeft="2dp"
android:paddingRight="0dp"
android:text="Ukraine"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:paddingLeft="2dp"
android:text="@string/osm_live_region_desc"
android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
@ -207,79 +293,115 @@
</LinearLayout> </LinearLayout>
</LinearLayout>
<include layout="@layout/card_bottom_divider"/>
<View
android:layout_width="match_parent"
android:layout_height="8dp"/>
<include layout="@layout/card_top_divider"/>
<LinearLayout <LinearLayout
android:id="@+id/purchaseCard" android:id="@+id/purchaseCard"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="8dp" android:background="?attr/bg_color"
android:background="?attr/bg_card"
android:orientation="vertical" android:orientation="vertical"
android:visibility="visible"> android:visibility="visible">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_marginTop="8dp"
android:orientation="horizontal"> android:orientation="horizontal">
<net.osmand.plus.widgets.TextViewEx <android.support.v7.widget.AppCompatImageView
android:layout_width="0dp" android:layout_width="56dp"
android:layout_height="48dp"
android:scaleType="center"
android:tint="?attr/color_dialog_buttons"
android:src="@drawable/ic_action_payment_card"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_marginLeft="16dp"
android:text="@string/osm_live_month_cost" android:layout_marginRight="16dp"
android:textColor="?android:attr/textColorPrimary" android:orientation="vertical">
android:textSize="@dimen/default_list_text_size_large"
android:textStyle="bold"/> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/priceTextView" android:id="@+id/priceTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:gravity="right" android:gravity="right"
android:text="@string/osm_live_default_price" android:text="@string/osm_live_default_price"
android:textColor="?attr/color_dialog_buttons" android:textColor="?attr/color_dialog_buttons"
android:textSize="@dimen/default_list_text_size_large" android:textSize="@dimen/default_list_text_size_large"
android:textStyle="bold"/> android:textStyle="bold"/>
<net.osmand.plus.widgets.TextViewEx
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" - "
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/default_list_text_size_large"
android:textStyle="bold"/>
<net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/osm_live_month_cost"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/default_list_text_size_large"
android:textStyle="bold"/>
</LinearLayout> </LinearLayout>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="16dp" android:layout_marginTop="8dp"
android:layout_marginRight="16dp" android:text="@string/osm_live_payment_desc"
android:text="@string/osm_live_month_cost_desc"
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/default_desc_text_size"/> android:textSize="@dimen/default_desc_text_size"/>
<View <android.support.v7.widget.AppCompatButton
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="10dp"
android:background="?attr/divider_color"/>
<Button
android:id="@+id/subscribeButton" android:id="@+id/subscribeButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="right" android:layout_marginTop="16dp"
android:layout_marginBottom="10dp" android:layout_marginBottom="20dp"
android:layout_marginLeft="16dp" android:background="@drawable/blue_button_drawable"
android:layout_marginRight="6dp" android:paddingBottom="4dp"
android:background="?attr/selectableItemBackground" android:paddingLeft="14dp"
android:paddingLeft="10dp" android:paddingRight="14dp"
android:paddingRight="10dp" android:paddingTop="4dp"
android:text="@string/osm_live_subscribe_btn" android:text="@string/osm_live_subscribe_btn"
android:textColor="?attr/color_dialog_buttons"/> android:textColor="@color/color_white"
android:visibility="visible"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout>
<include layout="@layout/card_bottom_divider"/>
<View
android:layout_width="match_parent"
android:layout_height="16dp"/>
</LinearLayout>
</ScrollView> </ScrollView>
</FrameLayout> </FrameLayout>

View file

@ -2090,8 +2090,8 @@
<string name="si_mi_meters">Мили/метры</string> <string name="si_mi_meters">Мили/метры</string>
<string name="get_for">Получить за %1$s</string> <string name="get_for">Получить за %1$s</string>
<string name="get_for_month">Получить за %1$s в месяц</string> <string name="get_for_month">Получить за %1$s в месяц</string>
<string name="get_it">Возьмите</string> <string name="get_it">Получить</string>
<string name="osm_live_banner_desc">Получите неограниченные загрузки карт и обновления более чем один раз в месяц: ежечасно, ежедневно или еженедельно.</string> <string name="osm_live_banner_desc">Получите неограниченные загрузки карт и обновления более чем один раз в месяц: ежечасно, ежедневно или еженедельно</string>
<string name="osmand_plus_banner_desc">Полная версия OsmAnd с неограниченной загрузкой карт и ежемесячных обновлений карты.</string> <string name="osmand_plus_banner_desc">Полная версия OsmAnd с неограниченной загрузкой карт и ежемесячных обновлений карты</string>
<string name="select_voice_provider">Выберите голосовое руководство</string> <string name="select_voice_provider">Выберите голосовое сопровождение</string>
</resources> </resources>

View file

@ -1,4 +1,4 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<resources> <resources>
<!-- <!--
Disclaimer: Disclaimer:
@ -9,6 +9,10 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
--> -->
<string name="osm_live_payment_desc">Subscription fee will be charged each month. You can always cancel your subscription on Google Play.</string>
<string name="donation_to_osm">Donation to OpenStreetMap community</string>
<string name="donation_to_osm_desc">Part of your donation will be sent to OSM users who submit changes to the OpenStreetMaps. Cost of the subscription remains the same.</string>
<string name="osm_live_subscription_desc">Subscription enables hourly, daily, weekly updates and unlimited downloads for all maps around the world.</string>
<string name="get_it">Get it</string> <string name="get_it">Get it</string>
<string name="get_for">Get for %1$s</string> <string name="get_for">Get for %1$s</string>
<string name="get_for_month">Get for %1$s month</string> <string name="get_for_month">Get for %1$s month</string>
@ -182,7 +186,7 @@
<string name="osm_live_ask_for_purchase">Please purchase OSM Live subscription first</string> <string name="osm_live_ask_for_purchase">Please purchase OSM Live subscription first</string>
<string name="osm_live_header">This subscription enables hourly updates for all maps around the world. <string name="osm_live_header">This subscription enables hourly updates for all maps around the world.
Most of the income goes back to the OSM community and is paid for each OSM contribution. Part of the income goes back to the OSM community and is paid for each OSM contribution.
If you love OsmAnd and OSM and want to support them, this is the perfect way to do it.</string> If you love OsmAnd and OSM and want to support them, this is the perfect way to do it.</string>
<string name="select_map_marker">Select map marker</string> <string name="select_map_marker">Select map marker</string>

View file

@ -30,6 +30,7 @@ public class AndroidNetworkUtils {
final Map<String, String> parameters, final Map<String, String> parameters,
final String userOperation, final String userOperation,
final boolean toastAllowed, final boolean toastAllowed,
final boolean post,
final OnRequestResultListener listener) { final OnRequestResultListener listener) {
new AsyncTask<Void, Void, String>() { new AsyncTask<Void, Void, String>() {
@ -37,7 +38,7 @@ public class AndroidNetworkUtils {
@Override @Override
protected String doInBackground(Void... params) { protected String doInBackground(Void... params) {
try { try {
return sendRequest(ctx, url, parameters, userOperation, toastAllowed); return sendRequest(ctx, url, parameters, userOperation, toastAllowed, post);
} catch (Exception e) { } catch (Exception e) {
return null; return null;
} }
@ -55,15 +56,11 @@ public class AndroidNetworkUtils {
public static String sendRequest(OsmandApplication ctx, String url, Map<String, String> parameters, public static String sendRequest(OsmandApplication ctx, String url, Map<String, String> parameters,
String userOperation, boolean toastAllowed) { String userOperation, boolean toastAllowed, boolean post) {
HttpURLConnection connection = null; HttpURLConnection connection = null;
try { try {
connection = NetworkUtils.getHttpURLConnection(url);
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("User-Agent", Version.getFullVersion(ctx));
connection.setConnectTimeout(15000);
String params = null;
if (parameters != null && parameters.size() > 0) { if (parameters != null && parameters.size() > 0) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : parameters.entrySet()) { for (Map.Entry<String, String> entry : parameters.entrySet()) {
@ -72,13 +69,18 @@ public class AndroidNetworkUtils {
} }
sb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8")); sb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8"));
} }
String params = sb.toString(); params = sb.toString();
}
String paramsSeparator = url.indexOf('?') == -1 ? "?" : "&";
connection = NetworkUtils.getHttpURLConnection(params == null || post ? url : url + paramsSeparator + params);
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("User-Agent", Version.getFullVersion(ctx));
connection.setConnectTimeout(15000);
if (params != null && post) {
connection.setDoInput(true); connection.setDoInput(true);
connection.setDoOutput(true); connection.setDoOutput(true);
connection.setUseCaches(false); connection.setUseCaches(false);
connection.setRequestMethod("POST"); connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
connection.setRequestProperty("Content-Length", String.valueOf(params.getBytes("UTF-8").length)); connection.setRequestProperty("Content-Length", String.valueOf(params.getBytes("UTF-8").length));
connection.setFixedLengthStreamingMode(params.getBytes("UTF-8").length); connection.setFixedLengthStreamingMode(params.getBytes("UTF-8").length);
@ -89,6 +91,7 @@ public class AndroidNetworkUtils {
output.close(); output.close();
} else { } else {
connection.setRequestMethod("GET"); connection.setRequestMethod("GET");
connection.connect(); connection.connect();
} }

View file

@ -895,11 +895,14 @@ public class OsmandSettings {
// this value string is synchronized with settings_pref.xml preference name // this value string is synchronized with settings_pref.xml preference name
public final OsmandPreference<String> USER_NAME = new StringPreference("user_name", "").makeGlobal(); public final OsmandPreference<String> USER_NAME = new StringPreference("user_name", "").makeGlobal();
public static final String BILLING_USER_DONATION_WORLD_PARAMETER = "";
public static final String BILLING_USER_DONATION_NONE_PARAMETER = "none";
public final OsmandPreference<String> BILLING_USER_ID = new StringPreference("billing_user_id", "").makeGlobal(); public final OsmandPreference<String> BILLING_USER_ID = new StringPreference("billing_user_id", "").makeGlobal();
public final OsmandPreference<String> BILLING_USER_NAME = new StringPreference("billing_user_name", "").makeGlobal(); public final OsmandPreference<String> BILLING_USER_NAME = new StringPreference("billing_user_name", "").makeGlobal();
public final OsmandPreference<String> BILLING_USER_EMAIL = new StringPreference("billing_user_email", "").makeGlobal(); public final OsmandPreference<String> BILLING_USER_EMAIL = new StringPreference("billing_user_email", "").makeGlobal();
public final OsmandPreference<String> BILLING_USER_COUNTRY = new StringPreference("billing_user_country", "").makeGlobal(); public final OsmandPreference<String> BILLING_USER_COUNTRY = new StringPreference("billing_user_country", "").makeGlobal();
public final OsmandPreference<String> BILLING_USER_COUNTRY_DOWNLOAD_NAME = new StringPreference("billing_user_country_download_name", "").makeGlobal(); public final OsmandPreference<String> BILLING_USER_COUNTRY_DOWNLOAD_NAME = new StringPreference("billing_user_country_download_name", BILLING_USER_DONATION_NONE_PARAMETER).makeGlobal();
public final OsmandPreference<Boolean> BILLING_HIDE_USER_NAME = new BooleanPreference("billing_hide_user_name", false).makeGlobal(); public final OsmandPreference<Boolean> BILLING_HIDE_USER_NAME = new BooleanPreference("billing_hide_user_name", false).makeGlobal();
public final OsmandPreference<Boolean> BILLING_PURCHASE_TOKEN_SENT = new BooleanPreference("billing_purchase_token_sent", false).makeGlobal(); public final OsmandPreference<Boolean> BILLING_PURCHASE_TOKEN_SENT = new BooleanPreference("billing_purchase_token_sent", false).makeGlobal();
public final OsmandPreference<Boolean> LIVE_UPDATES_PURCHASED = new BooleanPreference("billing_live_updates_purchased", false).makeGlobal(); public final OsmandPreference<Boolean> LIVE_UPDATES_PURCHASED = new BooleanPreference("billing_live_updates_purchased", false).makeGlobal();

View file

@ -128,6 +128,8 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
private static final int SHOW_POSITION_MSG_ID = OsmAndConstants.UI_HANDLER_MAP_VIEW + 1; private static final int SHOW_POSITION_MSG_ID = OsmAndConstants.UI_HANDLER_MAP_VIEW + 1;
private static final int LONG_KEYPRESS_MSG_ID = OsmAndConstants.UI_HANDLER_MAP_VIEW + 2; private static final int LONG_KEYPRESS_MSG_ID = OsmAndConstants.UI_HANDLER_MAP_VIEW + 2;
private static final int LONG_KEYPRESS_DELAY = 500; private static final int LONG_KEYPRESS_DELAY = 500;
private static final int ZOOM_LABEL_DISPLAY = 16;
private static final int MIN_ZOOM_LABEL_DISPLAY = 12;
private static final Log LOG = PlatformUtil.getLog(MapActivity.class); private static final Log LOG = PlatformUtil.getLog(MapActivity.class);
@ -277,13 +279,6 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
} }
mapView.refreshMap(true); mapView.refreshMap(true);
if (((app.getAppInitializer().isFirstTime() && Version.isDeveloperVersion(app))
|| !app.getResourceManager().isAnyMapIstalled()) && FirstUsageWelcomeFragment.SHOW) {
FirstUsageWelcomeFragment.SHOW = false;
getSupportFragmentManager().beginTransaction()
.add(R.id.fragmentContainer, new FirstUsageWelcomeFragment(),
FirstUsageWelcomeFragment.TAG).commitAllowingStateLoss();
}
mapActions.updateDrawerMenu(); mapActions.updateDrawerMenu();
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
@ -626,6 +621,14 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
} }
} }
enableDrawer(); enableDrawer();
if (((app.getAppInitializer().isFirstTime() && Version.isDeveloperVersion(app))
|| !app.getResourceManager().isAnyMapIstalled()) && FirstUsageWelcomeFragment.SHOW) {
getSupportFragmentManager().beginTransaction()
.add(R.id.fragmentContainer, new FirstUsageWelcomeFragment(),
FirstUsageWelcomeFragment.TAG).commitAllowingStateLoss();
}
FirstUsageWelcomeFragment.SHOW = false;
} }
@Override @Override
@ -749,7 +752,6 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
} }
// remember if map should come back to isMapLinkedToLocation=true // remember if map should come back to isMapLinkedToLocation=true
mapViewTrackingUtilities.setMapLinkedToLocation(false); mapViewTrackingUtilities.setMapLinkedToLocation(false);
if (mapLabelToShow != null && !mapLabelToShow.contextMenuDisabled()) { if (mapLabelToShow != null && !mapLabelToShow.contextMenuDisabled()) {
mapContextMenu.setMapCenter(latLonToShow); mapContextMenu.setMapCenter(latLonToShow);
mapContextMenu.setMapPosition(mapView.getMapPosition()); mapContextMenu.setMapPosition(mapView.getMapPosition());
@ -764,7 +766,8 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
tb.setPixelDimensions(tbw, tbh); tb.setPixelDimensions(tbw, tbh);
tb.setLatLonCenter(latLonToShow.getLatitude(), latLonToShow.getLongitude()); tb.setLatLonCenter(latLonToShow.getLatitude(), latLonToShow.getLongitude());
while (!tb.containsLatLon(prevCenter.getLatitude(), prevCenter.getLongitude()) && tb.getZoom() > 10) { tb.setZoom(ZOOM_LABEL_DISPLAY);
while (!tb.containsLatLon(prevCenter.getLatitude(), prevCenter.getLongitude()) && tb.getZoom() > MIN_ZOOM_LABEL_DISPLAY) {
tb.setZoom(tb.getZoom() - 1); tb.setZoom(tb.getZoom() - 1);
} }
//mapContextMenu.setMapZoom(settings.getMapZoomToShow()); //mapContextMenu.setMapZoom(settings.getMapZoomToShow());

View file

@ -12,14 +12,12 @@ import android.os.StatFs;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.UiThread; import android.support.annotation.UiThread;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback; import android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v4.widget.Space; import android.support.v4.widget.Space;
import android.support.v7.widget.AppCompatButton; import android.support.v7.widget.AppCompatButton;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
@ -35,6 +33,7 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import net.osmand.IProgress; import net.osmand.IProgress;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.access.AccessibilityAssistant; import net.osmand.access.AccessibilityAssistant;
@ -53,7 +52,6 @@ import net.osmand.plus.base.BasicProgressAsyncTask;
import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents; import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
import net.osmand.plus.download.ui.ActiveDownloadsDialogFragment; import net.osmand.plus.download.ui.ActiveDownloadsDialogFragment;
import net.osmand.plus.download.ui.DataStoragePlaceDialogFragment;
import net.osmand.plus.download.ui.DownloadResourceGroupFragment; import net.osmand.plus.download.ui.DownloadResourceGroupFragment;
import net.osmand.plus.download.ui.FreeVersionDialogFragment; import net.osmand.plus.download.ui.FreeVersionDialogFragment;
import net.osmand.plus.download.ui.LocalIndexesFragment; import net.osmand.plus.download.ui.LocalIndexesFragment;
@ -76,8 +74,6 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
public class DownloadActivity extends AbstractDownloadActivity implements DownloadEvents, public class DownloadActivity extends AbstractDownloadActivity implements DownloadEvents,
OnRequestPermissionsResultCallback, InAppListener { OnRequestPermissionsResultCallback, InAppListener {
@ -197,7 +193,6 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
filterCat = intent.getExtras().getString(FILTER_CAT); filterCat = intent.getExtras().getString(FILTER_CAT);
filterGroup = intent.getExtras().getString(FILTER_GROUP); filterGroup = intent.getExtras().getString(FILTER_GROUP);
} }
showFirstTimeExternalStorage();
} }
@Override @Override
@ -695,50 +690,11 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
} }
} }
private void showFirstTimeExternalStorage() {
final boolean firstTime = getMyApplication().getAppInitializer().isFirstTime();
if (firstTime && DataStoragePlaceDialogFragment.isInterestedInFirstTime) {
if (!hasPermissionToWriteExternalStorage(this)) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
} else {
chooseDataStorage();
}
}
}
private void chooseDataStorage() {
DataStoragePlaceDialogFragment.showInstance(getSupportFragmentManager(), false);
}
public static boolean hasPermissionToWriteExternalStorage(Context ctx) { public static boolean hasPermissionToWriteExternalStorage(Context ctx) {
return ContextCompat.checkSelfPermission(ctx, Manifest.permission.WRITE_EXTERNAL_STORAGE) return ContextCompat.checkSelfPermission(ctx, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED; == PackageManager.PERMISSION_GRANTED;
} }
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE
&& grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
new Timer().schedule(new TimerTask() {
@Override
public void run() {
chooseDataStorage();
}
}, 1);
} else {
Toast.makeText(this,
R.string.missing_write_external_storage_permission,
Toast.LENGTH_LONG).show();
}
return;
}
public String getFilterAndClear() { public String getFilterAndClear() {
String res = filter; String res = filter;
filter = null; filter = null;

View file

@ -14,6 +14,7 @@ import android.view.WindowManager;
import android.widget.ImageView; import android.widget.ImageView;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
public class FirstUsageWelcomeFragment extends Fragment { public class FirstUsageWelcomeFragment extends Fragment {
public static final String TAG = "FirstUsageWelcomeFragment"; public static final String TAG = "FirstUsageWelcomeFragment";
@ -33,26 +34,21 @@ public class FirstUsageWelcomeFragment extends Fragment {
skipButton.setOnClickListener(new View.OnClickListener() { skipButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getActivity().getWindow();
w.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
FirstUsageWizardFragment.startWizard(getActivity()); FirstUsageWizardFragment.startWizard(getActivity());
} }
}); });
return view; return view;
} }
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { ((MapActivity)getActivity()).disableDrawer();
Window w = getActivity().getWindow(); // in Activity's onCreate() for instance }
w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); @Override
} public void onPause() {
super.onPause();
((MapActivity)getActivity()).enableDrawer();
} }
} }

View file

@ -6,6 +6,7 @@ import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.StatFs; import android.os.StatFs;
import android.provider.Settings.Secure;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
@ -19,7 +20,6 @@ import android.view.ViewGroup;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import net.osmand.AndroidNetworkUtils; import net.osmand.AndroidNetworkUtils;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.ValueHolder; import net.osmand.ValueHolder;
@ -33,6 +33,7 @@ import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.download.DownloadActivity; import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadActivityType; import net.osmand.plus.download.DownloadActivityType;
@ -53,9 +54,11 @@ import java.io.IOException;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
@ -326,13 +329,20 @@ public class FirstUsageWizardFragment extends Fragment implements OsmAndLocation
switch (wizardType) { switch (wizardType) {
case SEARCH_LOCATION: case SEARCH_LOCATION:
if (searchLocationByIp) { if (searchLocationByIp) {
final Map<String, String> pms = new LinkedHashMap<>();
pms.put("version", Version.getFullVersion(app));
try {
pms.put("aid", Secure.getString(app.getContentResolver(), Secure.ANDROID_ID));
} catch (Exception e) {
e.printStackTrace();
}
new AsyncTask<Void, Void, String>() { new AsyncTask<Void, Void, String>() {
@Override @Override
protected String doInBackground(Void... params) { protected String doInBackground(Void... params) {
try { try {
return AndroidNetworkUtils.sendRequest(app, "http://osmand.net/api/geo-ip", null, return AndroidNetworkUtils.sendRequest(app, "http://osmand.net/api/geo-ip", pms,
"Requesting location by IP...", false); "Requesting location by IP...", false, false);
} catch (Exception e) { } catch (Exception e) {
logError("Requesting location by IP error: ", e); logError("Requesting location by IP error: ", e);
@ -424,6 +434,18 @@ public class FirstUsageWizardFragment extends Fragment implements OsmAndLocation
app.getAppInitializer().removeListener(this); app.getAppInitializer().removeListener(this);
} }
@Override
public void onResume() {
super.onResume();
((MapActivity)getActivity()).disableDrawer();
}
@Override
public void onPause() {
super.onPause();
((MapActivity)getActivity()).enableDrawer();
}
@Override @Override
public void updateLocation(final Location loc) { public void updateLocation(final Location loc) {
final OsmandApplication app = getMyApplication(); final OsmandApplication app = getMyApplication();

View file

@ -21,6 +21,7 @@ import android.annotation.SuppressLint;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.provider.Settings.Secure;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
@ -50,17 +51,21 @@ public class DiscountHelper {
} }
mLastCheckTime = System.currentTimeMillis(); mLastCheckTime = System.currentTimeMillis();
final Map<String, String> pms = new LinkedHashMap<>(); final Map<String, String> pms = new LinkedHashMap<>();
pms.put("name", Version.getAppName(app)); pms.put("version", Version.getFullVersion(app));
pms.put("version", Version.getAppVersion(app));
pms.put("nd", app.getAppInitializer().getFirstInstalledDays() +""); pms.put("nd", app.getAppInitializer().getFirstInstalledDays() +"");
pms.put("ns", app.getAppInitializer().getNumberOfStarts() + ""); pms.put("ns", app.getAppInitializer().getNumberOfStarts() + "");
try {
pms.put("aid", Secure.getString(app.getContentResolver(), Secure.ANDROID_ID));
} catch (Exception e) {
e.printStackTrace();
}
new AsyncTask<Void, Void, String>() { new AsyncTask<Void, Void, String>() {
@Override @Override
protected String doInBackground(Void... params) { protected String doInBackground(Void... params) {
try { try {
String res = AndroidNetworkUtils.sendRequest(mapActivity.getMyApplication(), String res = AndroidNetworkUtils.sendRequest(mapActivity.getMyApplication(),
URL, pms, "Requesting discount info...", false); URL, pms, "Requesting discount info...", false, false);
return res; return res;
} catch (Exception e) { } catch (Exception e) {
logError("Requesting discount info error: ", e); logError("Requesting discount info error: ", e);

View file

@ -328,7 +328,7 @@ public class GpxImportHelper {
} }
private void importFavourites(final GPXUtilities.GPXFile gpxFile, final String fileName, final boolean save) { private void importFavourites(final GPXUtilities.GPXFile gpxFile, final String fileName, final boolean save) {
if(gpxFile.points == null || gpxFile.points.size() == 0) { if(gpxFile == null || gpxFile.points == null || gpxFile.points.size() == 0) {
handleResult(gpxFile, fileName, save); handleResult(gpxFile, fileName, save);
return; return;
} }

View file

@ -11,7 +11,6 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import net.osmand.FloatMath;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;

View file

@ -300,7 +300,7 @@ public class InAppHelper {
return AndroidNetworkUtils.sendRequest(ctx, return AndroidNetworkUtils.sendRequest(ctx,
"http://download.osmand.net/subscription/register.php", "http://download.osmand.net/subscription/register.php",
parameters, "Requesting userId...", true); parameters, "Requesting userId...", true, true);
} catch (Exception e) { } catch (Exception e) {
logError("sendRequest Error", e); logError("sendRequest Error", e);
@ -443,7 +443,7 @@ public class InAppHelper {
AndroidNetworkUtils.sendRequestAsync(ctx, AndroidNetworkUtils.sendRequestAsync(ctx,
"http://download.osmand.net/subscription/purchased.php", "http://download.osmand.net/subscription/purchased.php",
parameters, "Sending purchase info...", true, new OnRequestResultListener() { parameters, "Sending purchase info...", true, true, new OnRequestResultListener() {
@Override @Override
public void onResult(String result) { public void onResult(String result) {
if (result != null) { if (result != null) {
@ -463,10 +463,10 @@ public class InAppHelper {
ctx.getSettings().BILLING_USER_COUNTRY_DOWNLOAD_NAME.set(prefferedCountry); ctx.getSettings().BILLING_USER_COUNTRY_DOWNLOAD_NAME.set(prefferedCountry);
CountrySelectionFragment countrySelectionFragment = new CountrySelectionFragment(); CountrySelectionFragment countrySelectionFragment = new CountrySelectionFragment();
countrySelectionFragment.initCountries(ctx); countrySelectionFragment.initCountries(ctx);
CountryItem countryItem; CountryItem countryItem = null;
if (Algorithms.isEmpty(prefferedCountry)) { if (Algorithms.isEmpty(prefferedCountry)) {
countryItem = countrySelectionFragment.getCountryItems().get(0); countryItem = countrySelectionFragment.getCountryItems().get(0);
} else { } else if (!prefferedCountry.equals(OsmandSettings.BILLING_USER_DONATION_NONE_PARAMETER)) {
countryItem = countrySelectionFragment.getCountryItem(prefferedCountry); countryItem = countrySelectionFragment.getCountryItem(prefferedCountry);
} }
if (countryItem != null) { if (countryItem != null) {

View file

@ -262,13 +262,13 @@ public class IabHelper {
} }
}; };
try {
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND"); Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending"); serviceIntent.setPackage("com.android.vending");
if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0).isEmpty()) { if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0).isEmpty()) {
// service available to handle that Intent // service available to handle that Intent
mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE); mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
} } else {
else {
// no service available to handle that Intent // no service available to handle that Intent
mServiceConn = null; mServiceConn = null;
if (listener != null) { if (listener != null) {
@ -277,6 +277,12 @@ public class IabHelper {
"Billing service unavailable on device.")); "Billing service unavailable on device."));
} }
} }
} catch (Exception e) {
if (listener != null) {
listener.onIabSetupFinished(new IabResult(IABHELPER_SUBSCRIPTIONS_NOT_AVAILABLE,
"InAppBillingService not available"));
}
}
} }
/** /**
@ -290,7 +296,13 @@ public class IabHelper {
mSetupDone = false; mSetupDone = false;
if (mServiceConn != null) { if (mServiceConn != null) {
logDebug("Unbinding from service."); logDebug("Unbinding from service.");
if (mContext != null) mContext.unbindService(mServiceConn); try {
if (mContext != null) {
mContext.unbindService(mServiceConn);
}
} catch (Exception e) {
logError("Unbinding failed.");
}
} }
mDisposed = true; mDisposed = true;
mContext = null; mContext = null;

View file

@ -10,6 +10,7 @@ import android.content.res.Resources;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.DrawableRes; import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
@ -117,7 +118,6 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppList
View bottomShadowView = inflater.inflate(R.layout.card_bottom_divider, listView, false); View bottomShadowView = inflater.inflate(R.layout.card_bottom_divider, listView, false);
listView.addFooterView(bottomShadowView); listView.addFooterView(bottomShadowView);
adapter = new LocalIndexesAdapter(this); adapter = new LocalIndexesAdapter(this);
listView.setAdapter(adapter);
listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override @Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
@ -151,8 +151,13 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppList
} }
}); });
} }
listView.setAdapter(adapter);
if(Build.VERSION.SDK_INT >= 11) {
loadLocalIndexesTask = new LoadLocalIndexTask(adapter, this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
loadLocalIndexesTask = new LoadLocalIndexTask(adapter, this).execute(); loadLocalIndexesTask = new LoadLocalIndexTask(adapter, this).execute();
}
return view; return view;
} }

View file

@ -105,10 +105,8 @@ public class OsmLiveActivity extends AbstractDownloadActivity implements Downloa
} }
public static class LiveUpdatesFragmentPagerAdapter extends FragmentPagerAdapter { public static class LiveUpdatesFragmentPagerAdapter extends FragmentPagerAdapter {
private final Fragment[] fragments = new Fragment[]{new LiveUpdatesFragment(), private final Fragment[] fragments = new Fragment[] { new LiveUpdatesFragment(), new ReportsFragment() };
new ReportsFragment()}; private static final int[] titleIds = new int[] { LiveUpdatesFragment.TITLE, ReportsFragment.TITLE };
private static final int[] titleIds = new int[]{LiveUpdatesFragment.TITLE,
ReportsFragment.TITLE};
private final String[] titles; private final String[] titles;
public LiveUpdatesFragmentPagerAdapter(FragmentManager fm, Resources res) { public LiveUpdatesFragmentPagerAdapter(FragmentManager fm, Resources res) {

View file

@ -4,12 +4,14 @@ import android.app.Activity;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v7.widget.AppCompatCheckBox;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
@ -41,10 +43,12 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
private static final String EMAIL_ID = "email_id"; private static final String EMAIL_ID = "email_id";
private static final String COUNTRY_ITEM_ID = "country_id"; private static final String COUNTRY_ITEM_ID = "country_id";
private static final String HIDE_USER_NAME_ID = "hide_user_name_id"; private static final String HIDE_USER_NAME_ID = "hide_user_name_id";
private static final String DONATION_ID = "donation_id";
private OsmandSettings settings; private OsmandSettings settings;
private ProgressDialog dlg; private ProgressDialog dlg;
private boolean editMode; private boolean editMode;
private boolean donation;
private String prevEmail; private String prevEmail;
private CountryItem selectedCountryItem; private CountryItem selectedCountryItem;
@ -76,6 +80,8 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
outState.putString(EMAIL_ID, emailEdit.getText().toString()); outState.putString(EMAIL_ID, emailEdit.getText().toString());
CheckBox hideUserNameCheckbox = (CheckBox) view.findViewById(R.id.hideUserNameCheckbox); CheckBox hideUserNameCheckbox = (CheckBox) view.findViewById(R.id.hideUserNameCheckbox);
outState.putBoolean(HIDE_USER_NAME_ID, hideUserNameCheckbox.isChecked()); outState.putBoolean(HIDE_USER_NAME_ID, hideUserNameCheckbox.isChecked());
CheckBox donationCheckbox = (CheckBox) view.findViewById(R.id.donationCheckbox);
outState.putBoolean(DONATION_ID, donationCheckbox.isChecked());
if (selectedCountryItem != null) { if (selectedCountryItem != null) {
outState.putSerializable(COUNTRY_ITEM_ID, selectedCountryItem); outState.putSerializable(COUNTRY_ITEM_ID, selectedCountryItem);
} }
@ -109,17 +115,20 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
String email = settings.BILLING_USER_EMAIL.get(); String email = settings.BILLING_USER_EMAIL.get();
String countryDownloadName = settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get(); String countryDownloadName = settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get();
boolean hideUserName = settings.BILLING_HIDE_USER_NAME.get(); boolean hideUserName = settings.BILLING_HIDE_USER_NAME.get();
donation = !countryDownloadName.equals(OsmandSettings.BILLING_USER_DONATION_NONE_PARAMETER);
if (savedInstanceState != null) { if (savedInstanceState != null) {
userName = savedInstanceState.getString(USER_NAME_ID); userName = savedInstanceState.getString(USER_NAME_ID);
email = savedInstanceState.getString(EMAIL_ID); email = savedInstanceState.getString(EMAIL_ID);
hideUserName = savedInstanceState.getBoolean(HIDE_USER_NAME_ID); hideUserName = savedInstanceState.getBoolean(HIDE_USER_NAME_ID);
donation = savedInstanceState.getBoolean(DONATION_ID);
Object obj = savedInstanceState.getSerializable(COUNTRY_ITEM_ID); Object obj = savedInstanceState.getSerializable(COUNTRY_ITEM_ID);
if (obj instanceof CountryItem) { if (obj instanceof CountryItem) {
selectedCountryItem = (CountryItem) obj; selectedCountryItem = (CountryItem) obj;
countryDownloadName = selectedCountryItem.getDownloadName(); countryDownloadName = selectedCountryItem.getDownloadName();
} else { } else {
countryDownloadName = ""; countryDownloadName =
donation ? OsmandSettings.BILLING_USER_DONATION_WORLD_PARAMETER : OsmandSettings.BILLING_USER_DONATION_NONE_PARAMETER;
} }
} }
@ -144,6 +153,20 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
title.setText(getString(R.string.osm_live_subscription)); title.setText(getString(R.string.osm_live_subscription));
} }
final View headerLayout = view.findViewById(R.id.headerLayout);
final View paramsLayout = view.findViewById(R.id.paramsLayout);
AppCompatCheckBox donationCheckbox = (AppCompatCheckBox) view.findViewById(R.id.donationCheckbox);
donationCheckbox.setChecked(donation);
donationCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
donation = isChecked;
paramsLayout.setVisibility(isChecked ? View.VISIBLE : View.GONE);
}
});
headerLayout.setVisibility(View.VISIBLE);
paramsLayout.setVisibility(donation ? View.VISIBLE : View.GONE);
final EditText userNameEdit = (EditText) view.findViewById(R.id.userNameEdit); final EditText userNameEdit = (EditText) view.findViewById(R.id.userNameEdit);
if (!Algorithms.isEmpty(userName)) { if (!Algorithms.isEmpty(userName)) {
userNameEdit.setText(userName); userNameEdit.setText(userName);
@ -155,7 +178,7 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
} }
countrySelectionFragment.initCountries(getMyApplication()); countrySelectionFragment.initCountries(getMyApplication());
if (Algorithms.isEmpty(countryDownloadName)) { if (Algorithms.isEmpty(countryDownloadName) || countryDownloadName.equals(OsmandSettings.BILLING_USER_DONATION_NONE_PARAMETER)) {
selectedCountryItem = countrySelectionFragment.getCountryItems().get(0); selectedCountryItem = countrySelectionFragment.getCountryItems().get(0);
} else { } else {
selectedCountryItem = countrySelectionFragment.getCountryItem(countryDownloadName); selectedCountryItem = countrySelectionFragment.getCountryItem(countryDownloadName);
@ -206,7 +229,7 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
AndroidNetworkUtils.sendRequestAsync(getMyApplication(), AndroidNetworkUtils.sendRequestAsync(getMyApplication(),
"http://download.osmand.net/subscription/update.php", "http://download.osmand.net/subscription/update.php",
parameters, "Sending data...", true, new AndroidNetworkUtils.OnRequestResultListener() { parameters, "Sending data...", true, true, new AndroidNetworkUtils.OnRequestResultListener() {
@Override @Override
public void onResult(String result) { public void onResult(String result) {
dismissProgress(); dismissProgress();
@ -297,9 +320,15 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
} }
private boolean applySettings(String userName, String email, boolean hideUserName) { private boolean applySettings(String userName, String email, boolean hideUserName) {
String countryName = selectedCountryItem != null ? selectedCountryItem.getLocalName() : ""; String countryName;
String countryDownloadName = selectedCountryItem != null ? selectedCountryItem.getDownloadName() : ""; String countryDownloadName;
if (!donation) {
countryName = "";
countryDownloadName = OsmandSettings.BILLING_USER_DONATION_NONE_PARAMETER;
} else {
countryName = selectedCountryItem != null ? selectedCountryItem.getLocalName() : "";
countryDownloadName = selectedCountryItem != null ?
selectedCountryItem.getDownloadName() : OsmandSettings.BILLING_USER_DONATION_WORLD_PARAMETER;
if (Algorithms.isEmpty(email) || !AndroidUtils.isValidEmail(email)) { if (Algorithms.isEmpty(email) || !AndroidUtils.isValidEmail(email)) {
getMyApplication().showToastMessage(getString(R.string.osm_live_enter_email)); getMyApplication().showToastMessage(getString(R.string.osm_live_enter_email));
return false; return false;
@ -308,6 +337,7 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
getMyApplication().showToastMessage(getString(R.string.osm_live_enter_user_name)); getMyApplication().showToastMessage(getString(R.string.osm_live_enter_user_name));
return false; return false;
} }
}
settings.BILLING_USER_NAME.set(userName); settings.BILLING_USER_NAME.set(userName);
settings.BILLING_USER_EMAIL.set(email); settings.BILLING_USER_EMAIL.set(email);

View file

@ -640,58 +640,7 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
} }
public void fabPressed() { public void fabPressed() {
hide(); mapActivity.getMapLayers().getMapControlsLayer().navigateFab();
final TargetPointsHelper targets = mapActivity.getMyApplication().getTargetPointsHelper();
RoutingHelper routingHelper = mapActivity.getMyApplication().getRoutingHelper();
if (routingHelper.isFollowingMode() || routingHelper.isRoutePlanningMode()) {
DirectionsDialogs.addWaypointDialogAndLaunchMap(mapActivity, latLon.getLatitude(),
latLon.getLongitude(), getPointDescriptionForTarget());
} else if (targets.getIntermediatePoints().isEmpty()) {
boolean hasPointToStart = settings.restorePointToStart();
targets.navigateToPoint(latLon, true, -1, getPointDescriptionForTarget());
if (!hasPointToStart) {
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true, true);
} else {
TargetPoint start = targets.getPointToStart();
if (start != null) {
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, start.point, start.getOriginalPointDescription(), true, true);
} else {
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true, true);
}
}
close();
} else {
Builder bld = new AlertDialog.Builder(mapActivity);
bld.setTitle(R.string.new_directions_point_dialog);
final int[] defaultVls = new int[]{0};
bld.setSingleChoiceItems(new String[]{
mapActivity.getString(R.string.clear_intermediate_points),
mapActivity.getString(R.string.keep_intermediate_points)
}, 0, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
defaultVls[0] = which;
}
});
bld.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (defaultVls[0] == 0) {
targets.removeAllWayPoints(false, true);
targets.navigateToPoint(latLon, true, -1, getPointDescriptionForTarget());
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true, true);
close();
} else {
targets.navigateToPoint(latLon, true, -1, getPointDescriptionForTarget());
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true, true);
close();
}
}
});
bld.setNegativeButton(R.string.shared_string_cancel, null);
bld.show();
}
} }
public void buttonWaypointPressed() { public void buttonWaypointPressed() {
@ -811,7 +760,7 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
return GpxUiHelper.selectSingleGPXFile(mapActivity, true, callbackWithObject); return GpxUiHelper.selectSingleGPXFile(mapActivity, true, callbackWithObject);
} }
private PointDescription getPointDescriptionForTarget() { public PointDescription getPointDescriptionForTarget() {
if (pointDescription.isLocation() if (pointDescription.isLocation()
&& pointDescription.getName().equals(PointDescription.getAddressNotFoundStr(mapActivity))) { && pointDescription.getName().equals(PointDescription.getAddressNotFoundStr(mapActivity))) {
return new PointDescription(PointDescription.POINT_TYPE_LOCATION, ""); return new PointDescription(PointDescription.POINT_TYPE_LOCATION, "");

View file

@ -73,7 +73,7 @@ public class NominatimPoiFilter extends PoiUIFilter {
@Override @Override
protected List<Amenity> searchAmenitiesInternal(double lat, double lon, double topLatitude, protected List<Amenity> searchAmenitiesInternal(double lat, double lon, double topLatitude,
double bottomLatitude, double leftLongitude, double rightLongitude, ResultMatcher<Amenity> matcher) { double bottomLatitude, double leftLongitude, double rightLongitude, int zoom, ResultMatcher<Amenity> matcher) {
final int deviceApiVersion = android.os.Build.VERSION.SDK_INT; final int deviceApiVersion = android.os.Build.VERSION.SDK_INT;
String NOMINATIM_API; String NOMINATIM_API;
if (deviceApiVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) { if (deviceApiVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) {

View file

@ -203,6 +203,12 @@ public class PoiUIFilter implements SearchPoiTypeFilter, Comparable<PoiUIFilter>
distanceInd = 0; distanceInd = 0;
} }
public void clearCurrentResults() {
if (currentSearchResult != null) {
currentSearchResult = new ArrayList<>();
}
}
public List<Amenity> initializeNewSearch(double lat, double lon, int firstTimeLimit, ResultMatcher<Amenity> matcher) { public List<Amenity> initializeNewSearch(double lat, double lon, int firstTimeLimit, ResultMatcher<Amenity> matcher) {
clearPreviousZoom(); clearPreviousZoom();
List<Amenity> amenityList = searchAmenities(lat, lon, matcher); List<Amenity> amenityList = searchAmenities(lat, lon, matcher);
@ -236,7 +242,7 @@ public class PoiUIFilter implements SearchPoiTypeFilter, Comparable<PoiUIFilter>
double bottomLatitude = Math.max(lat - (distance / baseDistY), -84.); double bottomLatitude = Math.max(lat - (distance / baseDistY), -84.);
double leftLongitude = Math.max(lon - (distance / baseDistX), -180); double leftLongitude = Math.max(lon - (distance / baseDistX), -180);
double rightLongitude = Math.min(lon + (distance / baseDistX), 180); double rightLongitude = Math.min(lon + (distance / baseDistX), 180);
return searchAmenitiesInternal(lat, lon, topLatitude, bottomLatitude, leftLongitude, rightLongitude, matcher); return searchAmenitiesInternal(lat, lon, topLatitude, bottomLatitude, leftLongitude, rightLongitude, -1, matcher);
} }
public List<Amenity> searchAmenities(double top, double left, double bottom, double right, int zoom, public List<Amenity> searchAmenities(double top, double left, double bottom, double right, int zoom,
@ -254,8 +260,8 @@ public class PoiUIFilter implements SearchPoiTypeFilter, Comparable<PoiUIFilter>
} }
} }
} }
List<Amenity> amenities = app.getResourceManager().searchAmenities(this, top, left, bottom, right, zoom, List<Amenity> amenities = searchAmenitiesInternal(top / 2 + bottom / 2, left / 2 + right / 2,
wrapResultMatcher(matcher)); top, bottom, left, right, zoom, matcher);
results.addAll(amenities); results.addAll(amenities);
return results; return results;
} }
@ -265,9 +271,9 @@ public class PoiUIFilter implements SearchPoiTypeFilter, Comparable<PoiUIFilter>
} }
protected List<Amenity> searchAmenitiesInternal(double lat, double lon, double topLatitude, protected List<Amenity> searchAmenitiesInternal(double lat, double lon, double topLatitude,
double bottomLatitude, double leftLongitude, double rightLongitude, final ResultMatcher<Amenity> matcher) { double bottomLatitude, double leftLongitude, double rightLongitude, int zoom, final ResultMatcher<Amenity> matcher) {
return app.getResourceManager().searchAmenities(this, return app.getResourceManager().searchAmenities(this,
topLatitude, leftLongitude, bottomLatitude, rightLongitude, -1, wrapResultMatcher(matcher)); topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, wrapResultMatcher(matcher));
} }
public AmenityNameFilter getNameFilter(String filter) { public AmenityNameFilter getNameFilter(String filter) {

View file

@ -32,7 +32,7 @@ public class SearchByNameFilter extends PoiUIFilter {
@Override @Override
protected List<Amenity> searchAmenitiesInternal(double lat, double lon, double topLatitude, protected List<Amenity> searchAmenitiesInternal(double lat, double lon, double topLatitude,
double bottomLatitude, double leftLongitude, double rightLongitude, final ResultMatcher<Amenity> matcher) { double bottomLatitude, double leftLongitude, double rightLongitude, int zoom, final ResultMatcher<Amenity> matcher) {
currentSearchResult = new ArrayList<Amenity>(); currentSearchResult = new ArrayList<Amenity>();
final int limit = distanceInd == 0 ? 500 : -1; final int limit = distanceInd == 0 ? 500 : -1;
List<Amenity> result = Collections.emptyList(); List<Amenity> result = Collections.emptyList();

View file

@ -219,9 +219,10 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
} else if (searchPhrase.isNoSelectedType() || searchPhrase.isLastWord(ObjectType.POI_TYPE)) { } else if (searchPhrase.isNoSelectedType() || searchPhrase.isLastWord(ObjectType.POI_TYPE)) {
PoiUIFilter filter; PoiUIFilter filter;
if (searchPhrase.isNoSelectedType()) { if (searchPhrase.isNoSelectedType()) {
filter = new PoiUIFilter(null, app, ""); filter = app.getPoiFilters().getSearchByNamePOIFilter();
if (!Algorithms.isEmpty(searchPhrase.getUnknownSearchWord())) { if (!Algorithms.isEmpty(searchPhrase.getUnknownSearchWord())) {
filter.setFilterByName(searchPhrase.getUnknownSearchWord()); filter.setFilterByName(searchPhrase.getUnknownSearchWord());
filter.clearCurrentResults();
} }
} else if (searchPhrase.getLastSelectedWord().getResult().object instanceof AbstractPoiType) { } else if (searchPhrase.getLastSelectedWord().getResult().object instanceof AbstractPoiType) {
if (searchPhrase.isNoSelectedType()) { if (searchPhrase.isNoSelectedType()) {

View file

@ -26,6 +26,7 @@ import android.widget.TextView;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.core.android.MapRendererContext; import net.osmand.core.android.MapRendererContext;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.data.RotatedTileBox; import net.osmand.data.RotatedTileBox;
import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmAndLocationProvider;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
@ -40,6 +41,8 @@ import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.MapActivity.ShowQuickSearchMode; import net.osmand.plus.activities.MapActivity.ShowQuickSearchMode;
import net.osmand.plus.activities.search.SearchAddressFragment; import net.osmand.plus.activities.search.SearchAddressFragment;
import net.osmand.plus.dashboard.DashboardOnMap.DashboardType; import net.osmand.plus.dashboard.DashboardOnMap.DashboardType;
import net.osmand.plus.dialogs.DirectionsDialogs;
import net.osmand.plus.mapcontextmenu.MapContextMenu;
import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenu; import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenu;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.views.corenative.NativeCoreContext; import net.osmand.plus.views.corenative.NativeCoreContext;
@ -54,6 +57,7 @@ public class MapControlsLayer extends OsmandMapLayer {
private static final int TIMEOUT_TO_SHOW_BUTTONS = 7000; private static final int TIMEOUT_TO_SHOW_BUTTONS = 7000;
public static final int REQUEST_ADDRESS_SELECT = 2; public static final int REQUEST_ADDRESS_SELECT = 2;
private static final int REQUEST_LOCATION_FOR_NAVIGATION_PERMISSION = 200; private static final int REQUEST_LOCATION_FOR_NAVIGATION_PERMISSION = 200;
private static final int REQUEST_LOCATION_FOR_NAVIGATION_FAB_PERMISSION = 201;
public MapHudButton createHudButton(View iv, int resId) { public MapHudButton createHudButton(View iv, int resId) {
MapHudButton mc = new MapHudButton(); MapHudButton mc = new MapHudButton();
@ -413,6 +417,69 @@ public class MapControlsLayer extends OsmandMapLayer {
hasTargets = false; hasTargets = false;
} }
public void navigateFab() {
if (!OsmAndLocationProvider.isLocationPermissionAvailable(mapActivity)) {
ActivityCompat.requestPermissions(mapActivity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION_FOR_NAVIGATION_FAB_PERMISSION);
} else {
final MapContextMenu menu = mapActivity.getContextMenu();
final LatLon latLon = menu.getLatLon();
final PointDescription pointDescription = menu.getPointDescriptionForTarget();
menu.hide();
final TargetPointsHelper targets = mapActivity.getMyApplication().getTargetPointsHelper();
RoutingHelper routingHelper = mapActivity.getMyApplication().getRoutingHelper();
if (routingHelper.isFollowingMode() || routingHelper.isRoutePlanningMode()) {
DirectionsDialogs.addWaypointDialogAndLaunchMap(mapActivity, latLon.getLatitude(),
latLon.getLongitude(), pointDescription);
} else if (targets.getIntermediatePoints().isEmpty()) {
boolean hasPointToStart = settings.restorePointToStart();
targets.navigateToPoint(latLon, true, -1, pointDescription);
if (!hasPointToStart) {
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true, true);
} else {
TargetPoint start = targets.getPointToStart();
if (start != null) {
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, start.point, start.getOriginalPointDescription(), true, true);
} else {
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true, true);
}
}
menu.close();
} else {
AlertDialog.Builder bld = new AlertDialog.Builder(mapActivity);
bld.setTitle(R.string.new_directions_point_dialog);
final int[] defaultVls = new int[]{0};
bld.setSingleChoiceItems(new String[]{
mapActivity.getString(R.string.clear_intermediate_points),
mapActivity.getString(R.string.keep_intermediate_points)
}, 0, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
defaultVls[0] = which;
}
});
bld.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (defaultVls[0] == 0) {
targets.removeAllWayPoints(false, true);
targets.navigateToPoint(latLon, true, -1, pointDescription);
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true, true);
menu.close();
} else {
targets.navigateToPoint(latLon, true, -1, pointDescription);
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true, true);
menu.close();
}
}
});
bld.setNegativeButton(R.string.shared_string_cancel, null);
bld.show();
}
}
}
public void switchToRouteFollowingLayout() { public void switchToRouteFollowingLayout() {
touchEvent = 0; touchEvent = 0;
@ -928,6 +995,9 @@ public class MapControlsLayer extends OsmandMapLayer {
if (requestCode == REQUEST_LOCATION_FOR_NAVIGATION_PERMISSION if (requestCode == REQUEST_LOCATION_FOR_NAVIGATION_PERMISSION
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
onNavigationClick(); onNavigationClick();
} else if (requestCode == REQUEST_LOCATION_FOR_NAVIGATION_FAB_PERMISSION
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
navigateFab();
} }
} }
} }

View file

@ -80,7 +80,6 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
private Bitmap poiBackgroundSmall; private Bitmap poiBackgroundSmall;
private OsmandMapTileView view; private OsmandMapTileView view;
private final static int MAXIMUM_SHOW_AMENITIES = 5;
private RoutingHelper routingHelper; private RoutingHelper routingHelper;
private Set<PoiUIFilter> filters = new TreeSet<>(); private Set<PoiUIFilter> filters = new TreeSet<>();

View file

@ -25,170 +25,10 @@ public class TurnPathHelper {
public static final int FIRST_TURN = 1; public static final int FIRST_TURN = 1;
public static final int SECOND_TURN = 2; public static final int SECOND_TURN = 2;
public static final int THIRD_TURN = 3; public static final int THIRD_TURN = 3;
private static final boolean USE_NEW_RNDB = true;
private static final boolean SHOW_STEPS = true; private static final boolean SHOW_STEPS = true;
// 72x72 private static class TurnVariables {
public static void calcTurnPath(Path pathForTurn, Path outlay, TurnType turnType,
Matrix transform, PointF center, boolean mini) {
if(turnType == null){
return;
}
pathForTurn.reset();
if(outlay != null) {
outlay.reset();
}
int ha = 72;
int wa = 72;
int th = 12; // thickness
pathForTurn.moveTo(wa / 2, ha - 1);
float sarrowL = 22; // side of arrow ?
float harrowL = (float) Math.sqrt(2) * sarrowL; // hypotenuse of arrow
float spartArrowL = (float) ((sarrowL - th / Math.sqrt(2)) / 2);
float hpartArrowL = (float) (harrowL - th) / 2;
if (TurnType.C == turnType.getValue()) {
int h = (int) (ha - hpartArrowL - 16);
pathForTurn.rMoveTo(th, 0);
pathForTurn.rLineTo(0, -h);
pathForTurn.rLineTo(hpartArrowL, 0);
pathForTurn.rLineTo(-harrowL / 2, -harrowL / 2); // center
pathForTurn.rLineTo(-harrowL / 2, harrowL / 2);
pathForTurn.rLineTo(hpartArrowL, 0);
pathForTurn.rLineTo(0, h);
} else if (TurnType.TR == turnType.getValue()|| TurnType.TL == turnType.getValue()) {
int b = TurnType.TR == turnType.getValue()? 1 : -1;
float quadShiftX = 18;
float quadShiftY = 18;
int wl = 10; // width
int h = (int) (ha - quadShiftY - harrowL + hpartArrowL - 5);
int sl = wl + th / 2;
pathForTurn.rMoveTo(-b * sl, 0);
pathForTurn.rLineTo(0, -h);
pathForTurn.rQuadTo(0, -quadShiftY, b * quadShiftX, -quadShiftY);
pathForTurn.rLineTo(b * wl, 0);
pathForTurn.rLineTo(0, hpartArrowL);
pathForTurn.rLineTo(b * harrowL / 2, -harrowL / 2); // center
pathForTurn.rLineTo(-b * harrowL / 2, -harrowL / 2);
pathForTurn.rLineTo(0, hpartArrowL);
pathForTurn.rLineTo(-b * wl, 0);
pathForTurn.rQuadTo(-b * (quadShiftX + th), 0, -b * (quadShiftX + th), quadShiftY + th);
pathForTurn.rLineTo(0, h);
} else if (TurnType.KL == turnType.getValue() || TurnType.KR == turnType.getValue()) {
int b = TurnType.KR == turnType.getValue()? 1 : -1;
float quadShiftX = 14;
float quadShiftY = 14;
th = 10;
spartArrowL = (float) ((sarrowL - th / Math.sqrt(2)) / 2);
hpartArrowL = (float) (harrowL - th) / 2;
int h = 12;
int lh = 15;
int sl = th / 2;
pathForTurn.rMoveTo(-b * (sl + 10), 0);
pathForTurn.rLineTo(0, -lh);
// 1st arc
pathForTurn.rQuadTo(0, -quadShiftY, b * quadShiftX, -quadShiftY);
// 2nd arc
pathForTurn.rQuadTo(b * quadShiftX, 0, b * quadShiftX, -quadShiftY);
// center
pathForTurn.rLineTo(0, -h);
pathForTurn.rLineTo(b*hpartArrowL, 0);
pathForTurn.rLineTo(-b*harrowL / 2, -harrowL / 2); // center
pathForTurn.rLineTo(-b*harrowL / 2, harrowL / 2);
pathForTurn.rLineTo(b*hpartArrowL, 0);
pathForTurn.rLineTo(0, h );
// 2nd arc
pathForTurn.rQuadTo(0, quadShiftY - th, -b * (quadShiftX - th), quadShiftY- th);
//1st arc
pathForTurn.rQuadTo(-b * (quadShiftX + th), 0, -b * (quadShiftX + th ), quadShiftY + th);
pathForTurn.rLineTo(0, lh );
} else if (TurnType.TSLR == turnType.getValue() || TurnType.TSLL == turnType.getValue()) {
int b = TurnType.TSLR == turnType.getValue() ? 1 : -1;
int h = 24;
int quadShiftY = 22;
float quadShiftX = (float) (quadShiftY / (1 + Math.sqrt(2)));
float nQuadShiftX = (sarrowL - 2 * spartArrowL) - quadShiftX - th;
float nQuadShifty = quadShiftY + (sarrowL - 2 * spartArrowL);
pathForTurn.rMoveTo(-b * 4, 0);
pathForTurn.rLineTo(0, -h /* + partArrowL */);
pathForTurn.rQuadTo(0, -quadShiftY + quadShiftX /*- partArrowL*/, b * quadShiftX, -quadShiftY /*- partArrowL*/);
pathForTurn.rLineTo(b * spartArrowL, spartArrowL);
pathForTurn.rLineTo(0, -sarrowL); // center
pathForTurn.rLineTo(-b * sarrowL, 0);
pathForTurn.rLineTo(b * spartArrowL, spartArrowL);
pathForTurn.rQuadTo(b * nQuadShiftX, -nQuadShiftX, b * nQuadShiftX, nQuadShifty);
pathForTurn.rLineTo(0, h);
} else if (TurnType.TSHR == turnType.getValue() || TurnType.TSHL == turnType.getValue()) {
int b = TurnType.TSHR == turnType.getValue() ? 1 : -1;
int h = 28;
float quadShiftX = 22;
int sh = 10;
float quadShiftY = -(float) (quadShiftX / (1 + Math.sqrt(2)));
float nQuadShiftX = -(sarrowL - 2 * spartArrowL) - quadShiftX - th;
float nQuadShiftY = -quadShiftY + (sarrowL - 2 * spartArrowL);
pathForTurn.rMoveTo(-b * sh, 0);
pathForTurn.rLineTo(0, -h);
pathForTurn.rQuadTo(0, -(quadShiftX - quadShiftY), b * quadShiftX, quadShiftY);
pathForTurn.rLineTo(-b * spartArrowL, spartArrowL);
pathForTurn.rLineTo(b * sarrowL, 0); // center
pathForTurn.rLineTo(0, -sarrowL);
pathForTurn.rLineTo(-b * spartArrowL, spartArrowL);
pathForTurn.rCubicTo(b * nQuadShiftX / 2, nQuadShiftX / 2, b * nQuadShiftX, nQuadShiftX / 2, b * nQuadShiftX, nQuadShiftY);
pathForTurn.rLineTo(0, h);
} else if(TurnType.TU == turnType.getValue() || TurnType.TRU == turnType.getValue()) {
int h = 40;
// right left
int b = TurnType.TU == turnType.getValue() ? 1 : -1;
float quadShiftX = 10; // 13
float quadShiftY = 10; // 13
int sm = 10;
pathForTurn.rMoveTo(b * 28, 0);
pathForTurn.rLineTo(0, -h);
pathForTurn.rQuadTo(0, -(quadShiftY+th), -b * (quadShiftX+th), -(quadShiftY+th));
pathForTurn.rQuadTo(-b * (quadShiftX+th), 0, -b * (quadShiftX+th), (quadShiftY+th));
pathForTurn.rLineTo(0, sm);
pathForTurn.rLineTo(-b * hpartArrowL, 0);
pathForTurn.rLineTo(b * harrowL/2, harrowL/2); // center
pathForTurn.rLineTo(b * harrowL/2, -harrowL/2);
pathForTurn.rLineTo(-b *hpartArrowL, 0);
pathForTurn.rLineTo(0, -sm);
pathForTurn.rQuadTo(0, -quadShiftX, b *quadShiftX, -quadShiftY);
pathForTurn.rQuadTo(b * quadShiftX, 0, b * quadShiftX, quadShiftY);
pathForTurn.rLineTo(0, h);
} else if (TurnType.OFFR == turnType.getValue()){
int h = (int) (ha - hpartArrowL - 16);
pathForTurn.rMoveTo(th, 0); //12 0
//first square
pathForTurn.rLineTo(0, -h / 4); //0 -7
pathForTurn.rLineTo(-th, 0); //-12 0
pathForTurn.rLineTo(0, h / 4); //0 7
pathForTurn.rLineTo(th, 0); //12 0
pathForTurn.rMoveTo(0, -h / 2); //12 0
//second square
pathForTurn.rLineTo(0, -h / 4); //0 -7
pathForTurn.rLineTo(-th, 0); //-12 0
pathForTurn.rLineTo(0, h / 4); //0 7
pathForTurn.rLineTo(th, 0); //12 0
pathForTurn.rMoveTo(0, -h / 2 + 1); //31 0
//arrow
pathForTurn.rLineTo(hpartArrowL, 0); //9 0
pathForTurn.rLineTo(-harrowL / 2, -harrowL / 2); // center -15 -15
pathForTurn.rLineTo(-harrowL / 2, harrowL / 2); // -15 15
pathForTurn.rLineTo(hpartArrowL + th, 0); //9 0
} else if(turnType != null && turnType.isRoundAbout() && USE_NEW_RNDB) {
int out = turnType.getExitOut();
boolean leftSide = turnType.isLeftSide();
float radEndOfArrow = 44; float radEndOfArrow = 44;
float radInnerCircle = 10; float radInnerCircle = 10;
float radOuterCircle = radInnerCircle + 8; float radOuterCircle = radInnerCircle + 8;
@ -196,27 +36,43 @@ public class TurnPathHelper {
float radBottom = radOuterCircle + 10; float radBottom = radOuterCircle + 10;
float radStepInter = radOuterCircle + 6; float radStepInter = radOuterCircle + 6;
float radArrowTriangle1 = radOuterCircle + 7; float radArrowTriangle1 = radOuterCircle + 7;
float radArrowTriangle2 = radOuterCircle + 8;
float widthStepIn = 8; float widthStepIn = 8;
float widthStepInter = 6; float widthStepInter = 6;
float widthArrow = 22; float widthArrow = 22;
float radArrowTriangle2;
private double dfL;
private double dfAr2;
private double dfStepInter;
private double dfAr;
private double dfOut;
private double dfStepOut;
private double dfIn;
private double minDelta;
private double rot;
private float cx;
private float cy;
private float scaleTriangle;
private TurnVariables(boolean leftSide, float turnAngle, int out, int wa, int ha, float scaleTriangle) {
this.scaleTriangle = scaleTriangle;
widthArrow = widthArrow * scaleTriangle;
radArrowTriangle2 = radArrowTriangle1 + 1 * scaleTriangle * scaleTriangle;
dfL = (leftSide ? 1 : -1) * Math.asin(widthStepIn / (2.0 * radBottom));
dfAr2 = (leftSide ? 1 : -1) * Math.asin(widthArrow / (2.0 * radArrowTriangle2));
dfStepInter = (leftSide ? 1 : -1) * Math.asin(widthStepInter / radStepInter);
dfAr = Math.asin(radBottom * Math.sin(dfL) / radArrowTriangle1);
dfOut = Math.asin(radBottom * Math.sin(dfL) / radOuterCircle);
dfStepOut = Math.asin(radStepInter * Math.sin(dfStepInter) / radOuterCircle);
dfIn = Math.asin(radBottom * Math.sin(dfL) / radInnerCircle);
minDelta = Math.abs(dfIn * 2 / Math.PI * 180) + 2;
double dfL = (leftSide ? 1 : -1) * Math.asin(widthStepIn / (2.0 * radBottom));
double dfAr2 = (leftSide ? 1 : -1) * Math.asin(widthArrow / (2.0 * radArrowTriangle2));
double dfStepInter = (leftSide ? 1 : -1) * Math.asin(widthStepInter / radStepInter);
double dfAr = Math.asin(radBottom * Math.sin(dfL) / radArrowTriangle1);
double dfOut = Math.asin(radBottom * Math.sin(dfL) / radOuterCircle);
double dfStepOut = Math.asin(radStepInter * Math.sin(dfStepInter) / radOuterCircle);
double dfIn = Math.asin(radBottom * Math.sin(dfL) / radInnerCircle);
double minDelta = Math.abs(dfIn * 2 / Math.PI * 180 ) + 2;
boolean showSteps = SHOW_STEPS && !mini;
// System.out.println("Angle " + dfL + " " + dfOut + " " + dfIn + " " + minDelta + " "); // System.out.println("Angle " + dfL + " " + dfOut + " " + dfIn + " " + minDelta + " ");
double rot = alignRotation(turnType.getTurnAngle(), leftSide, minDelta, out) / 180 * Math.PI; rot = alignRotation(turnAngle, leftSide, minDelta, out) / 180 * Math.PI;
float cx = wa / 2 ; cx = wa / 2;
float cy = ha / 2 ; cy = ha / 2;
// align center // align center
float potentialArrowEndX = (float) (Math.sin(rot) * radEndOfArrow); float potentialArrowEndX = (float) (Math.sin(rot) * radEndOfArrow);
float potentialArrowEndY = (float) (Math.cos(rot) * radEndOfArrow); float potentialArrowEndY = (float) (Math.cos(rot) * radEndOfArrow);
@ -230,13 +86,219 @@ public class TurnPathHelper {
} else if (potentialArrowEndY < -cy) { } else if (potentialArrowEndY < -cy) {
cy = -potentialArrowEndY; cy = -potentialArrowEndY;
} }
if(center != null) {
center.set(cx, cy);
} }
private float getProjX(double angle, double radius) {
return getX(angle, radius) + cx;
}
RectF qrOut = new RectF(cx - radOuterCircle, cy - radOuterCircle, cx + radOuterCircle, cy + radOuterCircle); private float getProjY(double angle, double radius) {
RectF qrIn = new RectF(cx - radInnerCircle, cy - radInnerCircle, cx + radInnerCircle, cy + radInnerCircle); return getY(angle, radius) + cy;
}
public float getTriangle2X() {
return getProjX(rot + dfAr, radArrowTriangle1);
}
public float getTriangle1X() {
return getProjX(rot - dfAr, radArrowTriangle1);
}
public float getTriangle2Y() {
return getProjY(rot + dfAr, radArrowTriangle1);
}
public float getTriangle1Y() {
return getProjY(rot - dfAr, radArrowTriangle1);
}
public void drawTriangle(Path pathForTurn) {
// up from arc
arcLineTo(pathForTurn, rot - dfAr, cx, cy, radArrowTriangle1);
// left triangle
// arcLineTo(pathForTurn, rot - dfAr2, cx, cy, radAr2); // 1.
// arcQuadTo(pathForTurn, rot - dfAr2, radAr2, rot, radArrow, 0.9f, cx, cy); // 2.
arcQuadTo(pathForTurn, rot - dfAr, radArrowTriangle1, rot - dfAr2, radArrowTriangle2, rot, radEndOfArrow,
4.5f * scaleTriangle, cx, cy); // 3.
// arcLineTo(pathForTurn, rot, cx, cy, radArrow); // 1.
arcQuadTo(pathForTurn, rot - dfAr2, radArrowTriangle2, rot, radEndOfArrow, rot + dfAr2, radArrowTriangle2,
4.5f, cx, cy);
// right triangle
// arcLineTo(pathForTurn, rot + dfAr2, cx, cy, radAr2); // 1.
arcQuadTo(pathForTurn, rot, radEndOfArrow, rot + dfAr2, radArrowTriangle2, rot + dfAr, radArrowTriangle1,
4.5f * scaleTriangle, cx, cy);
arcLineTo(pathForTurn, rot + dfAr, cx, cy, radArrowTriangle1);
}
}
// 72x72
public static void calcTurnPath(Path pathForTurn, Path outlay, TurnType turnType,
Matrix transform, PointF center, boolean mini) {
if(turnType == null){
return;
}
pathForTurn.reset();
if(outlay != null) {
outlay.reset();
}
int ha = 72;
int wa = 72;
int lowMargin = 6;
if (TurnType.C == turnType.getValue()) {
TurnVariables tv = new TurnVariables(false, 0, 0, wa, ha, 1.5f);
pathForTurn.moveTo(wa / 2 + tv.widthStepIn / 2, ha - lowMargin);
tv.drawTriangle(pathForTurn);
pathForTurn.lineTo(wa / 2 - tv.widthStepIn / 2, ha - lowMargin);
} else if (TurnType.OFFR == turnType.getValue()){
TurnVariables tv = new TurnVariables(false, 0, 0, wa, ha, 1.5f);
float rightX = wa / 2 + tv.widthStepIn / 2;
float leftX = wa / 2 - tv.widthStepIn / 2;
int step = 7;
pathForTurn.moveTo(rightX, ha - lowMargin);
pathForTurn.rLineTo(0, -step);
pathForTurn.rLineTo(-tv.widthStepIn , 0);
pathForTurn.rLineTo(0 , step);
pathForTurn.rLineTo(tv.widthStepIn, 0);
pathForTurn.moveTo(rightX, ha - 2 * lowMargin - step);
pathForTurn.rLineTo(0, -step);
pathForTurn.rLineTo(-tv.widthStepIn , 0);
pathForTurn.rLineTo(0 , step);
pathForTurn.rLineTo(tv.widthStepIn, 0);
pathForTurn.moveTo(rightX, ha - 3 * lowMargin - 2 * step);
pathForTurn.rLineTo(0, -step);
pathForTurn.rLineTo(-tv.widthStepIn , 0);
pathForTurn.rLineTo(0 , step);
pathForTurn.rLineTo(tv.widthStepIn, 0);
pathForTurn.moveTo(rightX, ha - 4 * lowMargin - 3 * step);
tv.drawTriangle(pathForTurn);
pathForTurn.lineTo(leftX, ha - 4 * lowMargin - 3 * step);
} else if (TurnType.TR == turnType.getValue()|| TurnType.TL == turnType.getValue()) {
int b = TurnType.TR == turnType.getValue()? 1 : -1;
TurnVariables tv = new TurnVariables(b != 1, b == 1 ? 90 : -90, 0, wa, ha / 2, 1.5f);
float centerCurveX = wa / 2 + b * 4;
float centerCurveY = ha / 2;
// calculated
float h = centerCurveY - lowMargin;
float r = tv.cy - tv.widthStepIn / 2;
float centerLineX = centerCurveX - b * (r + tv.widthStepIn / 2);
RectF innerOval = new RectF(centerCurveX - r, centerCurveY - r, centerCurveX + r, centerCurveY + r);
RectF outerOval = new RectF(innerOval);
outerOval.inset(-tv.widthStepIn, -tv.widthStepIn);
pathForTurn.moveTo(centerLineX + b * tv.widthStepIn / 2, ha - lowMargin);
pathForTurn.rLineTo(0, -h);
pathForTurn.arcTo(innerOval, b == 1 ? -180 : 0, b* 90);
tv.drawTriangle(pathForTurn);
pathForTurn.arcTo(outerOval, -90, - b *90);
pathForTurn.rLineTo(0, h);
} else if (TurnType.TSLR == turnType.getValue() || TurnType.TSLL == turnType.getValue()) {
int b = TurnType.TSLR == turnType.getValue() ? 1 : -1;
TurnVariables tv = new TurnVariables(b != 1, b == 1 ? 45 : -45, 0, wa, ha, 1.5f);
tv.cx -= b * 7;
float centerBottomX = wa / 2 - b * 6;
float centerCurveY = ha / 2 + 8;
float centerCurveX = centerBottomX + b * (wa / 2);
// calculated
float rx1 = Math.abs(centerCurveX - centerBottomX) - tv.widthStepIn / 2;
float rx2 = Math.abs(centerCurveX - centerBottomX) + tv.widthStepIn / 2;
double t1 = Math.acos(Math.abs(tv.getTriangle1X() - centerCurveX) / rx1) ;
float rb1 = (float) (Math.abs(tv.getTriangle1Y() - centerCurveY) / Math.sin(t1));
float ellipseAngle1 = (float) (t1 / Math.PI * 180);
double t2 = Math.acos(Math.abs(tv.getTriangle2X() - centerCurveX) / rx2) ;
float rb2 = (float) (Math.abs(tv.getTriangle2Y() - centerCurveY) / Math.sin(t2));
float ellipseAngle2 = (float) (t2 / Math.PI * 180);
RectF innerOval = new RectF(centerCurveX - rx1, centerCurveY - rb1, centerCurveX + rx1, centerCurveY + rb1);
RectF outerOval = new RectF(centerCurveX - rx2, centerCurveY - rb2, centerCurveX + rx2, centerCurveY + rb2);
pathForTurn.moveTo(centerBottomX + b * tv.widthStepIn / 2, ha - lowMargin);
pathForTurn.arcTo(innerOval, -90 - b * 90, b * (ellipseAngle1));
tv.drawTriangle(pathForTurn);
pathForTurn.arcTo(outerOval, -90 - b * (90 - (ellipseAngle2)), -b * (ellipseAngle2));
pathForTurn.lineTo(centerBottomX - b * tv.widthStepIn / 2, ha - lowMargin);
} else if (TurnType.TSHR == turnType.getValue() || TurnType.TSHL == turnType.getValue()) {
int b = TurnType.TSHR == turnType.getValue() ? 1 : -1;
float centerCircleY = ha / 4;
float centerCircleX = wa / 2 - b * (wa / 5);
TurnVariables tv = new TurnVariables(b != 1, b == 1 ? 135 : -135, 0, wa, ha, 1.5f);
// calculated
float angle = 45;
float r = tv.widthStepIn / 2;
tv.cx = centerCircleX;
tv.cy = centerCircleY;
RectF innerOval = new RectF(centerCircleX - r, centerCircleY - r, centerCircleX + r, centerCircleY + r);
pathForTurn.moveTo(centerCircleX + b * tv.widthStepIn / 2, ha - lowMargin);
pathForTurn.lineTo(centerCircleX + b * tv.widthStepIn / 2, (float) (centerCircleY +
2 * r));
// pathForTurn.arcTo(innerOval, -90 - b * 90, b * 45);
tv.drawTriangle(pathForTurn);
// pathForTurn.lineTo(centerCircleX - b * tv.widthStepIn / 2, (float) (centerCircleY - 2 *r));
pathForTurn.arcTo(innerOval, -90 + b * angle, - b * (90 + angle));
pathForTurn.lineTo(centerCircleX - b * tv.widthStepIn / 2, ha - lowMargin);
} else if(TurnType.TU == turnType.getValue() || TurnType.TRU == turnType.getValue()) {
int b = TurnType.TU == turnType.getValue() ? -1 : 1;
float radius = 16;
float centerRadiusY = ha / 2 - 10;
float extraMarginBottom = 5;
TurnVariables tv = new TurnVariables(b != 1, 180, 0, wa, ha, 1.5f);
// calculated
float centerRadiusX = wa / 2;
tv.cx = centerRadiusX + b * radius;
tv.cy = centerRadiusY - extraMarginBottom;
lowMargin += extraMarginBottom;
tv.rot = 0;
float r = radius - tv.widthStepIn / 2;
float r2 = radius + tv.widthStepIn / 2;
RectF innerOval = new RectF(centerRadiusX - r, centerRadiusY - r, centerRadiusX + r, centerRadiusY + r);
RectF outerOval = new RectF(centerRadiusX - r2, centerRadiusY - r2, centerRadiusX + r2, centerRadiusY + r2);
pathForTurn.moveTo(centerRadiusX - b * (radius - tv.widthStepIn / 2), ha - lowMargin);
pathForTurn.lineTo(centerRadiusX - b * (radius - tv.widthStepIn / 2), centerRadiusY);
pathForTurn.arcTo(innerOval, -90 - b * 90, b * 180);
tv.drawTriangle(pathForTurn);
pathForTurn.arcTo(outerOval, -90 + b * 90, -b * 180);
pathForTurn.lineTo(centerRadiusX - b * (radius + tv.widthStepIn / 2), ha - lowMargin);
} else if (TurnType.KL == turnType.getValue() || TurnType.KR == turnType.getValue()) {
int b = TurnType.KR == turnType.getValue()? 1 : -1;
float shiftX = 8;
float firstH = 18;
float secondH = 20;
TurnVariables tv = new TurnVariables(false, 0, 0, wa, ha, 1.5f);
// calculated
tv.cx += b * shiftX;
pathForTurn.moveTo(wa / 2 + tv.widthStepIn / 2 - b * shiftX, ha - lowMargin);
pathForTurn.lineTo(wa / 2 + tv.widthStepIn / 2 - b * shiftX, ha - lowMargin - firstH);
// pathForTurn.lineTo(wa / 2 + tv.widthStepIn / 2 + b * shiftX, ha - lowMargin - firstH - secondH);
pathForTurn.cubicTo(
wa / 2 + tv.widthStepIn / 2 - b * shiftX, ha - lowMargin - firstH - secondH / 2 + b * 3,
wa / 2 + tv.widthStepIn / 2 + b * shiftX, ha - lowMargin - firstH - secondH / 2 + b * 3,
wa / 2 + tv.widthStepIn / 2 + b * shiftX, ha - lowMargin - firstH - secondH);
tv.drawTriangle(pathForTurn);
pathForTurn.lineTo(wa / 2 - tv.widthStepIn / 2 + b * shiftX, ha - lowMargin - firstH - secondH);
pathForTurn.cubicTo(
wa / 2 - tv.widthStepIn / 2 + b * shiftX, ha - lowMargin - firstH - secondH / 2 - b * 2,
wa / 2 - tv.widthStepIn / 2 - b * shiftX, ha - lowMargin - firstH - secondH / 2 - b * 2,
wa / 2 - tv.widthStepIn / 2 - b * shiftX, ha - lowMargin - firstH );
// pathForTurn.lineTo(wa / 2 - tv.widthStepIn / 2 - b * shiftX, ha - lowMargin - firstH);
pathForTurn.lineTo(wa / 2 - tv.widthStepIn / 2 - b * shiftX, ha - lowMargin);
} else if(turnType != null && turnType.isRoundAbout() ) {
int out = turnType.getExitOut();
boolean leftSide = turnType.isLeftSide();
boolean showSteps = SHOW_STEPS && !mini;
TurnVariables tv = new TurnVariables(leftSide, turnType.getTurnAngle(), out, wa, ha, 1);
if(center != null) {
center.set(tv.cx, tv.cy);
}
RectF qrOut = new RectF(tv.cx - tv.radOuterCircle, tv.cy - tv.radOuterCircle,
tv.cx + tv.radOuterCircle, tv.cy + tv.radOuterCircle);
RectF qrIn = new RectF(tv.cx - tv.radInnerCircle, tv.cy - tv.radInnerCircle, tv.cx + tv.radInnerCircle, tv.cy + tv.radInnerCircle);
if(outlay != null && !mini) { if(outlay != null && !mini) {
outlay.addArc(qrOut, 0, 360); outlay.addArc(qrOut, 0, 360);
outlay.addArc(qrIn, 0, -360); outlay.addArc(qrIn, 0, -360);
@ -245,14 +307,14 @@ public class TurnPathHelper {
} }
// move to bottom ring // move to bottom ring
pathForTurn.moveTo(getProjX(dfOut, cx, cy, radOuterCircle), getProjY(dfOut, cx, cy, radOuterCircle)); pathForTurn.moveTo(tv.getProjX(tv.dfOut, tv.radOuterCircle), tv.getProjY(tv.dfOut, tv.radOuterCircle));
if (out <= 1) { if (out <= 1) {
showSteps = false; showSteps = false;
} }
if (showSteps && outlay != null) { if (showSteps && outlay != null) {
double totalStepInter = (out - 1) * dfStepOut; double totalStepInter = (out - 1) * tv.dfStepOut;
double st = (rot - 2 * dfOut - totalStepInter) / out; double st = (tv.rot - 2 * tv.dfOut - totalStepInter) / out;
if ((rot > 0) != (st > 0)) { if ((tv.rot > 0) != (st > 0)) {
showSteps = false; showSteps = false;
} }
if (Math.abs(st) < Math.PI / 60) { if (Math.abs(st) < Math.PI / 60) {
@ -261,126 +323,40 @@ public class TurnPathHelper {
// double st = (rot - 2 * dfOut ) / (2 * out - 1); // double st = (rot - 2 * dfOut ) / (2 * out - 1);
// dfStepOut = st; // dfStepOut = st;
if (showSteps) { if (showSteps) {
outlay.moveTo(getProjX(dfOut, cx, cy, radOuterCircle), getProjY(dfOut, cx, cy, radOuterCircle)); outlay.moveTo(tv.getProjX(tv.dfOut, tv.radOuterCircle), tv.getProjY(tv.dfOut, tv.radOuterCircle));
for (int i = 0; i < out - 1; i++) { for (int i = 0; i < out - 1; i++) {
outlay.arcTo(qrOut, startArcAngle(dfOut + i * (st + dfStepOut)), sweepArcAngle(st)); outlay.arcTo(qrOut, startArcAngle(tv.dfOut + i * (st + tv.dfStepOut)), sweepArcAngle(st));
arcLineTo(outlay, arcLineTo(outlay,
dfOut + (i + 1) * (st + dfStepOut) - dfStepOut / 2 - dfStepInter / 2, cx, cy, radStepInter); tv.dfOut + (i + 1) * (st + tv.dfStepOut) - tv.dfStepOut / 2 - tv.dfStepInter / 2,
arcLineTo(outlay, dfOut + (i + 1) * (st + dfStepOut) - dfStepOut / 2 + dfStepInter / 2, cx, cy, radStepInter); tv.cx, tv.cy, tv.radStepInter);
arcLineTo(outlay, dfOut + (i + 1) * (st + dfStepOut), cx, cy, radOuterCircle); arcLineTo(outlay, tv.dfOut + (i + 1) * (st + tv.dfStepOut) - tv.dfStepOut / 2 + tv.dfStepInter / 2,
tv.cx, tv.cy, tv.radStepInter);
arcLineTo(outlay, tv.dfOut + (i + 1) * (st + tv.dfStepOut), tv.cx, tv.cy, tv.radOuterCircle);
// pathForTurn.arcTo(qr1, startArcAngle(dfOut), sweepArcAngle(rot - dfOut - dfOut)); // pathForTurn.arcTo(qr1, startArcAngle(dfOut), sweepArcAngle(rot - dfOut - dfOut));
} }
outlay.arcTo(qrOut, startArcAngle(rot - dfOut - st), sweepArcAngle(st)); outlay.arcTo(qrOut, startArcAngle(tv.rot - tv.dfOut - st), sweepArcAngle(st));
// swipe back // swipe back
arcLineTo(outlay, rot - dfIn, cx, cy, radInnerCircle); arcLineTo(outlay, tv.rot - tv.dfIn, tv.cx, tv.cy, tv.radInnerCircle);
outlay.arcTo(qrIn, startArcAngle(rot - dfIn), -sweepArcAngle(rot - dfIn - dfIn)); outlay.arcTo(qrIn, startArcAngle(tv.rot - tv.dfIn), -sweepArcAngle(tv.rot - tv.dfIn - tv.dfIn));
} }
} }
// if(!showSteps) { // if(!showSteps) {
// // arc // // arc
// pathForTurn.arcTo(qrOut, startArcAngle(dfOut), sweepArcAngle(rot - dfOut - dfOut)); // pathForTurn.arcTo(qrOut, startArcAngle(dfOut), sweepArcAngle(rot - dfOut - dfOut));
// } // }
pathForTurn.arcTo(qrOut, startArcAngle(dfOut), sweepArcAngle(rot - dfOut - dfOut)); pathForTurn.arcTo(qrOut, startArcAngle(tv.dfOut), sweepArcAngle(tv.rot - tv.dfOut - tv.dfOut));
// up from arc tv.drawTriangle(pathForTurn);
arcLineTo(pathForTurn, rot - dfAr, cx, cy, radArrowTriangle1);
// left triangle
// arcLineTo(pathForTurn, rot - dfAr2, cx, cy, radAr2); // 1.
// arcQuadTo(pathForTurn, rot - dfAr2, radAr2, rot, radArrow, 0.9f, cx, cy); // 2.
arcQuadTo(pathForTurn, rot - dfAr, radArrowTriangle1, rot - dfAr2, radArrowTriangle2, rot, radEndOfArrow, 4.5f, cx, cy); // 3.
// arcLineTo(pathForTurn, rot, cx, cy, radArrow); // 1.
arcQuadTo(pathForTurn, rot - dfAr2, radArrowTriangle2, rot, radEndOfArrow, rot + dfAr2, radArrowTriangle2, 4.5f, cx, cy);
// right triangle
// arcLineTo(pathForTurn, rot + dfAr2, cx, cy, radAr2); // 1.
arcQuadTo(pathForTurn, rot, radEndOfArrow, rot + dfAr2, radArrowTriangle2, rot + dfAr, radArrowTriangle1, 4.5f, cx, cy);
arcLineTo(pathForTurn, rot + dfAr, cx, cy, radArrowTriangle1);
// down to arc // down to arc
arcLineTo(pathForTurn, rot + dfIn, cx, cy, radInnerCircle); arcLineTo(pathForTurn, tv.rot + tv.dfIn, tv.cx, tv.cy, tv.radInnerCircle);
// arc // arc
pathForTurn.arcTo(qrIn, startArcAngle(rot + dfIn), sweepArcAngle(-rot - dfIn - dfIn)); pathForTurn.arcTo(qrIn, startArcAngle(tv.rot + tv.dfIn), sweepArcAngle(-tv.rot - tv.dfIn - tv.dfIn));
// down // down
arcLineTo(pathForTurn, -dfL, cx, cy, radBottom); arcLineTo(pathForTurn, -tv.dfL, tv.cx, tv.cy, tv.radBottom);
// left // left
arcLineTo(pathForTurn, dfL, cx, cy, radBottom); arcLineTo(pathForTurn, tv.dfL, tv.cx, tv.cy, tv.radBottom);
} else if (turnType != null && turnType.isRoundAbout()) {
float t = turnType.getTurnAngle();
boolean leftSide = turnType.isLeftSide();
double minTurn = 25;
if (t >= 170 && t < 215) {
t = 215;
} else if (t > 155 && t < 170) {
t = 155;
}
float sweepAngle = (t - 360) - 180;
if (sweepAngle < -360) {
sweepAngle += 360;
}
if(leftSide && sweepAngle < 0) {
sweepAngle += 360;
}
float r1 = ha / 3f - 1;
float r2 = r1 - 9;
float angleToRot = leftSide ? -0.3f : 0.3f;
int cx = wa / 2 ;
int cy = ha / 2 - 2;
if (leftSide) {
pathForTurn.moveTo(cx - 8, ha - 1);
pathForTurn.lineTo(cx - 8, cy + r1);
} else {
pathForTurn.moveTo(cx, ha - 1);
pathForTurn.lineTo(cx, cy + r1);
}
RectF r = new RectF(cx - r1, cy - r1, cx + r1, cy + r1);
int out = turnType.getExitOut();
if (out < 1) {
out = 1;
}
float prev = 90;
float init = 90;
float step = sweepAngle / out;
for (int i = 1; i <= out; i++) {
float to = step * i;
if (i == out) {
pathForTurn.arcTo(r, prev, to - prev + init);
} else {
float tsRad = (float) ((to - step / 8 + 180) * Math.PI / 180f);
float tsRad2 = (float) ((to + step / 8 + 180) * Math.PI / 180f);
pathForTurn.arcTo(r, prev, to - step / 6 - prev + init );
pathForTurn.lineTo(cx + (r1 + 10) * (float) Math.sin(tsRad), cy - (r1 + 10) * (float) Math.cos(tsRad));
pathForTurn.lineTo(cx + (r1 + 10) * (float) Math.sin(tsRad2), cy - (r1 + 10) * (float) Math.cos(tsRad2));
// not necessary for next arcTo
//pathForTurn.lineTo(cx + (r1 + 0) * (float) Math.sin(tsRad2), cy - (r1 + 0) * (float) Math.cos(tsRad2));
prev = to + step / 6 + init;
}
}
float angleRad = (float) ((180 + sweepAngle) * Math.PI / 180f);
pathForTurn.lineTo(cx + (r1 + 4) * (float) Math.sin(angleRad), cy - (r1 + 4) * (float) Math.cos(angleRad));
pathForTurn.lineTo(cx + (r1 + 6) * (float) Math.sin(angleRad + angleToRot/2), cy - (r1 + 6) * (float) Math.cos(angleRad + angleToRot/2));
pathForTurn.lineTo(cx + (r1 + 14) * (float) Math.sin(angleRad - angleToRot/2), cy - (r1 + 12) * (float) Math.cos(angleRad - angleToRot/2));
pathForTurn.lineTo(cx + (r1 + 6) * (float) Math.sin(angleRad - 3*angleToRot/2), cy - (r1 + 6) * (float) Math.cos(angleRad - 3*angleToRot/2));
pathForTurn.lineTo(cx + (r1 + 4) * (float) Math.sin(angleRad - angleToRot), cy - (r1 + 4) * (float) Math.cos(angleRad - angleToRot));
pathForTurn.lineTo(cx + r2 * (float) Math.sin(angleRad - angleToRot), cy - r2 * (float) Math.cos(angleRad - angleToRot));
r.set(cx - r2, cy - r2, cx + r2, cy + r2);
pathForTurn.arcTo(r, 360 + sweepAngle + 90, -sweepAngle);
if (leftSide) {
pathForTurn.lineTo(cx, cy + r2);
pathForTurn.lineTo(cx, ha - 1);
} else {
pathForTurn.lineTo(cx - 8, cy + r2);
pathForTurn.lineTo(cx - 8, ha - 1);
}
pathForTurn.close();
} }
pathForTurn.close(); pathForTurn.close();
if(transform != null){ if(transform != null){