Merge branch 'master' into Fix_7763_gpx_track_selection

This commit is contained in:
Dima-1 2020-02-19 15:03:43 +02:00
commit c774bd1fc5
47 changed files with 797 additions and 280 deletions

View file

@ -1,8 +1,6 @@
package net.osmand.router; package net.osmand.router;
import net.osmand.Location;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.binary.RouteDataObject;
import net.osmand.router.GeneralRouter.GeneralRouterProfile; import net.osmand.router.GeneralRouter.GeneralRouterProfile;
import net.osmand.router.GeneralRouter.RouteAttributeContext; import net.osmand.router.GeneralRouter.RouteAttributeContext;
import net.osmand.router.GeneralRouter.RouteDataObjectAttribute; import net.osmand.router.GeneralRouter.RouteDataObjectAttribute;
@ -13,9 +11,10 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.Stack; import java.util.Stack;
public class RoutingConfiguration { public class RoutingConfiguration {
@ -55,7 +54,7 @@ public class RoutingConfiguration {
private String defaultRouter = ""; private String defaultRouter = "";
private Map<String, GeneralRouter> routers = new LinkedHashMap<>(); private Map<String, GeneralRouter> routers = new LinkedHashMap<>();
private Map<String, String> attributes = new LinkedHashMap<>(); private Map<String, String> attributes = new LinkedHashMap<>();
private HashMap<Long, Location> impassableRoadLocations = new HashMap<>(); private Set<Long> impassableRoadLocations = new HashSet<>();
public Builder() { public Builder() {
@ -95,7 +94,7 @@ public class RoutingConfiguration {
i.initialDirection = direction; i.initialDirection = direction;
i.recalculateDistance = parseSilentFloat(getAttribute(i.router, "recalculateDistanceHelp"), i.recalculateDistance) ; i.recalculateDistance = parseSilentFloat(getAttribute(i.router, "recalculateDistanceHelp"), i.recalculateDistance) ;
i.heuristicCoefficient = parseSilentFloat(getAttribute(i.router, "heuristicCoefficient"), i.heuristicCoefficient); i.heuristicCoefficient = parseSilentFloat(getAttribute(i.router, "heuristicCoefficient"), i.heuristicCoefficient);
i.router.addImpassableRoads(impassableRoadLocations.keySet()); i.router.addImpassableRoads(new HashSet<>(impassableRoadLocations));
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(i.router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES); i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(i.router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
int desirable = parseSilentInt(getAttribute(i.router, "memoryLimitInMB"), 0); int desirable = parseSilentInt(getAttribute(i.router, "memoryLimitInMB"), 0);
if(desirable != 0) { if(desirable != 0) {
@ -111,16 +110,12 @@ public class RoutingConfiguration {
return i; return i;
} }
public Map<Long, Location> getImpassableRoadLocations() { public Set<Long> getImpassableRoadLocations() {
return impassableRoadLocations; return impassableRoadLocations;
} }
public boolean addImpassableRoad(RouteDataObject route, Location location) { public boolean addImpassableRoad(long routeId) {
if (!impassableRoadLocations.containsKey(route.id)){ return impassableRoadLocations.add(routeId);
impassableRoadLocations.put(route.id, location);
return true;
}
return false;
} }
public Map<String, String> getAttributes() { public Map<String, String> getAttributes() {
@ -159,8 +154,8 @@ public class RoutingConfiguration {
return routers; return routers;
} }
public void removeImpassableRoad(RouteDataObject obj) { public void removeImpassableRoad(long routeId) {
impassableRoadLocations.remove(obj.id); impassableRoadLocations.remove(routeId);
} }
} }

View file

@ -49,6 +49,8 @@ public class MapUtils {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_', '~' '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_', '~'
}; };
public static double getDistance(LatLon l, double latitude, double longitude) { public static double getDistance(LatLon l, double latitude, double longitude) {
return getDistance(l.getLatitude(), l.getLongitude(), latitude, longitude); return getDistance(l.getLatitude(), l.getLongitude(), latitude, longitude);
} }
@ -695,39 +697,10 @@ public class MapUtils {
return new LatLon(Math.toDegrees(phi2), Math.toDegrees(lambda2)); return new LatLon(Math.toDegrees(phi2), Math.toDegrees(lambda2));
} }
public static double getVectorMagnitude(int startX, int startY, int endX, int endY) { public static double getSqrtDistance(int startX, int startY, int endX, int endY) {
return Math.sqrt(Math.pow((double) (endX - startX), 2.0) + Math.pow((double) (endY - startY), 2.0)); return Math.sqrt((endX - startX) * (endX - startX) + (endY - startY) * (endY - startY));
} }
//angle of vector
public static double getAngleForRadiusVector(int startX, int startY, int endX, int endY) {
return 2 * Math.atan((endY - startY) / (endX - startX
+ Math.sqrt(Math.pow((double) (endX - startX), 2.0) + Math.pow((double) (endY - startY), 2.0))));
}
//returns coordinates of point on circle
public static double[] getCoordinatesFromRadiusAndAngle(double centerX, double centerY, double radius, double angle) {
double x = centerX + radius * Math.cos(angle);
double y = centerY + radius * Math.sin(angle);
return new double[]{x,y};
}
//returns signed angle between vectors in radians
public static double getAngleBetweenVectors(int vectorAStartX, int vectorAStartY, int vectorAEndX, int vectorAEndY,
int vectorBStartX, int vectorBStartY, int vectorBEndX, int vectorBEndY) {
int[] vectorA = new int[] {getVectorAxisValue(vectorAStartX, vectorAEndX), getVectorAxisValue(vectorAStartY, vectorAEndY)};
int[] vectorB = new int[] {getVectorAxisValue(vectorBStartX, vectorBEndX), getVectorAxisValue(vectorBStartY, vectorBEndY)};
return Math.atan2(vectorA[0] * vectorB[1] - vectorA[1] * vectorB [0], vectorA[0] * vectorB[0] + vectorA[1] * vectorB[1]);
}
//calculates vector value for axis
public static int getVectorAxisValue(int axisStart, int axisEnd) {
if (axisEnd < axisStart) {
return Math.abs(axisEnd) - Math.abs(axisStart);
} else {
return Math.abs(axisStart) - Math.abs(axisEnd);
}
}
} }

View file

@ -0,0 +1,40 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M19,20L12,16V22H12.3944C14.7454,22 17.0438,21.3041 19,20Z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="16.5"
android:startX="12"
android:endY="24"
android:endX="17"
android:type="linear">
<item android:offset="0" android:color="#FF727272"/>
<item android:offset="1" android:color="#00727272"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M6,12H10V14H6V12Z"
android:strokeAlpha="0.2"
android:fillColor="#727272"
android:fillAlpha="0.2"/>
<path
android:pathData="M6,20H10V22H6V20Z"
android:strokeAlpha="0.2"
android:fillColor="#727272"
android:fillAlpha="0.2"/>
<path
android:pathData="M10,16H6V18H10V16Z"
android:strokeAlpha="0.2"
android:fillColor="#727272"
android:fillAlpha="0.2"/>
<path
android:pathData="M6,2V10.1487L18.9923,17.7276C19.9464,18.2841 21.171,17.9618 21.7276,17.0077C22.2841,16.0536 21.9618,14.829 21.0077,14.2724L10,7.8513V2H6ZM8,3L7,5H9L8,3ZM8,7L7,9H9L8,7ZM11.9019,12.366L10.6699,10.5L12.9019,10.634L11.9019,12.366ZM18.8301,16.366L17.5981,14.5L19.8301,14.634L18.8301,16.366ZM14.134,12.5L15.366,14.366L16.366,12.634L14.134,12.5Z"
android:fillColor="#727272"
android:fillType="evenOdd"/>
</vector>

View file

@ -46,6 +46,7 @@
android:ellipsize="end" android:ellipsize="end"
android:maxLines="2" android:maxLines="2"
android:lineSpacingMultiplier="@dimen/text_button_line_spacing_multiplier" android:lineSpacingMultiplier="@dimen/text_button_line_spacing_multiplier"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_sub_text_size" android:textSize="@dimen/default_sub_text_size"
tools:text="Some description" /> tools:text="Some description" />

View file

@ -64,6 +64,7 @@
android:layout_gravity="fill_horizontal" android:layout_gravity="fill_horizontal"
android:layout_marginBottom="24dp" android:layout_marginBottom="24dp"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:textColor="?android:textColorSecondary"
android:text="@string/application_dir_description" android:text="@string/application_dir_description"
android:textSize="16sp"/> android:textSize="16sp"/>

View file

@ -74,7 +74,7 @@
android:layout_marginLeft="6dp" android:layout_marginLeft="6dp"
android:drawablePadding="2dp" android:drawablePadding="2dp"
android:maxLines="1" android:maxLines="1"
android:textColor="@color/text_color_secondary_dark" android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_sub_text_size"/> android:textSize="@dimen/default_sub_text_size"/>
<TextView <TextView
@ -84,7 +84,7 @@
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:textColor="@color/text_color_secondary_dark" android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_sub_text_size"/> android:textSize="@dimen/default_sub_text_size"/>
<TextView <TextView

View file

@ -35,6 +35,7 @@
android:layout_weight="1" android:layout_weight="1"
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center_vertical" android:gravity="center_vertical"
android:textColor="?android:textColorPrimary"
tools:text="Today"/> tools:text="Today"/>
<android.support.v7.widget.SwitchCompat <android.support.v7.widget.SwitchCompat
@ -68,6 +69,7 @@
android:ellipsize="end" android:ellipsize="end"
android:maxLines="3" android:maxLines="3"
android:textAppearance="@style/TextAppearance.ContextMenuSubtitle" android:textAppearance="@style/TextAppearance.ContextMenuSubtitle"
android:textColor="?android:textColorSecondary"
tools:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard." /> tools:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard." />
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx

View file

@ -32,7 +32,7 @@
android:layout_marginRight="@dimen/list_content_padding_large" android:layout_marginRight="@dimen/list_content_padding_large"
android:layout_marginTop="@dimen/list_header_padding" android:layout_marginTop="@dimen/list_header_padding"
android:gravity="center" android:gravity="center"
android:textColor="?attr/card_description_text_color" android:textColor="?attr/dialog_text_description_color"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_regular" osmand:typeface="@string/font_roboto_regular"
tools:text="@string/osm_live_payment_desc"/> tools:text="@string/osm_live_payment_desc"/>

View file

@ -46,7 +46,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/osm_live_payment_contribute_descr" android:text="@string/osm_live_payment_contribute_descr"
android:textColor="?attr/card_description_text_color" android:textColor="?attr/dialog_text_description_color"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
android:visibility="gone" android:visibility="gone"
osmand:typeface="@string/font_roboto_regular" osmand:typeface="@string/font_roboto_regular"
@ -56,7 +56,7 @@
android:id="@+id/description" android:id="@+id/description"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="?attr/card_description_text_color" android:textColor="?attr/dialog_text_description_color"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_regular" osmand:typeface="@string/font_roboto_regular"
tools:text="Monthly payment" /> tools:text="Monthly payment" />

View file

@ -38,7 +38,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/osm_live_payment_contribute_descr" android:text="@string/osm_live_payment_contribute_descr"
android:textColor="?attr/card_description_text_color" android:textColor="?attr/dialog_text_description_color"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
android:visibility="gone" android:visibility="gone"
osmand:typeface="@string/font_roboto_regular" osmand:typeface="@string/font_roboto_regular"
@ -48,7 +48,7 @@
android:id="@+id/description" android:id="@+id/description"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="?attr/card_description_text_color" android:textColor="?attr/dialog_text_description_color"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_regular" osmand:typeface="@string/font_roboto_regular"
tools:text="$0.62 / month • Save 68%" /> tools:text="$0.62 / month • Save 68%" />

View file

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/seekbar_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<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:orientation="vertical"
android:paddingLeft="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:paddingTop="@dimen/content_padding"
android:paddingBottom="@dimen/content_padding_half">
<net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/content_padding_small"
android:paddingLeft="@dimen/content_padding_small"
android:text="@string/recalc_angle_dialog_title"
android:textColor="?android:textColorPrimary"
app:typeface="@string/font_roboto_medium"
android:textSize="@dimen/default_list_text_size_large" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/content_padding_half"
android:paddingStart="@dimen/content_padding_small"
android:paddingLeft="@dimen/content_padding_small"
android:paddingBottom="@dimen/content_padding"
android:text="@string/recalc_angle_dialog_descr"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size" />
<LinearLayout
android:id="@+id/angle_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/angle_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:paddingStart="@dimen/content_padding_small"
android:paddingLeft="@dimen/content_padding_small"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
tools:text="@string/shared_string_angle" />
<TextView
android:id="@+id/angle_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end"
android:maxLength="4"
android:maxLines="1"
android:paddingRight="4dp"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
tools:text="60" />
<TextView
android:id="@+id/angle_units"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="@dimen/content_padding_small"
android:paddingRight="@dimen/content_padding_small"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"
tools:text="°" />
</LinearLayout>
<LinearLayout
android:id="@+id/angle_seekbar_lane"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="@dimen/content_padding">
<TextView
android:id="@+id/angle_seekbar_min_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingStart="@dimen/content_padding_small"
android:paddingLeft="@dimen/content_padding_small"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"
android:text="0°" />
<TextView
android:id="@+id/angle_seekbar_max_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end"
android:paddingEnd="@dimen/content_padding_small"
android:paddingRight="@dimen/content_padding_small"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"
android:text="90°" />
</LinearLayout>
<SeekBar
android:id="@+id/angle_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="90"
android:paddingBottom="@dimen/content_padding" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View file

@ -11,6 +11,10 @@
Thx - Hardy Thx - Hardy
--> -->
<string name="shared_string_angle_param">Angle: %s°</string>
<string name="shared_string_angle">Angle</string>
<string name="recalc_angle_dialog_descr">Extra straight segment between my location and calculated route will be displayed until the route is recalculated</string>
<string name="recalc_angle_dialog_title">Minimum angle between my location and route</string>
<string name="navigation_notification_desc">Show system notification while navigation with navigation instructions.</string> <string name="navigation_notification_desc">Show system notification while navigation with navigation instructions.</string>
<string name="navigation_notification">Navigation notification</string> <string name="navigation_notification">Navigation notification</string>
<string name="shared_string_app_default_w_val">App Default (%s)</string> <string name="shared_string_app_default_w_val">App Default (%s)</string>

View file

@ -28,7 +28,6 @@ import android.support.annotation.AttrRes;
import android.support.annotation.ColorInt; import android.support.annotation.ColorInt;
import android.support.annotation.ColorRes; import android.support.annotation.ColorRes;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider; import android.support.v4.content.FileProvider;
import android.support.v4.text.TextUtilsCompat; import android.support.v4.text.TextUtilsCompat;
@ -342,18 +341,6 @@ public class AndroidUtils {
return res; return res;
} }
public static void setSnackbarTextColor(Snackbar snackbar, @ColorRes int colorId) {
View view = snackbar.getView();
TextView tv = (TextView) view.findViewById(android.support.design.R.id.snackbar_action);
tv.setTextColor(ContextCompat.getColor(view.getContext(), colorId));
}
public static void setSnackbarTextMaxLines(Snackbar snackbar, int maxLines) {
View view = snackbar.getView();
TextView tv = (TextView) view.findViewById(android.support.design.R.id.snackbar_text);
tv.setMaxLines(maxLines);
}
public static void setBackground(Context ctx, View view, boolean night, int lightResId, int darkResId) { public static void setBackground(Context ctx, View view, boolean night, int lightResId, int darkResId) {
Drawable drawable; Drawable drawable;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {

View file

@ -629,6 +629,7 @@ public class AppInitializer implements IProgress {
if (!customConfigs.isEmpty()) { if (!customConfigs.isEmpty()) {
app.getCustomRoutingConfigs().putAll(customConfigs); app.getCustomRoutingConfigs().putAll(customConfigs);
} }
app.avoidSpecificRoads.initRouteObjects(false);
callback.onRoutingFilesLoaded(); callback.onRoutingFilesLoaded();
} }
@ -739,7 +740,6 @@ public class AppInitializer implements IProgress {
notifyEvent(InitEvents.RESTORE_BACKUPS); notifyEvent(InitEvents.RESTORE_BACKUPS);
app.mapMarkersHelper.syncAllGroupsAsync(); app.mapMarkersHelper.syncAllGroupsAsync();
app.searchUICore.initSearchUICore(); app.searchUICore.initSearchUICore();
app.avoidSpecificRoads.initRouteObjects();
checkLiveUpdatesAlerts(); checkLiveUpdatesAlerts();

View file

@ -420,6 +420,14 @@ public class ApplicationMode {
app.getSettings().MAX_SPEED.setModeValue(this, defaultSpeed); app.getSettings().MAX_SPEED.setModeValue(this, defaultSpeed);
} }
public float getStrAngle() {
return app.getSettings().ROUTE_STRAIGHT_ANGLE.getModeValue(this);
}
public void setStrAngle(float angle) {
app.getSettings().ROUTE_STRAIGHT_ANGLE.setModeValue(this, angle);
}
public String getUserProfileName() { public String getUserProfileName() {
return app.getSettings().USER_PROFILE_NAME.getModeValue(this); return app.getSettings().USER_PROFILE_NAME.getModeValue(this);
} }

View file

@ -42,6 +42,7 @@ import net.osmand.plus.api.SettingsAPI;
import net.osmand.plus.api.SettingsAPI.SettingsEditor; import net.osmand.plus.api.SettingsAPI.SettingsEditor;
import net.osmand.plus.api.SettingsAPIImpl; import net.osmand.plus.api.SettingsAPIImpl;
import net.osmand.plus.dialogs.RateUsBottomSheetDialogFragment; import net.osmand.plus.dialogs.RateUsBottomSheetDialogFragment;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.helpers.SearchHistoryHelper; import net.osmand.plus.helpers.SearchHistoryHelper;
import net.osmand.plus.mapillary.MapillaryPlugin; import net.osmand.plus.mapillary.MapillaryPlugin;
import net.osmand.plus.mapmarkers.CoordinateInputFormats.Format; import net.osmand.plus.mapmarkers.CoordinateInputFormats.Format;
@ -2627,6 +2628,8 @@ public class OsmandSettings {
private static final String IMPASSABLE_ROAD_POINTS = "impassable_road_points"; private static final String IMPASSABLE_ROAD_POINTS = "impassable_road_points";
private static final String IMPASSABLE_ROADS_DESCRIPTIONS = "impassable_roads_descriptions"; private static final String IMPASSABLE_ROADS_DESCRIPTIONS = "impassable_roads_descriptions";
private static final String IMPASSABLE_ROADS_IDS = "impassable_roads_ids";
private static final String IMPASSABLE_ROADS_APP_MODE_KEYS = "impassable_roads_app_mode_keys";
private ImpassableRoadsStorage mImpassableRoadsStorage = new ImpassableRoadsStorage(); private ImpassableRoadsStorage mImpassableRoadsStorage = new ImpassableRoadsStorage();
public void backupPointToStart() { public void backupPointToStart() {
@ -2796,9 +2799,184 @@ public class OsmandSettings {
} }
private class ImpassableRoadsStorage extends MapPointsStorage { private class ImpassableRoadsStorage extends MapPointsStorage {
protected String roadsIdsKey;
protected String appModeKey;
public ImpassableRoadsStorage() { public ImpassableRoadsStorage() {
pointsKey = IMPASSABLE_ROAD_POINTS; pointsKey = IMPASSABLE_ROAD_POINTS;
descriptionsKey = IMPASSABLE_ROADS_DESCRIPTIONS; descriptionsKey = IMPASSABLE_ROADS_DESCRIPTIONS;
roadsIdsKey = IMPASSABLE_ROADS_IDS;
appModeKey = IMPASSABLE_ROADS_APP_MODE_KEYS;
}
public List<Long> getRoadIds(int size) {
List<Long> list = new ArrayList<>();
String roadIds = settingsAPI.getString(globalPreferences, roadsIdsKey, "");
if (roadIds.trim().length() > 0) {
StringTokenizer tok = new StringTokenizer(roadIds, ",");
while (tok.hasMoreTokens() && list.size() <= size) {
list.add(Long.parseLong(tok.nextToken()));
}
}
while (list.size() < size) {
list.add(0L);
}
return list;
}
public List<String> getAppModeKeys(int size) {
List<String> list = new ArrayList<>();
String roadIds = settingsAPI.getString(globalPreferences, appModeKey, "");
if (roadIds.trim().length() > 0) {
StringTokenizer tok = new StringTokenizer(roadIds, ",");
while (tok.hasMoreTokens() && list.size() <= size) {
list.add(tok.nextToken());
}
}
while (list.size() < size) {
list.add("");
}
return list;
}
public List<AvoidRoadInfo> getImpassableRoadsInfo() {
List<LatLon> points = getPoints();
List<Long> roadIds = getRoadIds(points.size());
List<String> appModeKeys = getAppModeKeys(points.size());
List<String> descriptions = getPointDescriptions(points.size());
List<AvoidRoadInfo> avoidRoadsInfo = new ArrayList<>();
for (int i = 0; i < points.size(); i++) {
LatLon latLon = points.get(i);
PointDescription description = PointDescription.deserializeFromString(descriptions.get(i), null);
AvoidRoadInfo avoidRoadInfo = new AvoidRoadInfo();
avoidRoadInfo.id = roadIds.get(i);
avoidRoadInfo.latitude = latLon.getLatitude();
avoidRoadInfo.longitude = latLon.getLongitude();
avoidRoadInfo.name = description.getName();
avoidRoadInfo.appModeKey = appModeKeys.get(i);
avoidRoadsInfo.add(avoidRoadInfo);
}
return avoidRoadsInfo;
}
public boolean addImpassableRoadInfo(AvoidRoadInfo avoidRoadInfo) {
List<LatLon> points = getPoints();
List<Long> roadIds = getRoadIds(points.size());
List<String> appModeKeys = getAppModeKeys(points.size());
List<String> descriptions = getPointDescriptions(points.size());
roadIds.add(0, avoidRoadInfo.id);
points.add(0, new LatLon(avoidRoadInfo.latitude, avoidRoadInfo.longitude));
appModeKeys.add(0, avoidRoadInfo.appModeKey);
descriptions.add(0, PointDescription.serializeToString(new PointDescription("", avoidRoadInfo.name)));
return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys);
}
public boolean updateImpassableRoadInfo(AvoidRoadInfo avoidRoadInfo) {
List<LatLon> points = getPoints();
int index = points.indexOf(new LatLon(avoidRoadInfo.latitude, avoidRoadInfo.longitude));
if (index != -1) {
List<Long> roadIds = getRoadIds(points.size());
List<String> appModeKeys = getAppModeKeys(points.size());
List<String> descriptions = getPointDescriptions(points.size());
roadIds.set(index, avoidRoadInfo.id);
appModeKeys.set(index, avoidRoadInfo.appModeKey);
descriptions.set(index, PointDescription.serializeToString(new PointDescription("", avoidRoadInfo.name)));
return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys);
}
return false;
}
@Override
public boolean deletePoint(int index) {
List<LatLon> points = getPoints();
List<Long> roadIds = getRoadIds(points.size());
List<String> appModeKeys = getAppModeKeys(points.size());
List<String> descriptions = getPointDescriptions(points.size());
if (index < points.size()) {
points.remove(index);
roadIds.remove(index);
appModeKeys.remove(index);
descriptions.remove(index);
return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys);
}
return false;
}
@Override
public boolean deletePoint(LatLon latLon) {
List<LatLon> points = getPoints();
List<Long> roadIds = getRoadIds(points.size());
List<String> appModeKeys = getAppModeKeys(points.size());
List<String> descriptions = getPointDescriptions(points.size());
int index = points.indexOf(latLon);
if (index != -1) {
points.remove(index);
roadIds.remove(index);
appModeKeys.remove(index);
descriptions.remove(index);
return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys);
}
return false;
}
@Override
public boolean movePoint(LatLon latLonEx, LatLon latLonNew) {
List<LatLon> points = getPoints();
List<Long> roadIds = getRoadIds(points.size());
List<String> appModeKeys = getAppModeKeys(points.size());
List<String> descriptions = getPointDescriptions(points.size());
int i = points.indexOf(latLonEx);
if (i != -1) {
points.set(i, latLonNew);
return saveAvoidRoadData(points, descriptions, roadIds, appModeKeys);
} else {
return false;
}
}
public boolean saveAvoidRoadData(List<LatLon> points, List<String> descriptions,
List<Long> roadIds, List<String> appModeKeys) {
return savePoints(points, descriptions) && saveRoadIds(roadIds) && saveAppModeKeys(appModeKeys);
}
public boolean saveRoadIds(List<Long> roadIds) {
StringBuilder stringBuilder = new StringBuilder();
Iterator<Long> iterator = roadIds.iterator();
while (iterator.hasNext()) {
stringBuilder.append(iterator.next());
if (iterator.hasNext()) {
stringBuilder.append(",");
}
}
return settingsAPI.edit(globalPreferences)
.putString(roadsIdsKey, stringBuilder.toString())
.commit();
}
public boolean saveAppModeKeys(List<String> appModeKeys) {
StringBuilder stringBuilder = new StringBuilder();
Iterator<String> iterator = appModeKeys.iterator();
while (iterator.hasNext()) {
stringBuilder.append(iterator.next());
if (iterator.hasNext()) {
stringBuilder.append(",");
}
}
return settingsAPI.edit(globalPreferences)
.putString(appModeKey, stringBuilder.toString())
.commit();
} }
} }
@ -2989,11 +3167,16 @@ public class OsmandSettings {
return settingsAPI.edit(globalPreferences).putInt(POINT_NAVIGATE_ROUTE, NAVIGATE).commit(); return settingsAPI.edit(globalPreferences).putInt(POINT_NAVIGATE_ROUTE, NAVIGATE).commit();
} }
public List<LatLon> getImpassableRoadPoints() { public List<AvoidRoadInfo> getImpassableRoadPoints() {
return mImpassableRoadsStorage.getPoints(); return mImpassableRoadsStorage.getImpassableRoadsInfo();
} }
public boolean addImpassableRoad(double latitude, double longitude) {
return mImpassableRoadsStorage.insertPoint(latitude, longitude, null, 0); public boolean addImpassableRoad(AvoidRoadInfo avoidRoadInfo) {
return mImpassableRoadsStorage.addImpassableRoadInfo(avoidRoadInfo);
}
public boolean updateImpassableRoadInfo(AvoidRoadInfo avoidRoadInfo) {
return mImpassableRoadsStorage.updateImpassableRoadInfo(avoidRoadInfo);
} }
public boolean removeImpassableRoad(int index) { public boolean removeImpassableRoad(int index) {

View file

@ -15,6 +15,7 @@ import android.support.annotation.ColorInt;
import android.support.annotation.ColorRes; import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes; import android.support.annotation.DrawableRes;
import android.support.annotation.StringRes; import android.support.annotation.StringRes;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v4.text.TextUtilsCompat; import android.support.v4.text.TextUtilsCompat;
@ -343,6 +344,40 @@ public class UiUtilities {
return screenOrientation; return screenOrientation;
} }
public static void setupSnackbar(Snackbar snackbar, boolean nightMode) {
setupSnackbar(snackbar, nightMode, null, null, null, null);
}
public static void setupSnackbar(Snackbar snackbar, boolean nightMode, Integer maxLines) {
setupSnackbar(snackbar, nightMode, null, null, null, maxLines);
}
public static void setupSnackbar(Snackbar snackbar, boolean nightMode, @ColorRes Integer backgroundColor,
@ColorRes Integer messageColor, @ColorRes Integer actionColor, Integer maxLines) {
if (snackbar == null) {
return;
}
View view = snackbar.getView();
Context ctx = view.getContext();
TextView tvMessage = (TextView) view.findViewById(android.support.design.R.id.snackbar_text);
TextView tvAction = (TextView) view.findViewById(android.support.design.R.id.snackbar_action);
if (messageColor == null) {
messageColor = nightMode ? R.color.text_color_primary_dark : R.color.text_color_primary_light;
}
tvMessage.setTextColor(ContextCompat.getColor(ctx, messageColor));
if (actionColor == null) {
actionColor = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
}
tvAction.setTextColor(ContextCompat.getColor(ctx, actionColor));
if (maxLines != null) {
tvMessage.setMaxLines(maxLines);
}
if (backgroundColor == null) {
backgroundColor = nightMode ? R.color.list_background_color_dark : R.color.list_background_color_light;
}
view.setBackgroundColor(ContextCompat.getColor(ctx, backgroundColor));
}
public static void setupLayoutDirection(View layout) { public static void setupLayoutDirection(View layout) {
Context ctx = layout.getContext(); Context ctx = layout.getContext();
Locale currentLocale = ctx.getResources().getConfiguration().locale; Locale currentLocale = ctx.getResources().getConfiguration().locale;

View file

@ -264,7 +264,7 @@ public class ContributionVersionActivity extends OsmandListActivity {
StringBuilder format = new StringBuilder(); StringBuilder format = new StringBuilder();
format.append(AndroidUtils.formatDateTime(getMyApplication(), build.date.getTime()))/*.append(" : ").append(build.size).append(" MB")*/; format.append(AndroidUtils.formatDateTime(getMyApplication(), build.date.getTime()))/*.append(" : ").append(build.size).append(" MB")*/;
description.setText(format.toString()); description.setText(format.toString());
int color = getResources().getColor(R.color.color_unknown); int color = getResources().getColor(R.color.text_color_secondary_dark);
if (currentInstalledDate != null) { if (currentInstalledDate != null) {
if (currentInstalledDate.before(build.date)) { if (currentInstalledDate.before(build.date)) {
color = getResources().getColor(R.color.color_update); color = getResources().getColor(R.color.color_update);

View file

@ -426,7 +426,7 @@ public class MapActivityActions implements DialogProvider {
mapActivity.getContextMenu().close(); mapActivity.getContextMenu().close();
MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), new LatLon(latitude, longitude)); MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), new LatLon(latitude, longitude));
} else if (standardId == R.string.avoid_road) { } else if (standardId == R.string.avoid_road) {
getMyApplication().getAvoidSpecificRoads().addImpassableRoad(mapActivity, new LatLon(latitude, longitude), true, false); getMyApplication().getAvoidSpecificRoads().addImpassableRoad(mapActivity, new LatLon(latitude, longitude), true, false, null);
} }
} }
}); });

