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

View file

@ -15,17 +15,17 @@
<ImageButton
android:id="@+id/closeButton"
android:contentDescription="@string/shared_string_close"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="52dp"
android:layout_height="52dp"
android:contentDescription="@string/shared_string_close"
android:src="@drawable/ic_action_remove_dark"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginLeft="20dp"
android:text="@string/osm_live_subscription"
android:textColor="@color/color_white"
android:textSize="@dimen/default_list_text_size_large"
@ -52,132 +52,341 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="56dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/emailIcon"
android:layout_width="56dp"
android:layout_height="48dp"
android:scaleType="center"
android:src="@drawable/ic_action_message"/>
<EditText
android:id="@+id/emailEdit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:hint="@string/shared_string_email_address"
android:inputType="textEmailAddress"
android:paddingLeft="2dp"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="72dp"
android:layout_marginRight="16dp"
android:paddingLeft="2dp"
android:text="@string/osm_live_email_desc"
android:textColor="?android:attr/textColorSecondary"/>
<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:minHeight="56dp"
android:orientation="horizontal">
android:layout_marginBottom="8dp"
android:orientation="vertical"
android:visibility="visible">
<ImageView
android:id="@+id/userNameIcon"
android:layout_width="56dp"
android:layout_height="48dp"
android:scaleType="center"
android:src="@drawable/ic_person"/>
<EditText
android:id="@+id/userNameEdit"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:hint="@string/osm_live_user_public_name"
android:inputType="text"
android:paddingLeft="2dp"/>
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>
<CheckBox
android:id="@+id/hideUserNameCheckbox"
<LinearLayout
android:id="@+id/paramsLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:layout_marginLeft="72dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:paddingLeft="2dp"
android:text="@string/osm_live_hide_user_name"
android:textColor="?android:attr/textColorPrimary"/>
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
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="56dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/emailIcon"
android:layout_width="56dp"
android:layout_height="48dp"
android:scaleType="center"
android:src="@drawable/ic_action_message"/>
<EditText
android:id="@+id/emailEdit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:hint="@string/shared_string_email_address"
android:inputType="textEmailAddress"
android:paddingLeft="2dp"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="72dp"
android:layout_marginRight="16dp"
android:paddingLeft="2dp"
android:text="@string/osm_live_email_desc"
android:textColor="?android:attr/textColorSecondary"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="56dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/userNameIcon"
android:layout_width="56dp"
android:layout_height="48dp"
android:scaleType="center"
android:src="@drawable/ic_person"/>
<EditText
android:id="@+id/userNameEdit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:hint="@string/osm_live_user_public_name"
android:inputType="text"
android:paddingLeft="2dp"/>
</LinearLayout>
<CheckBox
android:id="@+id/hideUserNameCheckbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:layout_marginLeft="72dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:paddingLeft="4dp"
android:text="@string/osm_live_hide_user_name"
android:textColor="?android:attr/textColorPrimary"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/editModeBottomView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginTop="16dp"
android:visibility="gone">
<Button
android:id="@+id/saveChangesButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="72dp"
android:layout_marginRight="16dp"
android:background="@drawable/btn_round_blue"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:text="@string/shared_string_save_changes"
android:textColor="@color/color_white"/>
</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
android:id="@+id/purchaseCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
android:orientation="vertical"
android:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="4dp"
android:minHeight="56dp"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/countryIcon"
<android.support.v7.widget.AppCompatImageView
android:layout_width="56dp"
android:layout_height="48dp"
android:scaleType="center"
android:src="@drawable/ic_world_globe_dark"/>
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_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
<LinearLayout
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"/>
android:orientation="horizontal">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/priceTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:text="@string/osm_live_default_price"
android:textColor="?attr/color_dialog_buttons"
android:textSize="@dimen/default_list_text_size_large"
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>
<net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/osm_live_payment_desc"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/default_desc_text_size"/>
<android.support.v7.widget.AppCompatButton
android:id="@+id/subscribeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="20dp"
android:background="@drawable/blue_button_drawable"
android:paddingBottom="4dp"
android:paddingLeft="14dp"
android:paddingRight="14dp"
android:paddingTop="4dp"
android:text="@string/osm_live_subscribe_btn"
android:textColor="@color/color_white"
android:visibility="visible"/>
</LinearLayout>
@ -185,98 +394,11 @@
</LinearLayout>
<LinearLayout
android:id="@+id/editModeBottomView"
<include layout="@layout/card_bottom_divider"/>
<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginTop="16dp"
android:visibility="gone">
<Button
android:id="@+id/saveChangesButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="72dp"
android:layout_marginRight="16dp"
android:background="@drawable/btn_round_blue"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:text="@string/shared_string_save_changes"
android:textColor="@color/color_white"/>
</LinearLayout>
<LinearLayout
android:id="@+id/purchaseCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="?attr/bg_card"
android:orientation="vertical"
android:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:orientation="horizontal">
<net.osmand.plus.widgets.TextViewEx
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/osm_live_month_cost"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/default_list_text_size_large"
android:textStyle="bold"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/priceTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:gravity="right"
android:text="@string/osm_live_default_price"
android:textColor="?attr/color_dialog_buttons"
android:textSize="@dimen/default_list_text_size_large"
android:textStyle="bold"/>
</LinearLayout>
<net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:text="@string/osm_live_month_cost_desc"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/default_desc_text_size"/>
<View
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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginBottom="10dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="6dp"
android:background="?attr/selectableItemBackground"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/osm_live_subscribe_btn"
android:textColor="?attr/color_dialog_buttons"/>
</LinearLayout>
android:layout_height="16dp"/>
</LinearLayout>