View file

@ -118,6 +118,7 @@ public class DownloadIndexesThread {
if (app.getDownloadService() != null) { if (app.getDownloadService() != null) {
app.getDownloadService().stopService(app); app.getDownloadService().stopService(app);
} }
app.getAvoidSpecificRoads().initRouteObjects(true);
} }
public void initSettingsFirstMap(WorldRegion reg) { public void initSettingsFirstMap(WorldRegion reg) {

View file

@ -50,32 +50,44 @@ public class AvoidSpecificRoads {
private OsmandApplication app; private OsmandApplication app;
private Map<LatLon, RouteDataObject> impassableRoads = new LinkedHashMap<>(); private Map<LatLon, AvoidRoadInfo> impassableRoads = new LinkedHashMap<>();
public AvoidSpecificRoads(final OsmandApplication app) { public AvoidSpecificRoads(final OsmandApplication app) {
this.app = app; this.app = app;
for (LatLon latLon : app.getSettings().getImpassableRoadPoints()) { for (AvoidRoadInfo avoidRoadInfo : app.getSettings().getImpassableRoadPoints()) {
impassableRoads.put(latLon, null); impassableRoads.put(new LatLon(avoidRoadInfo.latitude, avoidRoadInfo.longitude), avoidRoadInfo);
} }
} }
public Map<LatLon, RouteDataObject> getImpassableRoads() { public Map<LatLon, AvoidRoadInfo> getImpassableRoads() {
return impassableRoads; return impassableRoads;
} }
public void initRouteObjects() { public void initRouteObjects(boolean force) {
for (LatLon latLon : impassableRoads.keySet()) { for (Map.Entry<LatLon, AvoidRoadInfo> entry : impassableRoads.entrySet()) {
addImpassableRoad(null, latLon, false, true); AvoidRoadInfo roadInfo = entry.getValue();
if (roadInfo.id != 0) {
for (RoutingConfiguration.Builder builder : app.getAllRoutingConfigs()) {
if (force) {
builder.removeImpassableRoad(roadInfo.id);
} else {
builder.addImpassableRoad(roadInfo.id);
}
}
}
if (force || roadInfo.id == 0) {
addImpassableRoad(null, entry.getKey(), false, true, roadInfo.appModeKey);
}
} }
} }
private ArrayAdapter<LatLon> createAdapter(MapActivity mapActivity, boolean nightMode) { private ArrayAdapter<AvoidRoadInfo> createAdapter(MapActivity mapActivity, boolean nightMode) {
final ArrayList<LatLon> points = new ArrayList<>(impassableRoads.keySet()); final ArrayList<AvoidRoadInfo> points = new ArrayList<>(impassableRoads.values());
final LatLon mapLocation = mapActivity.getMapLocation(); final LatLon mapLocation = mapActivity.getMapLocation();
final LayoutInflater inflater = UiUtilities.getInflater(mapActivity, nightMode); final LayoutInflater inflater = UiUtilities.getInflater(mapActivity, nightMode);
Context themedContext = UiUtilities.getThemedContext(mapActivity, nightMode); Context themedContext = UiUtilities.getThemedContext(mapActivity, nightMode);
return new ArrayAdapter<LatLon>(themedContext, R.layout.waypoint_reached, R.id.title, points) { return new ArrayAdapter<AvoidRoadInfo>(themedContext, R.layout.waypoint_reached, R.id.title, points) {
@NonNull @NonNull
@Override @Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent) { public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
@ -83,12 +95,15 @@ public class AvoidSpecificRoads {
if (v == null || v.findViewById(R.id.info_close) == null) { if (v == null || v.findViewById(R.id.info_close) == null) {
v = inflater.inflate(R.layout.waypoint_reached, parent, false); v = inflater.inflate(R.layout.waypoint_reached, parent, false);
} }
final LatLon item = getItem(position); final AvoidRoadInfo item = getItem(position);
v.findViewById(R.id.all_points).setVisibility(View.GONE); v.findViewById(R.id.all_points).setVisibility(View.GONE);
((ImageView) v.findViewById(R.id.waypoint_icon)) ((ImageView) v.findViewById(R.id.waypoint_icon))
.setImageDrawable(getIcon(R.drawable.ic_action_road_works_dark)); .setImageDrawable(getIcon(R.drawable.ic_action_road_works_dark));
((TextView) v.findViewById(R.id.waypoint_dist)).setText(getDist(mapLocation, item));
((TextView) v.findViewById(R.id.waypoint_text)).setText(getText(item)); LatLon latLon = item != null ? new LatLon(item.latitude, item.longitude) : null;
String name = item != null ? item.name : app.getString(R.string.shared_string_road);
((TextView) v.findViewById(R.id.waypoint_dist)).setText(getDist(mapLocation, latLon));
((TextView) v.findViewById(R.id.waypoint_text)).setText(name);
ImageButton remove = (ImageButton) v.findViewById(R.id.info_close); ImageButton remove = (ImageButton) v.findViewById(R.id.info_close);
remove.setVisibility(View.VISIBLE); remove.setVisibility(View.VISIBLE);
remove.setImageDrawable(getIcon(R.drawable.ic_action_remove_dark)); remove.setImageDrawable(getIcon(R.drawable.ic_action_remove_dark));
@ -117,25 +132,15 @@ public class AvoidSpecificRoads {
public String getText(@Nullable LatLon point) { public String getText(@Nullable LatLon point) {
if (point != null) { if (point != null) {
RouteDataObject obj = impassableRoads.get(point); AvoidRoadInfo obj = impassableRoads.get(point);
if (obj != null) { if (obj != null && !TextUtils.isEmpty(obj.name)) {
String locale = app.getSettings().MAP_PREFERRED_LOCALE.get(); return obj.name;
boolean transliterate = app.getSettings().MAP_TRANSLITERATE_NAMES.get();
String name = RoutingHelper.formatStreetName(
obj.getName(locale, transliterate),
obj.getRef(locale, transliterate, true),
obj.getDestinationName(locale, transliterate, true),
app.getString(R.string.towards)
);
if (!TextUtils.isEmpty(name)) {
return name;
}
} }
} }
return app.getString(R.string.shared_string_road); return app.getString(R.string.shared_string_road);
} }
public String getText(@Nullable RouteDataObject obj) { public String getRoadName(@Nullable RouteDataObject obj) {
if (obj != null) { if (obj != null) {
String locale = app.getSettings().MAP_PREFERRED_LOCALE.get(); String locale = app.getSettings().MAP_PREFERRED_LOCALE.get();
boolean transliterate = app.getSettings().MAP_TRANSLITERATE_NAMES.get(); boolean transliterate = app.getSettings().MAP_TRANSLITERATE_NAMES.get();
@ -161,15 +166,15 @@ public class AvoidSpecificRoads {
public void removeImpassableRoad(LatLon latLon) { public void removeImpassableRoad(LatLon latLon) {
app.getSettings().removeImpassableRoad(latLon); app.getSettings().removeImpassableRoad(latLon);
RouteDataObject obj = impassableRoads.remove(latLon); AvoidRoadInfo obj = impassableRoads.remove(latLon);
if (obj != null) { if (obj != null) {
for (RoutingConfiguration.Builder builder : app.getAllRoutingConfigs()) { for (RoutingConfiguration.Builder builder : app.getAllRoutingConfigs()) {
builder.removeImpassableRoad(obj); builder.removeImpassableRoad(obj.id);
} }
} }
} }
public void removeImpassableRoad(RouteDataObject obj) { public void removeImpassableRoad(AvoidRoadInfo obj) {
removeImpassableRoad(getLocation(obj)); removeImpassableRoad(getLocation(obj));
} }
@ -182,13 +187,13 @@ public class AvoidSpecificRoads {
if (impassableRoads.isEmpty()) { if (impassableRoads.isEmpty()) {
bld.setMessage(R.string.avoid_roads_msg); bld.setMessage(R.string.avoid_roads_msg);
} else { } else {
final ArrayAdapter<LatLon> listAdapter = createAdapter(mapActivity, nightMode); final ArrayAdapter<AvoidRoadInfo> listAdapter = createAdapter(mapActivity, nightMode);
bld.setAdapter(listAdapter, new DialogInterface.OnClickListener() { bld.setAdapter(listAdapter, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
LatLon point = listAdapter.getItem(which); AvoidRoadInfo point = listAdapter.getItem(which);
if (point != null) { if (point != null) {
showOnMap(mapActivity, point.getLatitude(), point.getLongitude(), getText(point)); showOnMap(mapActivity, point.latitude, point.longitude, point.name);
} }
dialog.dismiss(); dialog.dismiss();
} }
@ -210,20 +215,23 @@ public class AvoidSpecificRoads {
cm.setSelectOnMap(new CallbackWithObject<LatLon>() { cm.setSelectOnMap(new CallbackWithObject<LatLon>() {
@Override @Override
public boolean processResult(LatLon result) { public boolean processResult(LatLon result) {
addImpassableRoad(mapActivity, result, true, false); addImpassableRoad(mapActivity, result, true, false, null);
return true; return true;
} }
}); });
} }
public void addImpassableRoad(@Nullable final MapActivity mapActivity, public void addImpassableRoad(@Nullable final MapActivity mapActivity,
@NonNull final LatLon loc, @NonNull final LatLon loc,
final boolean showDialog, final boolean showDialog,
final boolean skipWritingSettings) { final boolean skipWritingSettings,
@Nullable final String appModeKey) {
final Location ll = new Location(""); final Location ll = new Location("");
ll.setLatitude(loc.getLatitude()); ll.setLatitude(loc.getLatitude());
ll.setLongitude(loc.getLongitude()); ll.setLongitude(loc.getLongitude());
ApplicationMode appMode = app.getRoutingHelper().getAppMode();
ApplicationMode defaultAppMode = app.getRoutingHelper().getAppMode();
final ApplicationMode appMode = appModeKey != null ? ApplicationMode.valueOfStringKey(appModeKey, defaultAppMode) : defaultAppMode;
List<RouteSegmentResult> roads = app.getRoutingHelper().getRoute().getOriginalRoute(); List<RouteSegmentResult> roads = app.getRoutingHelper().getRoute().getOriginalRoute();
if (mapActivity != null && roads != null) { if (mapActivity != null && roads != null) {
@ -236,9 +244,12 @@ public class AvoidSpecificRoads {
LatLon newLoc = new LatLon(MapUtils.get31LatitudeY((int) point.y), MapUtils.get31LongitudeX((int) point.x)); LatLon newLoc = new LatLon(MapUtils.get31LatitudeY((int) point.y), MapUtils.get31LongitudeX((int) point.x));
ll.setLatitude(newLoc.getLatitude()); ll.setLatitude(newLoc.getLatitude());
ll.setLongitude(newLoc.getLongitude()); ll.setLongitude(newLoc.getLongitude());
addImpassableRoadInternal(roads.get(searchResult.getRoadIndex()).getObject(), ll, showDialog, mapActivity, newLoc);
RouteDataObject object = roads.get(searchResult.getRoadIndex()).getObject();
AvoidRoadInfo avoidRoadInfo = getAvoidRoadInfoForDataObject(object, newLoc.getLatitude(), newLoc.getLongitude(), appMode.getStringKey());
addImpassableRoadInternal(avoidRoadInfo, showDialog, mapActivity, newLoc);
if (!skipWritingSettings) { if (!skipWritingSettings) {
app.getSettings().addImpassableRoad(newLoc.getLatitude(), newLoc.getLongitude()); app.getSettings().addImpassableRoad(avoidRoadInfo);
} }
return; return;
} }
@ -252,7 +263,8 @@ public class AvoidSpecificRoads {
Toast.makeText(mapActivity, R.string.error_avoid_specific_road, Toast.LENGTH_LONG).show(); Toast.makeText(mapActivity, R.string.error_avoid_specific_road, Toast.LENGTH_LONG).show();
} }
} else { } else {
addImpassableRoadInternal(object, ll, showDialog, mapActivity, loc); AvoidRoadInfo avoidRoadInfo = getAvoidRoadInfoForDataObject(object, ll.getLatitude(), ll.getLongitude(), appMode.getStringKey());
addImpassableRoadInternal(avoidRoadInfo, showDialog, mapActivity, loc);
} }
return true; return true;
} }
@ -264,19 +276,22 @@ public class AvoidSpecificRoads {
}); });
if (!skipWritingSettings) { if (!skipWritingSettings) {
app.getSettings().addImpassableRoad(loc.getLatitude(), loc.getLongitude()); AvoidRoadInfo avoidRoadInfo = getAvoidRoadInfoForDataObject(null, loc.getLatitude(), loc.getLongitude(), appMode.getStringKey());
app.getSettings().addImpassableRoad(avoidRoadInfo);
} }
} }
public void replaceImpassableRoad(final MapActivity activity, public void replaceImpassableRoad(final MapActivity activity,
final RouteDataObject currentObject, final AvoidRoadInfo currentObject,
final LatLon newLoc, final LatLon newLoc,
final boolean showDialog, final boolean showDialog,
final AvoidSpecificRoadsCallback callback) { final AvoidSpecificRoadsCallback callback) {
final Location ll = new Location(""); final Location ll = new Location("");
ll.setLatitude(newLoc.getLatitude()); ll.setLatitude(newLoc.getLatitude());
ll.setLongitude(newLoc.getLongitude()); ll.setLongitude(newLoc.getLongitude());
ApplicationMode appMode = app.getRoutingHelper().getAppMode();
ApplicationMode defaultAppMode = app.getRoutingHelper().getAppMode();
final ApplicationMode appMode = ApplicationMode.valueOfStringKey(currentObject.appModeKey, defaultAppMode);
app.getLocationProvider().getRouteSegment(ll, appMode, false, new ResultMatcher<RouteDataObject>() { app.getLocationProvider().getRouteSegment(ll, appMode, false, new ResultMatcher<RouteDataObject>() {
@ -292,12 +307,13 @@ public class AvoidSpecificRoads {
app.getSettings().moveImpassableRoad(oldLoc, newLoc); app.getSettings().moveImpassableRoad(oldLoc, newLoc);
impassableRoads.remove(oldLoc); impassableRoads.remove(oldLoc);
for (RoutingConfiguration.Builder builder : app.getAllRoutingConfigs()) { for (RoutingConfiguration.Builder builder : app.getAllRoutingConfigs()) {
builder.removeImpassableRoad(currentObject); builder.removeImpassableRoad(currentObject.id);
} }
addImpassableRoadInternal(object, ll, showDialog, activity, newLoc); AvoidRoadInfo avoidRoadInfo = getAvoidRoadInfoForDataObject(object, newLoc.getLatitude(), newLoc.getLongitude(), appMode.getStringKey());
addImpassableRoadInternal(avoidRoadInfo, showDialog, activity, newLoc);
if (callback != null) { if (callback != null) {
callback.onAddImpassableRoad(true, object); callback.onAddImpassableRoad(true, avoidRoadInfo);
} }
} }
return true; return true;
@ -310,19 +326,19 @@ public class AvoidSpecificRoads {
}); });
} }
private void addImpassableRoadInternal(@NonNull RouteDataObject object, private void addImpassableRoadInternal(@NonNull AvoidRoadInfo avoidRoadInfo,
@NonNull Location ll,
boolean showDialog, boolean showDialog,
@Nullable MapActivity activity, @Nullable MapActivity activity,
@NonNull LatLon loc) { @NonNull LatLon loc) {
boolean roadAdded = false; boolean roadAdded = false;
for (RoutingConfiguration.Builder builder : app.getAllRoutingConfigs()) { for (RoutingConfiguration.Builder builder : app.getAllRoutingConfigs()) {
roadAdded |= builder.addImpassableRoad(object, ll); roadAdded |= builder.addImpassableRoad(avoidRoadInfo.id);
} }
if (roadAdded) { if (roadAdded) {
impassableRoads.put(loc, object); app.getSettings().updateImpassableRoadInfo(avoidRoadInfo);
impassableRoads.put(loc, avoidRoadInfo);
} else { } else {
LatLon location = getLocation(object); LatLon location = getLocation(avoidRoadInfo);
if (location != null) { if (location != null) {
app.getSettings().removeImpassableRoad(location); app.getSettings().removeImpassableRoad(location);
} }
@ -347,21 +363,40 @@ public class AvoidSpecificRoads {
MapActivity.launchMapActivityMoveToTop(ctx); MapActivity.launchMapActivityMoveToTop(ctx);
} }
public LatLon getLocation(RouteDataObject object) { public LatLon getLocation(AvoidRoadInfo avoidRoadInfo) {
Location location = null;
for (RoutingConfiguration.Builder builder : app.getAllRoutingConfigs()) { for (RoutingConfiguration.Builder builder : app.getAllRoutingConfigs()) {
location = builder.getImpassableRoadLocations().get(object.getId()); if (builder.getImpassableRoadLocations().contains(avoidRoadInfo.id)) {
if (location != null) { return new LatLon(avoidRoadInfo.latitude, avoidRoadInfo.longitude);
break;
} }
} }
return location == null ? null : new LatLon(location.getLatitude(), location.getLongitude()); return null;
} }
public interface AvoidSpecificRoadsCallback { public interface AvoidSpecificRoadsCallback {
void onAddImpassableRoad(boolean success, RouteDataObject newObject); void onAddImpassableRoad(boolean success, AvoidRoadInfo avoidRoadInfo);
boolean isCancelled(); boolean isCancelled();
} }
private AvoidRoadInfo getAvoidRoadInfoForDataObject(@Nullable RouteDataObject object, double lat, double lon, String appModeKey) {
AvoidRoadInfo avoidRoadInfo = impassableRoads.get(new LatLon(lat, lon));
if (avoidRoadInfo == null) {
avoidRoadInfo = new AvoidRoadInfo();
}
avoidRoadInfo.id = object != null ? object.id : 0;
avoidRoadInfo.latitude = lat;
avoidRoadInfo.longitude = lon;
avoidRoadInfo.appModeKey = appModeKey;
avoidRoadInfo.name = getRoadName(object);
return avoidRoadInfo;
}
public static class AvoidRoadInfo {
public long id;
public double latitude;
public double longitude;
public String name;
public String appModeKey;
}
} }

View file

@ -22,7 +22,6 @@ import net.osmand.PlatformUtil;
import net.osmand.aidl.AidlMapPointWrapper; import net.osmand.aidl.AidlMapPointWrapper;
import net.osmand.binary.BinaryMapDataObject; import net.osmand.binary.BinaryMapDataObject;
import net.osmand.binary.BinaryMapIndexReader.TagValuePair; import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
import net.osmand.binary.RouteDataObject;
import net.osmand.data.Amenity; import net.osmand.data.Amenity;
import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
@ -45,6 +44,7 @@ import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.download.DownloadIndexesThread; import net.osmand.plus.download.DownloadIndexesThread;
import net.osmand.plus.download.DownloadValidationManager; import net.osmand.plus.download.DownloadValidationManager;
import net.osmand.plus.download.IndexItem; import net.osmand.plus.download.IndexItem;
import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.helpers.SearchHistoryHelper; import net.osmand.plus.helpers.SearchHistoryHelper;
import net.osmand.plus.mapcontextmenu.MenuBuilder.CollapsableView; import net.osmand.plus.mapcontextmenu.MenuBuilder.CollapsableView;
import net.osmand.plus.mapcontextmenu.MenuBuilder.CollapseExpandListener; import net.osmand.plus.mapcontextmenu.MenuBuilder.CollapseExpandListener;
@ -220,8 +220,8 @@ public abstract class MenuController extends BaseMenuController implements Colla
} else if (pointDescription.isMyLocation()) { } else if (pointDescription.isMyLocation()) {
menuController = new MyLocationMenuController(mapActivity, pointDescription); menuController = new MyLocationMenuController(mapActivity, pointDescription);
} }
} else if (object instanceof RouteDataObject) { } else if (object instanceof AvoidSpecificRoads.AvoidRoadInfo) {
menuController = new ImpassibleRoadsMenuController(mapActivity, pointDescription, (RouteDataObject) object); menuController = new ImpassibleRoadsMenuController(mapActivity, pointDescription, (AvoidSpecificRoads.AvoidRoadInfo) object);
} else if (object instanceof RenderedObject) { } else if (object instanceof RenderedObject) {
menuController = new RenderedObjectMenuController(mapActivity, pointDescription, (RenderedObject) object); menuController = new RenderedObjectMenuController(mapActivity, pointDescription, (RenderedObject) object);
} else if (object instanceof MapillaryImage) { } else if (object instanceof MapillaryImage) {

View file

@ -4,24 +4,24 @@ import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import net.osmand.binary.RouteDataObject;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.mapcontextmenu.MenuBuilder; import net.osmand.plus.mapcontextmenu.MenuBuilder;
import net.osmand.plus.mapcontextmenu.MenuController; import net.osmand.plus.mapcontextmenu.MenuController;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
public class ImpassibleRoadsMenuController extends MenuController { public class ImpassibleRoadsMenuController extends MenuController {
private RouteDataObject route; private AvoidRoadInfo avoidRoadInfo;
public ImpassibleRoadsMenuController(@NonNull MapActivity mapActivity, public ImpassibleRoadsMenuController(@NonNull MapActivity mapActivity,
@NonNull PointDescription pointDescription, @NonNull PointDescription pointDescription,
@NonNull RouteDataObject route) { @NonNull AvoidRoadInfo avoidRoadInfo) {
super(new MenuBuilder(mapActivity), pointDescription, mapActivity); super(new MenuBuilder(mapActivity), pointDescription, mapActivity);
this.route = route; this.avoidRoadInfo = avoidRoadInfo;
final OsmandApplication app = mapActivity.getMyApplication(); final OsmandApplication app = mapActivity.getMyApplication();
leftTitleButtonController = new TitleButtonController() { leftTitleButtonController = new TitleButtonController() {
@Override @Override
@ -29,7 +29,7 @@ public class ImpassibleRoadsMenuController extends MenuController {
MapActivity activity = getMapActivity(); MapActivity activity = getMapActivity();
if (activity != null) { if (activity != null) {
app.getAvoidSpecificRoads().removeImpassableRoad( app.getAvoidSpecificRoads().removeImpassableRoad(
ImpassibleRoadsMenuController.this.route); ImpassibleRoadsMenuController.this.avoidRoadInfo);
RoutingHelper rh = app.getRoutingHelper(); RoutingHelper rh = app.getRoutingHelper();
if (rh.isRouteCalculated() || rh.isRouteBeingCalculated()) { if (rh.isRouteCalculated() || rh.isRouteBeingCalculated()) {
rh.recalculateRouteDueToSettingsChange(); rh.recalculateRouteDueToSettingsChange();
@ -44,12 +44,12 @@ public class ImpassibleRoadsMenuController extends MenuController {
@Override @Override
protected void setObject(Object object) { protected void setObject(Object object) {
route = (RouteDataObject) object; avoidRoadInfo = (AvoidRoadInfo) object;
} }
@Override @Override
protected Object getObject() { protected Object getObject() {
return route; return avoidRoadInfo;
} }
@NonNull @NonNull

View file

@ -33,7 +33,7 @@ public class PointDescriptionMenuController extends MenuController {
MapActivity activity = getMapActivity(); MapActivity activity = getMapActivity();
if (activity != null) { if (activity != null) {
AvoidSpecificRoads roads = activity.getMyApplication().getAvoidSpecificRoads(); AvoidSpecificRoads roads = activity.getMyApplication().getAvoidSpecificRoads();
roads.addImpassableRoad(activity, getLatLon(), false, false); roads.addImpassableRoad(activity, getLatLon(), false, false, null);
} }
} }
}; };

View file

@ -65,6 +65,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.UiUtilities;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.activities.SavingTrackHelper;
import net.osmand.plus.activities.TrackActivity; import net.osmand.plus.activities.TrackActivity;
@ -1092,7 +1093,7 @@ public class CoordinateInputDialogFragment extends DialogFragment implements Osm
startActivity(intent); startActivity(intent);
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, R.color.active_color_primary_dark); UiUtilities.setupSnackbar(snackbar, !lightTheme);
snackbar.show(); snackbar.show();
} }
}; };
@ -1119,7 +1120,7 @@ public class CoordinateInputDialogFragment extends DialogFragment implements Osm
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, R.color.active_color_primary_dark); UiUtilities.setupSnackbar(snackbar, !lightTheme);
snackbar.show(); snackbar.show();
} }

View file

@ -33,6 +33,7 @@ import net.osmand.plus.MapMarkersHelper.OnGroupSyncedListener;
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.UiUtilities;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.TrackActivity; import net.osmand.plus.activities.TrackActivity;
import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment.OnPointsSavedListener; import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment.OnPointsSavedListener;
@ -449,7 +450,7 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
} }
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, R.color.active_color_primary_dark); UiUtilities.setupSnackbar(snackbar, !lightTheme);
snackbar.show(); snackbar.show();
} }
} }
@ -494,7 +495,7 @@ public class MapMarkersDialogFragment extends android.support.v4.app.DialogFragm
startActivity(intent); startActivity(intent);
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, R.color.active_color_primary_dark); UiUtilities.setupSnackbar(snackbar, !lightTheme);
snackbar.show(); snackbar.show();
} }
}; };

View file

@ -207,7 +207,7 @@ public class MapMarkersGroupsFragment extends Fragment implements OsmAndCompassL
updateAdapter(); updateAdapter();
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, R.color.active_color_primary_dark); UiUtilities.setupSnackbar(snackbar, night);
snackbar.show(); snackbar.show();
} }
} }

View file

@ -171,8 +171,7 @@ public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHel
} }
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, night ? R.color.active_color_primary_dark : R.color.active_color_primary_light); UiUtilities.setupSnackbar(snackbar, night);
snackbar.getView().setBackgroundColor(ContextCompat.getColor(app, night ? R.color.list_background_color_dark : R.color.list_background_color_light));
snackbar.show(); snackbar.show();
} }
} }

View file

@ -48,6 +48,7 @@ public class SelectWptCategoriesBottomSheetDialogFragment extends MenuBottomShee
if (gpxFile == null) { if (gpxFile == null) {
return; return;
} }
int activeColorResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
isUpdateMode = getArguments().getBoolean(UPDATE_CATEGORIES_KEY); isUpdateMode = getArguments().getBoolean(UPDATE_CATEGORIES_KEY);
List<String> categories = getArguments().getStringArrayList(ACTIVE_CATEGORIES_KEY); List<String> categories = getArguments().getStringArrayList(ACTIVE_CATEGORIES_KEY);
@ -58,6 +59,7 @@ public class SelectWptCategoriesBottomSheetDialogFragment extends MenuBottomShee
final BottomSheetItemWithCompoundButton[] selectAllItem = new BottomSheetItemWithCompoundButton[1]; final BottomSheetItemWithCompoundButton[] selectAllItem = new BottomSheetItemWithCompoundButton[1];
selectAllItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() selectAllItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
.setChecked(!isUpdateMode || categories!=null&&categories.size() == gpxFile.getPointsByCategories().size()) .setChecked(!isUpdateMode || categories!=null&&categories.size() == gpxFile.getPointsByCategories().size())
.setCompoundButtonColorId(activeColorResId)
.setDescription(getString(R.string.shared_string_total) + ": " + gpxFile.getPoints().size()) .setDescription(getString(R.string.shared_string_total) + ": " + gpxFile.getPoints().size())
.setIcon(getContentIcon(R.drawable.ic_action_group_select_all)) .setIcon(getContentIcon(R.drawable.ic_action_group_select_all))
.setTitle(getString(R.string.shared_string_select_all)) .setTitle(getString(R.string.shared_string_select_all))
@ -93,6 +95,7 @@ public class SelectWptCategoriesBottomSheetDialogFragment extends MenuBottomShee
} }
} }
}) })
.setCompoundButtonColorId(activeColorResId)
.setDescription(String.valueOf(pointsByCategories.get(category).size())) .setDescription(String.valueOf(pointsByCategories.get(category).size()))
.setIcon(getContentIcon(R.drawable.ic_action_folder)) .setIcon(getContentIcon(R.drawable.ic_action_folder))
.setTitle(category.equals("") ? getString(R.string.shared_string_waypoints) : category) .setTitle(category.equals("") ? getString(R.string.shared_string_waypoints) : category)