View file

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

View file

@ -1,4 +1,4 @@
<?xml version='1.0' encoding='utf-8'?>
<?xml version='1.0' encoding='utf-8'?>
<resources>
<!--
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).
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_for">Get for %1$s</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_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>
<string name="select_map_marker">Select map marker</string>

View file

@ -30,6 +30,7 @@ public class AndroidNetworkUtils {
final Map<String, String> parameters,
final String userOperation,
final boolean toastAllowed,
final boolean post,
final OnRequestResultListener listener) {
new AsyncTask<Void, Void, String>() {
@ -37,7 +38,7 @@ public class AndroidNetworkUtils {
@Override
protected String doInBackground(Void... params) {
try {
return sendRequest(ctx, url, parameters, userOperation, toastAllowed);
return sendRequest(ctx, url, parameters, userOperation, toastAllowed, post);
} catch (Exception e) {
return null;
}
@ -55,15 +56,11 @@ public class AndroidNetworkUtils {
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;
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) {
StringBuilder sb = new StringBuilder();
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"));
}
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.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
connection.setRequestProperty("Content-Length", String.valueOf(params.getBytes("UTF-8").length));
connection.setFixedLengthStreamingMode(params.getBytes("UTF-8").length);
@ -89,6 +91,7 @@ public class AndroidNetworkUtils {
output.close();
} else {
connection.setRequestMethod("GET");
connection.connect();
}
@ -96,7 +99,7 @@ public class AndroidNetworkUtils {
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
if (toastAllowed) {
String msg = userOperation
+ " " + ctx.getString(R.string.failed_op) + " : " + connection.getResponseMessage();
+ " " + ctx.getString(R.string.failed_op) + ": " + connection.getResponseMessage();
showToast(ctx, msg);
}
} else {

View file

@ -895,11 +895,14 @@ public class OsmandSettings {
// this value string is synchronized with settings_pref.xml preference name
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_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_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_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();

View file

@ -53,7 +53,7 @@ public class Version {
private static Version ver = null;
private static Version getVersion(OsmandApplication ctx){
if(ver == null){
if (ver == null) {
ver = new Version(ctx);
}
return ver;

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 LONG_KEYPRESS_MSG_ID = OsmAndConstants.UI_HANDLER_MAP_VIEW + 2;
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);
@ -277,13 +279,6 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
}
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();
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
@ -626,6 +621,14 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
}
}
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
@ -749,7 +752,6 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
}
// remember if map should come back to isMapLinkedToLocation=true
mapViewTrackingUtilities.setMapLinkedToLocation(false);
if (mapLabelToShow != null && !mapLabelToShow.contextMenuDisabled()) {
mapContextMenu.setMapCenter(latLonToShow);
mapContextMenu.setMapPosition(mapView.getMapPosition());
@ -764,7 +766,8 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
tb.setPixelDimensions(tbw, tbh);
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);
}
//mapContextMenu.setMapZoom(settings.getMapZoomToShow());

View file

@ -12,14 +12,12 @@ import android.os.StatFs;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v4.widget.Space;
import android.support.v7.widget.AppCompatButton;
import android.text.method.LinkMovementMethod;
@ -35,6 +33,7 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import net.osmand.IProgress;
import net.osmand.PlatformUtil;
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.download.DownloadIndexesThread.DownloadEvents;
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.FreeVersionDialogFragment;
import net.osmand.plus.download.ui.LocalIndexesFragment;
@ -76,8 +74,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
public class DownloadActivity extends AbstractDownloadActivity implements DownloadEvents,
OnRequestPermissionsResultCallback, InAppListener {
@ -197,7 +193,6 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
filterCat = intent.getExtras().getString(FILTER_CAT);
filterGroup = intent.getExtras().getString(FILTER_GROUP);
}
showFirstTimeExternalStorage();
}
@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) {
return ContextCompat.checkSelfPermission(ctx, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== 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() {
String res = filter;
filter = null;

View file

@ -14,6 +14,7 @@ import android.view.WindowManager;
import android.widget.ImageView;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
public class FirstUsageWelcomeFragment extends Fragment {
public static final String TAG = "FirstUsageWelcomeFragment";
@ -33,26 +34,21 @@ public class FirstUsageWelcomeFragment extends Fragment {
skipButton.setOnClickListener(new View.OnClickListener() {
@Override
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());
}
});
return view;
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getActivity().getWindow(); // in Activity's onCreate() for instance
w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
((MapActivity)getActivity()).disableDrawer();
}
@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.Bundle;
import android.os.StatFs;
import android.provider.Settings.Secure;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
@ -19,7 +20,6 @@ import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;
import net.osmand.AndroidNetworkUtils;
import net.osmand.Location;
import net.osmand.ValueHolder;
@ -33,6 +33,7 @@ import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadActivityType;
@ -53,9 +54,11 @@ import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
@ -326,13 +329,20 @@ public class FirstUsageWizardFragment extends Fragment implements OsmAndLocation
switch (wizardType) {
case SEARCH_LOCATION:
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>() {
@Override
protected String doInBackground(Void... params) {
try {
return AndroidNetworkUtils.sendRequest(app, "http://osmand.net/api/geo-ip", null,
"Requesting location by IP...", false);
return AndroidNetworkUtils.sendRequest(app, "http://osmand.net/api/geo-ip", pms,
"Requesting location by IP...", false, false);
} catch (Exception e) {
logError("Requesting location by IP error: ", e);
@ -424,6 +434,18 @@ public class FirstUsageWizardFragment extends Fragment implements OsmAndLocation
app.getAppInitializer().removeListener(this);
}
@Override
public void onResume() {
super.onResume();
((MapActivity)getActivity()).disableDrawer();
}
@Override
public void onPause() {
super.onPause();
((MapActivity)getActivity()).enableDrawer();
}
@Override
public void updateLocation(final Location loc) {
final OsmandApplication app = getMyApplication();

View file

@ -21,6 +21,7 @@ import android.annotation.SuppressLint;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.Settings.Secure;
import android.util.Log;
import android.view.View;
@ -50,17 +51,21 @@ public class DiscountHelper {
}
mLastCheckTime = System.currentTimeMillis();
final Map<String, String> pms = new LinkedHashMap<>();
pms.put("name", Version.getAppName(app));
pms.put("version", Version.getAppVersion(app));
pms.put("version", Version.getFullVersion(app));
pms.put("nd", app.getAppInitializer().getFirstInstalledDays() +"");
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>() {
@Override
protected String doInBackground(Void... params) {
try {
String res = AndroidNetworkUtils.sendRequest(mapActivity.getMyApplication(),
URL, pms, "Requesting discount info...", false);
URL, pms, "Requesting discount info...", false, false);
return res;
} catch (Exception 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) {
if(gpxFile.points == null || gpxFile.points.size() == 0) {
if(gpxFile == null || gpxFile.points == null || gpxFile.points.size() == 0) {
handleResult(gpxFile, fileName, save);
return;
}

View file

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

View file

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

View file

@ -262,19 +262,25 @@ public class IabHelper {
}
};
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0).isEmpty()) {
// service available to handle that Intent
mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
}
else {
// no service available to handle that Intent
mServiceConn = null;
try {
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0).isEmpty()) {
// service available to handle that Intent
mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
} else {
// no service available to handle that Intent
mServiceConn = null;
if (listener != null) {
listener.onIabSetupFinished(
new IabResult(BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE,
"Billing service unavailable on device."));
}
}
} catch (Exception e) {
if (listener != null) {
listener.onIabSetupFinished(
new IabResult(BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE,
"Billing service unavailable on device."));
listener.onIabSetupFinished(new IabResult(IABHELPER_SUBSCRIPTIONS_NOT_AVAILABLE,
"InAppBillingService not available"));
}
}
}
@ -290,7 +296,13 @@ public class IabHelper {
mSetupDone = false;
if (mServiceConn != null) {
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;
mContext = null;

View file

@ -10,6 +10,7 @@ import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
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);
listView.addFooterView(bottomShadowView);
adapter = new LocalIndexesAdapter(this);
listView.setAdapter(adapter);
listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
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);
loadLocalIndexesTask = new LoadLocalIndexTask(adapter, this).execute();
if(Build.VERSION.SDK_INT >= 11) {
loadLocalIndexesTask = new LoadLocalIndexTask(adapter, this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
loadLocalIndexesTask = new LoadLocalIndexTask(adapter, this).execute();
}
return view;
}

View file

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

View file

@ -4,12 +4,14 @@ import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.AppCompatCheckBox;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
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 COUNTRY_ITEM_ID = "country_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 ProgressDialog dlg;
private boolean editMode;
private boolean donation;
private String prevEmail;
private CountryItem selectedCountryItem;
@ -76,6 +80,8 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
outState.putString(EMAIL_ID, emailEdit.getText().toString());
CheckBox hideUserNameCheckbox = (CheckBox) view.findViewById(R.id.hideUserNameCheckbox);
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) {
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 countryDownloadName = settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get();
boolean hideUserName = settings.BILLING_HIDE_USER_NAME.get();
donation = !countryDownloadName.equals(OsmandSettings.BILLING_USER_DONATION_NONE_PARAMETER);
if (savedInstanceState != null) {
userName = savedInstanceState.getString(USER_NAME_ID);
email = savedInstanceState.getString(EMAIL_ID);
hideUserName = savedInstanceState.getBoolean(HIDE_USER_NAME_ID);
donation = savedInstanceState.getBoolean(DONATION_ID);
Object obj = savedInstanceState.getSerializable(COUNTRY_ITEM_ID);
if (obj instanceof CountryItem) {
selectedCountryItem = (CountryItem) obj;
countryDownloadName = selectedCountryItem.getDownloadName();
} 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));
}
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);
if (!Algorithms.isEmpty(userName)) {
userNameEdit.setText(userName);
@ -155,7 +178,7 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
}
countrySelectionFragment.initCountries(getMyApplication());
if (Algorithms.isEmpty(countryDownloadName)) {
if (Algorithms.isEmpty(countryDownloadName) || countryDownloadName.equals(OsmandSettings.BILLING_USER_DONATION_NONE_PARAMETER)) {
selectedCountryItem = countrySelectionFragment.getCountryItems().get(0);
} else {
selectedCountryItem = countrySelectionFragment.getCountryItem(countryDownloadName);
@ -206,7 +229,7 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
AndroidNetworkUtils.sendRequestAsync(getMyApplication(),
"http://download.osmand.net/subscription/update.php",
parameters, "Sending data...", true, new AndroidNetworkUtils.OnRequestResultListener() {
parameters, "Sending data...", true, true, new AndroidNetworkUtils.OnRequestResultListener() {
@Override
public void onResult(String result) {
dismissProgress();
@ -297,16 +320,23 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
}
private boolean applySettings(String userName, String email, boolean hideUserName) {
String countryName = selectedCountryItem != null ? selectedCountryItem.getLocalName() : "";
String countryDownloadName = selectedCountryItem != null ? selectedCountryItem.getDownloadName() : "";
if (Algorithms.isEmpty(email) || !AndroidUtils.isValidEmail(email)) {
getMyApplication().showToastMessage(getString(R.string.osm_live_enter_email));
return false;
}
if (Algorithms.isEmpty(userName) && !hideUserName) {
getMyApplication().showToastMessage(getString(R.string.osm_live_enter_user_name));
return false;
String countryName;
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)) {
getMyApplication().showToastMessage(getString(R.string.osm_live_enter_email));
return false;
}
if (Algorithms.isEmpty(userName) && !hideUserName) {
getMyApplication().showToastMessage(getString(R.string.osm_live_enter_user_name));
return false;
}
}
settings.BILLING_USER_NAME.set(userName);

View file

@ -640,58 +640,7 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
}
public void fabPressed() {
hide();
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();
}
mapActivity.getMapLayers().getMapControlsLayer().navigateFab();
}
public void buttonWaypointPressed() {
@ -811,7 +760,7 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
return GpxUiHelper.selectSingleGPXFile(mapActivity, true, callbackWithObject);
}
private PointDescription getPointDescriptionForTarget() {
public PointDescription getPointDescriptionForTarget() {
if (pointDescription.isLocation()
&& pointDescription.getName().equals(PointDescription.getAddressNotFoundStr(mapActivity))) {
return new PointDescription(PointDescription.POINT_TYPE_LOCATION, "");

View file

@ -73,7 +73,7 @@ public class NominatimPoiFilter extends PoiUIFilter {
@Override
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;
String NOMINATIM_API;
if (deviceApiVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) {

View file

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

View file

@ -32,7 +32,7 @@ public class SearchByNameFilter extends PoiUIFilter {
@Override
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>();
final int limit = distanceInd == 0 ? 500 : -1;
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)) {
PoiUIFilter filter;
if (searchPhrase.isNoSelectedType()) {
filter = new PoiUIFilter(null, app, "");
filter = app.getPoiFilters().getSearchByNamePOIFilter();
if (!Algorithms.isEmpty(searchPhrase.getUnknownSearchWord())) {
filter.setFilterByName(searchPhrase.getUnknownSearchWord());
filter.clearCurrentResults();
}
} else if (searchPhrase.getLastSelectedWord().getResult().object instanceof AbstractPoiType) {
if (searchPhrase.isNoSelectedType()) {

View file

@ -26,6 +26,7 @@ import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.core.android.MapRendererContext;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.OsmAndLocationProvider;
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.search.SearchAddressFragment;
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.routing.RoutingHelper;
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;
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_FAB_PERMISSION = 201;
public MapHudButton createHudButton(View iv, int resId) {
MapHudButton mc = new MapHudButton();
@ -413,6 +417,69 @@ public class MapControlsLayer extends OsmandMapLayer {
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() {
touchEvent = 0;
@ -928,6 +995,9 @@ public class MapControlsLayer extends OsmandMapLayer {
if (requestCode == REQUEST_LOCATION_FOR_NAVIGATION_PERMISSION
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
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 OsmandMapTileView view;
private final static int MAXIMUM_SHOW_AMENITIES = 5;
private RoutingHelper routingHelper;
private Set<PoiUIFilter> filters = new TreeSet<>();

View file

@ -25,8 +25,113 @@ public class TurnPathHelper {
public static final int FIRST_TURN = 1;
public static final int SECOND_TURN = 2;
public static final int THIRD_TURN = 3;
private static final boolean USE_NEW_RNDB = true;
private static final boolean SHOW_STEPS = true;
private static class TurnVariables {
float radEndOfArrow = 44;
float radInnerCircle = 10;
float radOuterCircle = radInnerCircle + 8;
float radBottom = radOuterCircle + 10;
float radStepInter = radOuterCircle + 6;
float radArrowTriangle1 = radOuterCircle + 7;
float widthStepIn = 8;
float widthStepInter = 6;
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;
// System.out.println("Angle " + dfL + " " + dfOut + " " + dfIn + " " + minDelta + " ");
rot = alignRotation(turnAngle, leftSide, minDelta, out) / 180 * Math.PI;
cx = wa / 2;
cy = ha / 2;
// align center
float potentialArrowEndX = (float) (Math.sin(rot) * radEndOfArrow);
float potentialArrowEndY = (float) (Math.cos(rot) * radEndOfArrow);
if (potentialArrowEndX > cx) {
cx = potentialArrowEndX;
} else if (potentialArrowEndX < -cx) {
cx = 2 * cx + potentialArrowEndX;
}
if (potentialArrowEndY > cy) {
cy = 2 * cy - potentialArrowEndY;
} else if (potentialArrowEndY < -cy) {
cy = -potentialArrowEndY;
}
}
private float getProjX(double angle, double radius) {
return getX(angle, radius) + cx;
}
private float getProjY(double angle, double radius) {
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,
@ -40,203 +145,160 @@ public class TurnPathHelper {
}
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;
int lowMargin = 6;
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);
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;
float quadShiftX = 18;
float quadShiftY = 18;
int wl = 10; // width
int h = (int) (ha - quadShiftY - harrowL + hpartArrowL - 5);
int sl = wl + th / 2;
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.rMoveTo(-b * sl, 0);
pathForTurn.moveTo(centerLineX + b * tv.widthStepIn / 2, ha - lowMargin);
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 );
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;
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);
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;
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);
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 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 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();
float radEndOfArrow = 44;
float radInnerCircle = 10;
float radOuterCircle = radInnerCircle + 8;
float radBottom = radOuterCircle + 10;
float radStepInter = radOuterCircle + 6;
float radArrowTriangle1 = radOuterCircle + 7;
float radArrowTriangle2 = radOuterCircle + 8;
float widthStepIn = 8;
float widthStepInter = 6;
float widthArrow = 22;
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 + " ");
double rot = alignRotation(turnType.getTurnAngle(), leftSide, minDelta, out) / 180 * Math.PI;
float cx = wa / 2 ;
float cy = ha / 2 ;
// align center
float potentialArrowEndX = (float) (Math.sin(rot) * radEndOfArrow);
float potentialArrowEndY = (float) (Math.cos(rot) * radEndOfArrow);
if (potentialArrowEndX > cx) {
cx = potentialArrowEndX;
} else if (potentialArrowEndX < -cx) {
cx = 2 * cx + potentialArrowEndX;
}
if(potentialArrowEndY > cy) {
cy = 2 * cy - potentialArrowEndY;
} else if(potentialArrowEndY < -cy) {
cy = -potentialArrowEndY;
}
TurnVariables tv = new TurnVariables(leftSide, turnType.getTurnAngle(), out, wa, ha, 1);
if(center != null) {
center.set(cx, cy);
center.set(tv.cx, tv.cy);
}
RectF qrOut = new RectF(cx - radOuterCircle, cy - radOuterCircle, cx + radOuterCircle, cy + radOuterCircle);
RectF qrIn = new RectF(cx - radInnerCircle, cy - radInnerCircle, cx + radInnerCircle, cy + radInnerCircle);
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) {
outlay.addArc(qrOut, 0, 360);
outlay.addArc(qrIn, 0, -360);
@ -245,14 +307,14 @@ public class TurnPathHelper {
}
// 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) {
showSteps = false;
}
if (showSteps && outlay != null) {
double totalStepInter = (out - 1) * dfStepOut;
double st = (rot - 2 * dfOut - totalStepInter) / out;
if ((rot > 0) != (st > 0)) {
double totalStepInter = (out - 1) * tv.dfStepOut;
double st = (tv.rot - 2 * tv.dfOut - totalStepInter) / out;
if ((tv.rot > 0) != (st > 0)) {
showSteps = false;
}
if (Math.abs(st) < Math.PI / 60) {
@ -261,127 +323,41 @@ public class TurnPathHelper {
// double st = (rot - 2 * dfOut ) / (2 * out - 1);
// dfStepOut = st;
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++) {
outlay.arcTo(qrOut, startArcAngle(dfOut + i * (st + dfStepOut)), sweepArcAngle(st));
outlay.arcTo(qrOut, startArcAngle(tv.dfOut + i * (st + tv.dfStepOut)), sweepArcAngle(st));
arcLineTo(outlay,
dfOut + (i + 1) * (st + dfStepOut) - dfStepOut / 2 - dfStepInter / 2, cx, cy, radStepInter);
arcLineTo(outlay, dfOut + (i + 1) * (st + dfStepOut) - dfStepOut / 2 + dfStepInter / 2, cx, cy, radStepInter);
arcLineTo(outlay, dfOut + (i + 1) * (st + dfStepOut), cx, cy, radOuterCircle);
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.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));
}
outlay.arcTo(qrOut, startArcAngle(rot - dfOut - st), sweepArcAngle(st));
outlay.arcTo(qrOut, startArcAngle(tv.rot - tv.dfOut - st), sweepArcAngle(st));
// swipe back
arcLineTo(outlay, rot - dfIn, cx, cy, radInnerCircle);
outlay.arcTo(qrIn, startArcAngle(rot - dfIn), -sweepArcAngle(rot - dfIn - dfIn));
arcLineTo(outlay, tv.rot - tv.dfIn, tv.cx, tv.cy, tv.radInnerCircle);
outlay.arcTo(qrIn, startArcAngle(tv.rot - tv.dfIn), -sweepArcAngle(tv.rot - tv.dfIn - tv.dfIn));
}
}
// if(!showSteps) {
// // arc
// 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
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);
tv.drawTriangle(pathForTurn);
// down to arc
arcLineTo(pathForTurn, rot + dfIn, cx, cy, radInnerCircle);
arcLineTo(pathForTurn, tv.rot + tv.dfIn, tv.cx, tv.cy, tv.radInnerCircle);
// 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
arcLineTo(pathForTurn, -dfL, cx, cy, radBottom);
arcLineTo(pathForTurn, -tv.dfL, tv.cx, tv.cy, tv.radBottom);
// 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();
if(transform != null){
pathForTurn.transform(transform);