View file

@ -74,6 +74,7 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
ImageView markerImageViewToUpdate; ImageView markerImageViewToUpdate;
int drawableResToUpdate; int drawableResToUpdate;
int markerColor = MapMarker.getColorId(marker.colorIndex); int markerColor = MapMarker.getColorId(marker.colorIndex);
int actionIconColor = night ? R.color.icon_color_primary_dark : R.color.icon_color_primary_light;
LatLon markerLatLon = new LatLon(marker.getLatitude(), marker.getLongitude()); LatLon markerLatLon = new LatLon(marker.getLatitude(), marker.getLongitude());
final boolean displayedInWidget = pos < mapActivity.getMyApplication().getSettings().DISPLAYED_MARKERS_WIDGETS_COUNT.get(); final boolean displayedInWidget = pos < mapActivity.getMyApplication().getSettings().DISPLAYED_MARKERS_WIDGETS_COUNT.get();
if (showDirectionEnabled && displayedInWidget) { if (showDirectionEnabled && displayedInWidget) {
@ -98,7 +99,7 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
holder.title.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.text_color_primary_dark : R.color.text_color_primary_light)); holder.title.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.text_color_primary_dark : R.color.text_color_primary_light));
holder.divider.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.app_bar_color_dark : R.color.divider_color_light)); holder.divider.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.app_bar_color_dark : R.color.divider_color_light));
holder.optionsBtn.setBackgroundDrawable(mapActivity.getResources().getDrawable(night ? R.drawable.marker_circle_background_dark_with_inset : R.drawable.marker_circle_background_light_with_inset)); holder.optionsBtn.setBackgroundDrawable(mapActivity.getResources().getDrawable(night ? R.drawable.marker_circle_background_dark_with_inset : R.drawable.marker_circle_background_light_with_inset));
holder.optionsBtn.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_marker_passed, night ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light)); holder.optionsBtn.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_marker_passed, actionIconColor));
holder.iconReorder.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_reorder)); holder.iconReorder.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_reorder));
holder.description.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.icon_color_default_dark : R.color.icon_color_default_light)); holder.description.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.icon_color_default_dark : R.color.icon_color_default_light));
@ -162,8 +163,7 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
notifyDataSetChanged(); notifyDataSetChanged();
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, night ? R.color.active_color_primary_dark : R.color.active_color_primary_light); UiUtilities.setupSnackbar(snackbar, night);
snackbar.getView().setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.list_background_color_dark : R.color.list_background_color_light));
snackbar.show(); snackbar.show();
} }
}); });
@ -229,8 +229,7 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
notifyDataSetChanged(); notifyDataSetChanged();
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, night ? R.color.active_color_primary_dark : R.color.active_color_primary_light); UiUtilities.setupSnackbar(snackbar, night);
snackbar.getView().setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.list_background_color_dark : R.color.list_background_color_light));
snackbar.show(); snackbar.show();
} }

View file

@ -12,7 +12,6 @@ import android.view.ViewGroup;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.ImageView; import android.widget.ImageView;
import net.osmand.AndroidUtils;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.GPXUtilities; import net.osmand.GPXUtilities;
@ -272,6 +271,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
} }
ImageView markerImageViewToUpdate; ImageView markerImageViewToUpdate;
int drawableResToUpdate; int drawableResToUpdate;
int actionIconColor = night ? R.color.icon_color_primary_dark : R.color.icon_color_primary_light;
final boolean markerToHighlight = showDirectionMarkers.contains(marker); final boolean markerToHighlight = showDirectionMarkers.contains(marker);
if (showDirectionEnabled && markerToHighlight) { if (showDirectionEnabled && markerToHighlight) {
itemViewHolder.iconDirection.setVisibility(View.GONE); itemViewHolder.iconDirection.setVisibility(View.GONE);
@ -294,8 +294,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
itemViewHolder.title.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.text_color_primary_dark : R.color.text_color_primary_light)); itemViewHolder.title.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.text_color_primary_dark : R.color.text_color_primary_light));
itemViewHolder.divider.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.app_bar_color_dark : R.color.divider_color_light)); itemViewHolder.divider.setBackgroundColor(ContextCompat.getColor(mapActivity, night ? R.color.app_bar_color_dark : R.color.divider_color_light));
itemViewHolder.optionsBtn.setBackgroundDrawable(mapActivity.getResources().getDrawable(night ? R.drawable.marker_circle_background_dark_with_inset : R.drawable.marker_circle_background_light_with_inset)); itemViewHolder.optionsBtn.setBackgroundDrawable(mapActivity.getResources().getDrawable(night ? R.drawable.marker_circle_background_dark_with_inset : R.drawable.marker_circle_background_light_with_inset));
itemViewHolder.optionsBtn.setImageDrawable(iconsCache.getIcon(markerInHistory ? R.drawable.ic_action_reset_to_default_dark : R.drawable.ic_action_marker_passed, itemViewHolder.optionsBtn.setImageDrawable(iconsCache.getIcon(markerInHistory ? R.drawable.ic_action_reset_to_default_dark : R.drawable.ic_action_marker_passed, actionIconColor));
night ? R.color.icon_color_primary_dark : R.color.active_buttons_and_links_text_light));
itemViewHolder.description.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.icon_color_default_dark : R.color.icon_color_default_light)); itemViewHolder.description.setTextColor(ContextCompat.getColor(mapActivity, night ? R.color.icon_color_default_dark : R.color.icon_color_default_light));
drawableResToUpdate = R.drawable.ic_direction_arrow; drawableResToUpdate = R.drawable.ic_direction_arrow;
@ -354,8 +353,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
updateDisplayedData(); updateDisplayedData();
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, night ? R.color.active_color_primary_dark : R.color.active_color_primary_light); UiUtilities.setupSnackbar(snackbar, night);
snackbar.getView().setBackgroundColor(ContextCompat.getColor(app, night ? R.color.list_background_color_dark : R.color.list_background_color_light));
snackbar.show(); snackbar.show();
} }
} }
@ -490,7 +488,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
mapMarkersHelper.enableGroup(group); mapMarkersHelper.enableGroup(group);
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, R.color.active_color_primary_dark); UiUtilities.setupSnackbar(snackbar, night);
snackbar.show(); snackbar.show();
} }
} }
@ -498,6 +496,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
headerViewHolder.disableGroupSwitch.setOnCheckedChangeListener(null); headerViewHolder.disableGroupSwitch.setOnCheckedChangeListener(null);
headerViewHolder.disableGroupSwitch.setChecked(!groupIsDisabled); headerViewHolder.disableGroupSwitch.setChecked(!groupIsDisabled);
headerViewHolder.disableGroupSwitch.setOnCheckedChangeListener(checkedChangeListener); headerViewHolder.disableGroupSwitch.setOnCheckedChangeListener(checkedChangeListener);
UiUtilities.setupCompoundButton(headerViewHolder.disableGroupSwitch, night, UiUtilities.CompoundButtonType.GLOBAL);
} else { } else {
throw new IllegalArgumentException("Unsupported header"); throw new IllegalArgumentException("Unsupported header");
} }

View file

@ -118,7 +118,8 @@ public class MapMarkersHistoryAdapter extends RecyclerView.Adapter<RecyclerView.
final MapMarker marker = (MapMarker) getItem(position); final MapMarker marker = (MapMarker) getItem(position);
itemViewHolder.iconReorder.setVisibility(View.GONE); itemViewHolder.iconReorder.setVisibility(View.GONE);
int color = R.color.icon_color_default_dark; int color = night ? R.color.icon_color_default_dark : R.color.icon_color_default_light;
int actionIconColor = night ? R.color.icon_color_primary_dark : R.color.icon_color_primary_light;
itemViewHolder.icon.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_flag_dark, color)); itemViewHolder.icon.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_flag_dark, color));
itemViewHolder.title.setText(marker.getName(app)); itemViewHolder.title.setText(marker.getName(app));
@ -134,7 +135,7 @@ public class MapMarkersHistoryAdapter extends RecyclerView.Adapter<RecyclerView.
itemViewHolder.description.setText(desc); itemViewHolder.description.setText(desc);
itemViewHolder.optionsBtn.setBackgroundDrawable(app.getResources().getDrawable(night ? R.drawable.marker_circle_background_dark_with_inset : R.drawable.marker_circle_background_light_with_inset)); itemViewHolder.optionsBtn.setBackgroundDrawable(app.getResources().getDrawable(night ? R.drawable.marker_circle_background_dark_with_inset : R.drawable.marker_circle_background_light_with_inset));
itemViewHolder.optionsBtn.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_reset_to_default_dark)); itemViewHolder.optionsBtn.setImageDrawable(iconsCache.getIcon(R.drawable.ic_action_reset_to_default_dark, actionIconColor));
itemViewHolder.optionsBtn.setOnClickListener(new View.OnClickListener() { itemViewHolder.optionsBtn.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
@ -151,8 +152,7 @@ public class MapMarkersHistoryAdapter extends RecyclerView.Adapter<RecyclerView.
app.getMapMarkersHelper().moveMapMarkerToHistory(marker); app.getMapMarkersHelper().moveMapMarkerToHistory(marker);
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, night ? R.color.active_color_primary_dark : R.color.active_color_primary_light); UiUtilities.setupSnackbar(snackbar, night);
snackbar.getView().setBackgroundColor(ContextCompat.getColor(app, night ? R.color.list_background_color_dark : R.color.list_background_color_light));
snackbar.show(); snackbar.show();
} }
}); });

View file

@ -202,7 +202,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
updateEnable = false; updateEnable = false;
if (operationTask != null) { if (operationTask != null && !(operationTask instanceof SelectGpxTask)) {
operationTask.cancel(true); operationTask.cancel(true);
} }
if (actionMode != null) { if (actionMode != null) {

View file

@ -550,7 +550,8 @@ public class TrackPointFragment extends OsmandExpandableListFragment implements
super.onDismissed(transientBottomBar, event); super.onDismissed(transientBottomBar, event);
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, R.color.active_color_primary_dark); boolean nightMode = !app.getSettings().isLightContent();
UiUtilities.setupSnackbar(snackbar, nightMode);
snackbar.show(); snackbar.show();
} }
} }

View file

@ -192,9 +192,15 @@ public class SelectProfileBottomSheetDialogFragment extends BasePreferenceBottom
tvTitle.setText(profile.getName()); tvTitle.setText(profile.getName());
tvDescription.setText(profile.getDescription()); tvDescription.setText(profile.getDescription());
final boolean isSelected = profile.getStringKey().equals(selectedItemKey); boolean isSelected = profile.getStringKey().equals(selectedItemKey);
final Drawable drawableIcon = app.getUIUtilities().getIcon(profile.getIconRes(), int iconColor;
isSelected ? activeColorResId : iconDefaultColorResId); if (type.equals(TYPE_BASE_APP_PROFILE)) {
iconColor = profile.getIconColor(nightMode);
} else {
iconColor = isSelected ? activeColorResId : iconDefaultColorResId;
}
Drawable drawableIcon = app.getUIUtilities().getIcon(profile.getIconRes(), iconColor);
ivIcon.setImageDrawable(drawableIcon); ivIcon.setImageDrawable(drawableIcon);
compoundButton.setChecked(isSelected); compoundButton.setChecked(isSelected);
UiUtilities.setupCompoundButton(compoundButton, nightMode, UiUtilities.CompoundButtonType.GLOBAL); UiUtilities.setupCompoundButton(compoundButton, nightMode, UiUtilities.CompoundButtonType.GLOBAL);
@ -220,7 +226,7 @@ public class SelectProfileBottomSheetDialogFragment extends BasePreferenceBottom
private void addButtonItem(int titleId, int iconId, OnClickListener listener) { private void addButtonItem(int titleId, int iconId, OnClickListener listener) {
OsmandApplication app = requiredMyApplication(); OsmandApplication app = requiredMyApplication();
int activeColorResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; int activeColorResId = isNightMode(app) ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
View buttonView = View.inflate(app, R.layout.bottom_sheet_item_preference_btn, null); View buttonView = View.inflate(app, R.layout.bottom_sheet_item_preference_btn, null);
TextView tvTitle = buttonView.findViewById(R.id.title); TextView tvTitle = buttonView.findViewById(R.id.title);

View file

@ -38,7 +38,6 @@ import net.osmand.Location;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.StateChangedListener; import net.osmand.StateChangedListener;
import net.osmand.ValueHolder; import net.osmand.ValueHolder;
import net.osmand.binary.RouteDataObject;
import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
@ -67,6 +66,7 @@ import net.osmand.plus.base.ContextMenuFragment.MenuState;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.helpers.WaypointHelper;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenuFragment; import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenuFragment;
import net.osmand.plus.mapmarkers.MapMarkerSelectionFragment; import net.osmand.plus.mapmarkers.MapMarkerSelectionFragment;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
@ -110,13 +110,13 @@ import org.apache.commons.logging.Log;
import java.io.IOException; import java.io.IOException;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.Stack; import java.util.Stack;
import java.util.TreeMap;
public class MapRouteInfoMenu implements IRouteInformationListener, CardListener, FavoritesListener { public class MapRouteInfoMenu implements IRouteInformationListener, CardListener, FavoritesListener {
@ -1204,7 +1204,7 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener
final LinearLayout item = createToolbarOptionView(false, null, -1, -1, null); final LinearLayout item = createToolbarOptionView(false, null, -1, -1, null);
if (item != null) { if (item != null) {
item.findViewById(R.id.route_option_container).setVisibility(View.GONE); item.findViewById(R.id.route_option_container).setVisibility(View.GONE);
Map<LatLon, RouteDataObject> impassableRoads = new TreeMap<>(); Map<LatLon, AvoidRoadInfo> impassableRoads = new HashMap<>();
if (parameter instanceof AvoidRoadsRoutingParameter) { if (parameter instanceof AvoidRoadsRoutingParameter) {
impassableRoads = app.getAvoidSpecificRoads().getImpassableRoads(); impassableRoads = app.getAvoidSpecificRoads().getImpassableRoads();
} }
@ -1232,22 +1232,19 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener
return avoidedParameters; return avoidedParameters;
} }
private void createImpassableRoadsItems(MapActivity mapActivity, Map<LatLon, RouteDataObject> impassableRoads, final LocalRoutingParameter parameter, final RouteMenuAppModes mode, final LinearLayout item) { private void createImpassableRoadsItems(MapActivity mapActivity, Map<LatLon, AvoidRoadInfo> impassableRoads,
OsmandApplication app = mapActivity.getMyApplication(); final LocalRoutingParameter parameter, final RouteMenuAppModes mode, final LinearLayout item) {
Iterator<RouteDataObject> it = impassableRoads.values().iterator(); Iterator<AvoidRoadInfo> it = impassableRoads.values().iterator();
while (it.hasNext()) { while (it.hasNext()) {
final RouteDataObject routeDataObject = it.next(); final AvoidRoadInfo avoidRoadInfo = it.next();
final View container = createToolbarSubOptionView(false, app.getAvoidSpecificRoads().getText(routeDataObject), R.drawable.ic_action_remove_dark, !it.hasNext(), new OnClickListener() { final View container = createToolbarSubOptionView(false, avoidRoadInfo.name, R.drawable.ic_action_remove_dark, !it.hasNext(), new OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (mapActivity != null) { if (mapActivity != null) {
OsmandApplication app = mapActivity.getMyApplication(); OsmandApplication app = mapActivity.getMyApplication();
RoutingHelper routingHelper = app.getRoutingHelper(); app.getAvoidSpecificRoads().removeImpassableRoad(avoidRoadInfo);
if (routeDataObject != null) { app.getRoutingHelper().recalculateRouteDueToSettingsChange();
app.getAvoidSpecificRoads().removeImpassableRoad(routeDataObject);
}
routingHelper.recalculateRouteDueToSettingsChange();
if (app.getAvoidSpecificRoads().getImpassableRoads().isEmpty() && getAvoidedParameters(app).isEmpty()) { if (app.getAvoidSpecificRoads().getImpassableRoads().isEmpty() && getAvoidedParameters(app).isEmpty()) {
mode.parameters.remove(parameter); mode.parameters.remove(parameter);
} }

View file

@ -430,7 +430,13 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
boolean osmandRouter = applicationMode.getRouteService() == RouteProvider.RouteService.OSMAND; boolean osmandRouter = applicationMode.getRouteService() == RouteProvider.RouteService.OSMAND;
if (!osmandRouter) { if (!osmandRouter) {
routingParameters = AppModeOptions.OTHER.routingParameters; if (applicationMode.getRouteService() == RouteProvider.RouteService.STRAIGHT) {
routingParameters = AppModeOptions.STRAIGHT.routingParameters;
} else if (applicationMode.getRouteService() == RouteProvider.RouteService.DIRECT_TO) {
routingParameters = AppModeOptions.DIRECT_TO.routingParameters;
} else {
routingParameters = AppModeOptions.OTHER.routingParameters;
}
} else if (applicationMode.isDerivedRoutingFrom(ApplicationMode.CAR)) { } else if (applicationMode.isDerivedRoutingFrom(ApplicationMode.CAR)) {
routingParameters = AppModeOptions.CAR.routingParameters; routingParameters = AppModeOptions.CAR.routingParameters;
} else if (applicationMode.isDerivedRoutingFrom(ApplicationMode.BICYCLE)) { } else if (applicationMode.isDerivedRoutingFrom(ApplicationMode.BICYCLE)) {
@ -579,6 +585,22 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
DividerItem.KEY, DividerItem.KEY,
GpxLocalRoutingParameter.KEY, GpxLocalRoutingParameter.KEY,
OtherSettingsRoutingParameter.KEY, OtherSettingsRoutingParameter.KEY,
RouteSimulationItem.KEY),
STRAIGHT(MuteSoundRoutingParameter.KEY,
DividerItem.KEY,
ShowAlongTheRouteItem.KEY,
DividerItem.KEY,
GpxLocalRoutingParameter.KEY,
OtherSettingsRoutingParameter.KEY,
RouteSimulationItem.KEY),
DIRECT_TO(MuteSoundRoutingParameter.KEY,
DividerItem.KEY,
ShowAlongTheRouteItem.KEY,
DividerItem.KEY,
GpxLocalRoutingParameter.KEY,
OtherSettingsRoutingParameter.KEY,
RouteSimulationItem.KEY); RouteSimulationItem.KEY);

View file

@ -1037,10 +1037,7 @@ public class RouteCalculationResult {
nextInd++; nextInd++;
} }
} }
int dist = getListDistance(currentRoute); int dist = getDistanceToFinish(fromLoc);
if (fromLoc != null) {
dist += fromLoc.distanceTo(locations.get(currentRoute));
}
if (nextInd < directions.size()) { if (nextInd < directions.size()) {
info.directionInfo = directions.get(nextInd); info.directionInfo = directions.get(nextInd);
if (directions.get(nextInd).routePointOffset <= currentRoute if (directions.get(nextInd).routePointOffset <= currentRoute
@ -1157,15 +1154,27 @@ public class RouteCalculationResult {
return 0; return 0;
} }
public int getDistanceFromPoint(int locationIndex) {
if(listDistance != null && locationIndex < listDistance.length) {
return listDistance[locationIndex];
}
return 0;
}
public boolean isPointPassed(int locationIndex) { public boolean isPointPassed(int locationIndex) {
return locationIndex <= currentRoute; return locationIndex <= currentRoute;
} }
public int getDistanceToFinish(Location fromLoc) { public int getDistanceToFinish(Location fromLoc) {
if(listDistance != null && currentRoute < listDistance.length){ Location ap = this.currentStraightAnglePoint;
int dist = listDistance[currentRoute]; int rp = currentStraightAngleRoute > currentRoute ? currentStraightAngleRoute : currentRoute;
Location l = locations.get(currentRoute); if(listDistance != null && rp < listDistance.length){
if(fromLoc != null){ int dist = listDistance[rp];
Location l = locations.get(rp);
if(ap != null){
dist += fromLoc.distanceTo(ap);
dist += ap.distanceTo(l);
} else {
dist += fromLoc.distanceTo(l); dist += fromLoc.distanceTo(l);
} }
return dist; return dist;
@ -1174,12 +1183,8 @@ public class RouteCalculationResult {
} }
public int getDistanceToNextIntermediate(Location fromLoc) { public int getDistanceToNextIntermediate(Location fromLoc) {
int dist = getDistanceToFinish(fromLoc);
if(listDistance != null && currentRoute < listDistance.length){ if(listDistance != null && currentRoute < listDistance.length){
int dist = listDistance[currentRoute];
Location l = locations.get(currentRoute);
if(fromLoc != null){
dist += fromLoc.distanceTo(l);
}
if(nextIntermediate >= intermediatePoints.length ){ if(nextIntermediate >= intermediatePoints.length ){
return 0; return 0;
} else { } else {
@ -1245,8 +1250,8 @@ public class RouteCalculationResult {
} }
public void updateNextVisiblePoint(int nextPoint, Location mp) { public void updateNextVisiblePoint(int nextPoint, Location mp) {
currentStraightAngleRoute = nextPoint;
currentStraightAnglePoint = mp; currentStraightAnglePoint = mp;
currentStraightAngleRoute = nextPoint;
} }
public static class NextDirectionInfo { public static class NextDirectionInfo {

View file

@ -1240,29 +1240,35 @@ public class RouteProvider {
} }
private RouteCalculationResult findStraightRoute(RouteCalculationParams params) { private RouteCalculationResult findStraightRoute(RouteCalculationParams params) {
Location currentLocation = params.currentLocation;
LinkedList<Location> points = new LinkedList<>(); LinkedList<Location> points = new LinkedList<>();
List<Location> segments = new ArrayList<>(); List<Location> segments = new ArrayList<>();
points.add(params.start); points.add(new Location("pnt", params.start.getLatitude(), params.start.getLongitude()));
if(params.intermediates != null) { if(params.intermediates != null) {
for (LatLon l : params.intermediates) { for (LatLon l : params.intermediates) {
points.add(new Location("", l.getLatitude(), l.getLongitude())); points.add(new Location("pnt", l.getLatitude(), l.getLongitude()));
} }
} }
points.add(new Location("", params.end.getLatitude(), params.end.getLongitude())); points.add(new Location("", params.end.getLatitude(), params.end.getLongitude()));
Location lastAdded = points.poll(); Location lastAdded = null;
segments.add(lastAdded); float speed = params.mode.getDefaultSpeed();
List<RouteDirectionInfo> computeDirections = new ArrayList<RouteDirectionInfo>();
while(!points.isEmpty()) { while(!points.isEmpty()) {
Location pl = points.peek(); Location pl = points.peek();
if (lastAdded.distanceTo(pl) < MIN_STRAIGHT_DIST) { if (lastAdded == null || lastAdded.distanceTo(pl) < MIN_STRAIGHT_DIST) {
lastAdded = points.poll(); lastAdded = points.poll();
if(lastAdded.getProvider().equals("pnt")) {
RouteDirectionInfo previousInfo = new RouteDirectionInfo(speed, TurnType.straight());
previousInfo.routePointOffset = segments.size();
previousInfo.setDescriptionRoute(params.ctx.getString(R.string.route_head));
computeDirections.add(previousInfo);
}
segments.add(lastAdded); segments.add(lastAdded);
} else { } else {
Location mp = MapUtils.calculateMidPoint(lastAdded, pl); Location mp = MapUtils.calculateMidPoint(lastAdded, pl);
points.add(0, mp); points.add(0, mp);
} }
} }
return new RouteCalculationResult(segments, null, params, null, false); return new RouteCalculationResult(segments, computeDirections, params, null, false);
} }

View file

@ -430,7 +430,6 @@ public class RoutingHelper {
// 0. Route empty or needs to be extended? Then re-calculate route. // 0. Route empty or needs to be extended? Then re-calculate route.
if(route.isEmpty()) { if(route.isEmpty()) {
calculateRoute = true; calculateRoute = true;
//originalRoute = null;
} else { } else {
// 1. Update current route position status according to latest received location // 1. Update current route position status according to latest received location
boolean finished = updateCurrentRouteStatus(currentLocation, posTolerance); boolean finished = updateCurrentRouteStatus(currentLocation, posTolerance);

View file

@ -366,8 +366,8 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
fragment.setUsedOnMap(false); fragment.setUsedOnMap(false);
fragment.setAppMode(getSelectedAppMode()); fragment.setAppMode(getSelectedAppMode());
if (getSelectedAppMode() != null) { if (changedProfile.parent != null) {
bundle.putString(SELECTED_KEY, getSelectedAppMode().getRoutingProfile()); bundle.putString(SELECTED_KEY, changedProfile.parent.getStringKey());
} }
bundle.putString(DIALOG_TYPE, TYPE_BASE_APP_PROFILE); bundle.putString(DIALOG_TYPE, TYPE_BASE_APP_PROFILE);
fragment.setArguments(bundle); fragment.setArguments(bundle);

View file

@ -1,14 +1,23 @@
package net.osmand.plus.settings; package net.osmand.plus.settings;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.preference.Preference; import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.PreferenceViewHolder; import android.support.v7.preference.PreferenceViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import net.osmand.GPXUtilities;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.StateChangedListener; import net.osmand.StateChangedListener;
import net.osmand.plus.ApplicationMode; import net.osmand.plus.ApplicationMode;
@ -17,6 +26,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.OsmandSettings.BooleanPreference; import net.osmand.plus.OsmandSettings.BooleanPreference;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.SettingsBaseActivity; import net.osmand.plus.activities.SettingsBaseActivity;
import net.osmand.plus.activities.SettingsNavigationActivity; import net.osmand.plus.activities.SettingsNavigationActivity;
import net.osmand.plus.routing.RouteProvider; import net.osmand.plus.routing.RouteProvider;
@ -83,7 +93,6 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP
routeParametersInfo.setTitle(getString(R.string.route_parameters_info, getSelectedAppMode().toHumanString())); routeParametersInfo.setTitle(getString(R.string.route_parameters_info, getSelectedAppMode().toHumanString()));
setupRoutingPrefs(); setupRoutingPrefs();
setupTimeConditionalRoutingPref();
} }
@Override @Override
@ -131,21 +140,19 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP
} }
PreferenceScreen screen = getPreferenceScreen(); PreferenceScreen screen = getPreferenceScreen();
ApplicationMode am = getSelectedAppMode();
SwitchPreferenceEx fastRoute = createSwitchPreferenceEx(app.getSettings().FAST_ROUTE_MODE.getId(), R.string.fast_route_mode, R.layout.preference_with_descr_dialog_and_switch); SwitchPreferenceEx fastRoute = createSwitchPreferenceEx(app.getSettings().FAST_ROUTE_MODE.getId(), R.string.fast_route_mode, R.layout.preference_with_descr_dialog_and_switch);
fastRoute.setIcon(getRoutingPrefIcon(app.getSettings().FAST_ROUTE_MODE.getId())); fastRoute.setIcon(getRoutingPrefIcon(app.getSettings().FAST_ROUTE_MODE.getId()));
fastRoute.setDescription(getString(R.string.fast_route_mode_descr)); fastRoute.setDescription(getString(R.string.fast_route_mode_descr));
fastRoute.setSummaryOn(R.string.shared_string_on); fastRoute.setSummaryOn(R.string.shared_string_on);
fastRoute.setSummaryOff(R.string.shared_string_off); fastRoute.setSummaryOff(R.string.shared_string_off);
ApplicationMode am = getSelectedAppMode();
float defaultAllowedDeviation = RoutingHelper.getDefaultAllowedDeviation(settings, am, float defaultAllowedDeviation = RoutingHelper.getDefaultAllowedDeviation(settings, am,
RoutingHelper.getPosTolerance(0)); RoutingHelper.getPosTolerance(0));
if (am.getRouteService() != RouteProvider.RouteService.OSMAND) { setupSelectRouteRecalcDistance(screen, defaultAllowedDeviation);
screen.addPreference(fastRoute);
setupSelectRouteRecalcDistance(screen, defaultAllowedDeviation); if (am.getRouteService() == RouteProvider.RouteService.OSMAND){
} else {
setupSelectRouteRecalcDistance(screen, defaultAllowedDeviation);
GeneralRouter router = app.getRouter(am); GeneralRouter router = app.getRouter(am);
clearParameters(); clearParameters();
if (router != null) { if (router != null) {
@ -231,9 +238,87 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP
} }
} }
} }
setupTimeConditionalRoutingPref();
} else if (am.getRouteService() == RouteProvider.RouteService.BROUTER) {
screen.addPreference(fastRoute);
setupTimeConditionalRoutingPref();
} else if (am.getRouteService() == RouteProvider.RouteService.STRAIGHT) {
Preference straightAngle = new Preference(app.getApplicationContext());
straightAngle.setPersistent(false);
straightAngle.setKey(settings.ROUTE_STRAIGHT_ANGLE.getId());
straightAngle.setTitle(getString(R.string.recalc_angle_dialog_title));
straightAngle.setSummary(String.format(getString(R.string.shared_string_angle_param), (int) am.getStrAngle()));
straightAngle.setLayoutResource(R.layout.preference_with_descr);
straightAngle.setIcon(getRoutingPrefIcon("routing_recalc_distance")); //TODO change for appropriate icon when available
getPreferenceScreen().addPreference(straightAngle);
} }
} }
@Override
public boolean onPreferenceClick(Preference preference) {
if (preference.getKey().equals(settings.ROUTE_STRAIGHT_ANGLE.getId())) {
showSeekbarSettingsDialog(getActivity(), getSelectedAppMode());
}
return super.onPreferenceClick(preference);
}
private void showSeekbarSettingsDialog(Activity activity, final ApplicationMode mode) {
if (activity == null || mode == null) {
return;
}
final OsmandApplication app = (OsmandApplication) activity.getApplication();
final float[] angleValue = new float[] {mode.getStrAngle()};
boolean nightMode = !app.getSettings().isLightContentForMode(mode);
Context themedContext = UiUtilities.getThemedContext(activity, nightMode);
AlertDialog.Builder builder = new AlertDialog.Builder(themedContext);
View seekbarView = LayoutInflater.from(themedContext).inflate(R.layout.recalculation_angle_dialog, null, false);
builder.setView(seekbarView);
builder.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mode.setStrAngle(angleValue[0]);
updateAllSettings();
RoutingHelper routingHelper = app.getRoutingHelper();
if (mode.equals(routingHelper.getAppMode()) && (routingHelper.isRouteCalculated() || routingHelper.isRouteBeingCalculated())) {
routingHelper.recalculateRouteDueToSettingsChange();
}
}
});
builder.setNegativeButton(R.string.shared_string_cancel, null);
int selectedModeColor = ContextCompat.getColor(app, mode.getIconColorInfo().getColor(nightMode));
setupAngleSlider(angleValue, seekbarView, nightMode, selectedModeColor);
builder.show();
}
private static void setupAngleSlider(final float[] angleValue,
View seekbarView,
final boolean nightMode,
final int activeColor) {
final SeekBar angleBar = seekbarView.findViewById(R.id.angle_seekbar);
final TextView angleTv = seekbarView.findViewById(R.id.angle_text);
angleTv.setText(String.valueOf(angleValue[0]));
angleBar.setProgress((int) angleValue[0]);
angleBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
int value = progress - (progress % 5);
angleValue[0] = value;
angleTv.setText(String.valueOf(value));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
UiUtilities.setupSeekBar(angleBar, activeColor, nightMode);
}
private void setupSelectRouteRecalcDistance(PreferenceScreen screen, float defaultAllowedDeviation) { private void setupSelectRouteRecalcDistance(PreferenceScreen screen, float defaultAllowedDeviation) {
Float[] entryValues; Float[] entryValues;
OsmandSettings settings = app.getSettings(); OsmandSettings settings = app.getSettings();

View file

@ -10,7 +10,6 @@ import android.graphics.PointF;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import net.osmand.binary.RouteDataObject;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.data.RotatedTileBox; import net.osmand.data.RotatedTileBox;
@ -18,6 +17,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.AvoidSpecificRoads; import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidSpecificRoadsCallback; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidSpecificRoadsCallback;
import net.osmand.plus.views.ContextMenuLayer.ApplyMovedObjectCallback; import net.osmand.plus.views.ContextMenuLayer.ApplyMovedObjectCallback;
@ -55,7 +55,7 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements
@Override @Override
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) { public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (contextMenuLayer.getMoveableObject() instanceof RouteDataObject) { if (contextMenuLayer.getMoveableObject() instanceof AvoidRoadInfo) {
PointF pf = contextMenuLayer.getMovableCenterPoint(tileBox); PointF pf = contextMenuLayer.getMovableCenterPoint(tileBox);
drawPoint(canvas, pf.x, pf.y, true); drawPoint(canvas, pf.x, pf.y, true);
} }
@ -64,11 +64,11 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements
@Override @Override
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) { public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (tileBox.getZoom() >= START_ZOOM) { if (tileBox.getZoom() >= START_ZOOM) {
for (Map.Entry<LatLon, RouteDataObject> entry : avoidSpecificRoads.getImpassableRoads().entrySet()) { for (Map.Entry<LatLon, AvoidRoadInfo> entry : avoidSpecificRoads.getImpassableRoads().entrySet()) {
LatLon location = entry.getKey(); LatLon location = entry.getKey();
RouteDataObject road = entry.getValue(); AvoidRoadInfo road = entry.getValue();
if (road != null && contextMenuLayer.getMoveableObject() instanceof RouteDataObject) { if (road != null && contextMenuLayer.getMoveableObject() instanceof AvoidRoadInfo) {
RouteDataObject object = (RouteDataObject) contextMenuLayer.getMoveableObject(); AvoidRoadInfo object = (AvoidRoadInfo) contextMenuLayer.getMoveableObject();
if (object.id == road.id) { if (object.id == road.id) {
continue; continue;
} }
@ -146,9 +146,9 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements
int compare = getRadiusPoi(tileBox); int compare = getRadiusPoi(tileBox);
int radius = compare * 3 / 2; int radius = compare * 3 / 2;
for (Map.Entry<LatLon, RouteDataObject> entry : avoidSpecificRoads.getImpassableRoads().entrySet()) { for (Map.Entry<LatLon, AvoidRoadInfo> entry : avoidSpecificRoads.getImpassableRoads().entrySet()) {
LatLon location = entry.getKey(); LatLon location = entry.getKey();
RouteDataObject road = entry.getValue(); AvoidRoadInfo road = entry.getValue();
if (location != null && road != null) { if (location != null && road != null) {
int x = (int) tileBox.getPixXFromLatLon(location.getLatitude(), location.getLongitude()); int x = (int) tileBox.getPixXFromLatLon(location.getLatitude(), location.getLongitude());
int y = (int) tileBox.getPixYFromLatLon(location.getLatitude(), location.getLongitude()); int y = (int) tileBox.getPixYFromLatLon(location.getLatitude(), location.getLongitude());
@ -163,36 +163,37 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements
@Override @Override
public LatLon getObjectLocation(Object o) { public LatLon getObjectLocation(Object o) {
if (o instanceof RouteDataObject) { if (o instanceof AvoidRoadInfo) {
return avoidSpecificRoads.getLocation((RouteDataObject) o); AvoidRoadInfo avoidRoadInfo = (AvoidRoadInfo) o;
return new LatLon(avoidRoadInfo.latitude, avoidRoadInfo.longitude);
} }
return null; return null;
} }
@Override @Override
public PointDescription getObjectName(Object o) { public PointDescription getObjectName(Object o) {
if (o instanceof RouteDataObject) { if (o instanceof AvoidRoadInfo) {
RouteDataObject route = (RouteDataObject) o; AvoidRoadInfo route = (AvoidRoadInfo) o;
return new PointDescription(PointDescription.POINT_TYPE_BLOCKED_ROAD, route.getName()); return new PointDescription(PointDescription.POINT_TYPE_BLOCKED_ROAD, route.name);
} }
return null; return null;
} }
@Override @Override
public boolean isObjectMovable(Object o) { public boolean isObjectMovable(Object o) {
return o instanceof RouteDataObject; return o instanceof AvoidRoadInfo;
} }
@Override @Override
public void applyNewObjectPosition(@NonNull Object o, public void applyNewObjectPosition(@NonNull Object o,
@NonNull LatLon position, @NonNull LatLon position,
@Nullable final ApplyMovedObjectCallback callback) { @Nullable final ApplyMovedObjectCallback callback) {
if (o instanceof RouteDataObject) { if (o instanceof AvoidRoadInfo) {
final RouteDataObject object = (RouteDataObject) o; final AvoidRoadInfo object = (AvoidRoadInfo) o;
final OsmandApplication application = activity.getMyApplication(); final OsmandApplication application = activity.getMyApplication();
application.getAvoidSpecificRoads().replaceImpassableRoad(activity, object, position, false, new AvoidSpecificRoadsCallback() { application.getAvoidSpecificRoads().replaceImpassableRoad(activity, object, position, false, new AvoidSpecificRoadsCallback() {
@Override @Override
public void onAddImpassableRoad(boolean success, RouteDataObject newObject) { public void onAddImpassableRoad(boolean success, AvoidRoadInfo newObject) {
if (callback != null) { if (callback != null) {
callback.onApplyMovedObject(success, newObject); callback.onApplyMovedObject(success, newObject);
} }

View file

@ -35,6 +35,7 @@ import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu; import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu.TrackChartPoints; import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu.TrackChartPoints;
import net.osmand.plus.profiles.LocationIcon;
import net.osmand.plus.render.RenderingIcons; import net.osmand.plus.render.RenderingIcons;
import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteCalculationResult;
import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.plus.routing.RouteDirectionInfo;
@ -319,7 +320,8 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont
private void drawProjectionPoint(Canvas canvas, double[] projectionXY) { private void drawProjectionPoint(Canvas canvas, double[] projectionXY) {
if (projectionIcon == null) { if (projectionIcon == null) {
projectionIcon = (LayerDrawable) view.getResources().getDrawable(helper.getSettings().getApplicationMode().getLocationIcon().getIconId()); helper.getSettings().getApplicationMode().getLocationIcon();
projectionIcon = (LayerDrawable) view.getResources().getDrawable(LocationIcon.DEFAULT.getIconId());
} }
int locationX = (int) projectionXY[0]; int locationX = (int) projectionXY[0];
int locationY = (int) projectionXY[1]; int locationY = (int) projectionXY[1];
@ -1146,45 +1148,39 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont
} }
private double[] calculateProjectionOnRoutePoint(List<Location> routeNodes, RoutingHelper helper, RotatedTileBox box) { private double[] calculateProjectionOnRoutePoint(List<Location> routeNodes, RoutingHelper helper, RotatedTileBox box) {
double[] projectionXY; double[] projectionXY = null;
boolean visible; Location ll = helper.getLastFixedLocation();
Location previousInRoute = null; RouteCalculationResult route = helper.getRoute();
Location nextInRoute = null; List<Location> locs = route.getImmutableAllLocations();
//need to change this code by fixing helper.route.getCurrentRoute() miscalculation int cr = route.getCurrentRoute();
// TODO simplifiy all culation! int locIndex = locs.size() - 1;
if (helper.getRoute().getIntermediatePointsToPass() > 0) { if(route.getIntermediatePointsToPass() > 0) {
for (int i = 1; i < routeNodes.size(); i++) { locIndex = route.getIndexOfIntermediate(route.getIntermediatePointsToPass() - 1);
LatLon routePoint = new LatLon(routeNodes.get(i).getLatitude(), routeNodes.get(i).getLongitude());
if (routePoint.equals(helper.getIntermediatePoints().get(0))) {
previousInRoute = routeNodes.get(i - 1);
nextInRoute = routeNodes.get(i);
}
}
} else {
previousInRoute = routeNodes.get(routeNodes.size() - 2);
nextInRoute = routeNodes.get(routeNodes.size() - 1);
} }
if(ll != null && cr > 0 && cr < locs.size() && locIndex >= 0 && locIndex < locs.size()) {
Location loc1 = locs.get(cr - 1);
Location loc2 = locs.get(cr);
double distLeft = route.getDistanceFromPoint(cr) - route.getDistanceFromPoint(locIndex);
double baDist = route.getDistanceFromPoint(cr - 1) - route.getDistanceFromPoint(cr);
Location target = locs.get(locIndex);
double dTarget = ll.distanceTo(target);
final int aX = box.getPixXFromLonNoRot(loc1.getLongitude());
final int aY = box.getPixYFromLatNoRot(loc1.getLatitude());
final int bX = box.getPixXFromLonNoRot(loc2.getLongitude());
final int bY = box.getPixYFromLatNoRot(loc2.getLatitude());
if(baDist != 0) {
double CF = (dTarget - distLeft) / baDist;
double rX = bX - CF * (bX - aX);
double rY = bY - CF * (bY - aY);
projectionXY = new double[] {rX, rY};
}
}
if(projectionXY != null) {
if (nextInRoute != null && previousInRoute != null) { double distanceLoc2Proj = MapUtils.getSqrtDistance((int)projectionXY[0], (int) projectionXY[1],
box.getPixXFromLonNoRot(ll.getLongitude()), box.getPixYFromLatNoRot(ll.getLatitude()));
final Location ll = view.getApplication().getLocationProvider().getLastKnownLocation(); boolean visible = box.containsPoint((float) projectionXY[0], (float) projectionXY[1], 20.0f)
final int aX = box.getPixXFromLonNoRot(ll.getLongitude()); && distanceLoc2Proj > AndroidUtils.dpToPx(view.getContext(), 52) / 2.0;
final int aY = box.getPixYFromLatNoRot(ll.getLatitude());
final int centerX = box.getPixXFromLonNoRot(nextInRoute.getLongitude());
final int centerY = box.getPixYFromLatNoRot(nextInRoute.getLatitude());
final int bX = box.getPixXFromLonNoRot(previousInRoute.getLongitude());
final int bY = box.getPixYFromLatNoRot(previousInRoute.getLatitude());
double radius = MapUtils.getVectorMagnitude(centerX, centerY, aX, aY);
double angle2 = MapUtils.getAngleForRadiusVector(centerX, centerY, bX, bY);
projectionXY = MapUtils.getCoordinatesFromRadiusAndAngle(centerX, centerY, radius, angle2);
double distanceLoc2Proj = MapUtils.getVectorMagnitude(aX, aY, (int)projectionXY[0], (int)projectionXY[1]);
boolean isProjectionOnSegment = MapUtils.getVectorMagnitude(centerX ,centerY, (int) projectionXY[0], (int) projectionXY[1])
< MapUtils.getVectorMagnitude(centerX, centerY, bX, bY);
visible = box.containsPoint((float)projectionXY[0], (float)projectionXY[1], 20.0f)
&& Math.abs(Math.toDegrees(MapUtils.getAngleBetweenVectors(centerX, centerY, aX, aY, centerX, centerY, bX, bY))) < 90
&& distanceLoc2Proj > AndroidUtils.dpToPx(view.getContext(), 52) / 2.0
&& isProjectionOnSegment;
if (visible) { if (visible) {
return projectionXY; return projectionXY;
} }

View file

@ -1405,8 +1405,7 @@ public class MapInfoWidgetsFactory {
ctx.startActivity(Intent.createChooser(intent, ctx.getString(R.string.send_location))); ctx.startActivity(Intent.createChooser(intent, ctx.getString(R.string.send_location)));
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, R.color.active_color_primary_dark); UiUtilities.setupSnackbar(snackbar, nightMode, 5);
AndroidUtils.setSnackbarTextMaxLines(snackbar, 5);
snackbar.show(); snackbar.show();
} }

View file

@ -11,6 +11,7 @@ import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.text.Html; import android.text.Html;
import android.util.Log; import android.util.Log;
import android.view.ContextThemeWrapper;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.ResultMatcher; import net.osmand.ResultMatcher;
@ -86,7 +87,7 @@ public class WikiArticleHelper {
activityRef = new WeakReference<>(activity); activityRef = new WeakReference<>(activity);
this.isNightMode = nightMode; this.isNightMode = nightMode;
this.url = url; this.url = url;
dialog = createProgressDialog(activity); dialog = createProgressDialog(activity, isNightMode);
} }
@Override @Override
@ -215,9 +216,9 @@ public class WikiArticleHelper {
return ""; return "";
} }
private static ProgressDialog createProgressDialog(@NonNull FragmentActivity activity) { private static ProgressDialog createProgressDialog(@NonNull FragmentActivity activity, boolean nightMode) {
if (activity != null) { if (activity != null) {
ProgressDialog dialog = new ProgressDialog(activity); ProgressDialog dialog = new ProgressDialog(new ContextThemeWrapper(activity, nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme));
dialog.setCancelable(false); dialog.setCancelable(false);
dialog.setMessage(activity.getString(R.string.wiki_article_search_text)); dialog.setMessage(activity.getString(R.string.wiki_article_search_text));
return dialog; return dialog;

View file

@ -204,7 +204,10 @@ public class SavedArticlesRvAdapter extends RecyclerView.Adapter<RecyclerView.Vi
ldh.restoreSavedArticle(article); ldh.restoreSavedArticle(article);
} }
}); });
AndroidUtils.setSnackbarTextColor(snackbar, R.color.wikivoyage_active_dark); boolean nightMode = !settings.isLightContent();
UiUtilities.setupSnackbar(snackbar, nightMode);
int wikivoyageActiveColorResId = nightMode ? R.color.wikivoyage_active_dark : R.color.wikivoyage_active_light;
UiUtilities.setupSnackbar(snackbar, nightMode, null, null, wikivoyageActiveColorResId, null);
snackbar.show(); snackbar.show();
} }
} }