From 584e7dbf6d7ab00a42e3366a68599e7de263569b Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Sun, 21 Feb 2021 13:44:22 +0200 Subject: [PATCH 01/29] Implement GPX online routing, step 1 --- .../main/java/net/osmand/util/Algorithms.java | 10 + .../onlinerouting/OnlineRoutingFactory.java | 3 + .../onlinerouting/OnlineRoutingHelper.java | 21 +- .../plus/onlinerouting/VehicleType.java | 1 + .../plus/onlinerouting/engine/EngineType.java | 20 +- .../plus/onlinerouting/engine/GpxEngine.java | 57 ++++++ .../engine/GraphhopperEngine.java | 162 +-------------- .../engine/OnlineRoutingEngine.java | 94 +++------ .../plus/onlinerouting/engine/OrsEngine.java | 48 +---- .../plus/onlinerouting/engine/OsrmEngine.java | 181 +---------------- .../plus/onlinerouting/parser/GpxParser.java | 42 ++++ .../parser/GraphhopperParser.java | 165 ++++++++++++++++ .../plus/onlinerouting/parser/JSONParser.java | 77 ++++++++ .../plus/onlinerouting/parser/OrsParser.java | 52 +++++ .../plus/onlinerouting/parser/OsrmParser.java | 187 ++++++++++++++++++ .../onlinerouting/parser/ResponseParser.java | 77 ++++++++ .../ui/OnlineRoutingEngineFragment.java | 8 +- .../osmand/plus/routing/RouteProvider.java | 28 ++- 18 files changed, 778 insertions(+), 455 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/parser/GraphhopperParser.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/parser/OrsParser.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/parser/OsrmParser.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/parser/ResponseParser.java diff --git a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java index 83b7c14b44..247fc30ced 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java @@ -53,6 +53,8 @@ public class Algorithms { public static final int XML_FILE_SIGNATURE = 0x3c3f786d; public static final int OBF_FILE_SIGNATURE = 0x08029001; public static final int SQLITE_FILE_SIGNATURE = 0x53514C69; + public static final int BZIP_FILE_SIGNATURE = 0x425a; + public static final int GZIP_FILE_SIGNATURE = 0x1f8b; public static String normalizeSearchText(String s) { boolean norm = false; @@ -358,6 +360,14 @@ public class Algorithms { return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4); } + public static int readSmallInt(InputStream in) throws IOException { + int ch1 = in.read(); + int ch2 = in.read(); + if ((ch1 | ch2) < 0) + throw new EOFException(); + return ((ch1 << 8) + ch2); + } + public static String capitalizeFirstLetterAndLowercase(String s) { if (s != null && s.length() > 1) { // not very efficient algorithm diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingFactory.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingFactory.java index 4b92000847..71ea72f5e4 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingFactory.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingFactory.java @@ -4,6 +4,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import net.osmand.plus.onlinerouting.engine.EngineType; +import net.osmand.plus.onlinerouting.engine.GpxEngine; import net.osmand.plus.onlinerouting.engine.GraphhopperEngine; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.onlinerouting.engine.OrsEngine; @@ -27,6 +28,8 @@ public class OnlineRoutingFactory { return new OsrmEngine(params); case ORS: return new OrsEngine(params); + case GPX: + return new GpxEngine(params); default: throw new IllegalArgumentException( "Online routing type {" + type.name() + "} not supported"); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index de36b87449..079cfd8a12 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -9,7 +9,8 @@ import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.Version; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; -import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse; +import net.osmand.plus.onlinerouting.parser.ResponseParser; +import net.osmand.plus.onlinerouting.parser.ResponseParser.OnlineRoutingResponse; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; @@ -19,12 +20,14 @@ import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.zip.GZIPInputStream; import static net.osmand.util.Algorithms.isEmpty; @@ -88,7 +91,8 @@ public class OnlineRoutingHelper { boolean leftSideNavigation) throws IOException, JSONException { String url = engine.getFullUrl(path); String content = makeRequest(url); - return engine.parseServerResponse(content, app, leftSideNavigation); + ResponseParser parser = engine.getResponseParser(); + return parser.parseResponse(content, app, leftSideNavigation); } @NonNull @@ -98,7 +102,7 @@ public class OnlineRoutingHelper { StringBuilder content = new StringBuilder(); BufferedReader reader; if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { - reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + reader = new BufferedReader(new InputStreamReader(getInputStream(connection))); } else { reader = new BufferedReader(new InputStreamReader(connection.getErrorStream())); } @@ -113,6 +117,17 @@ public class OnlineRoutingHelper { return content.toString(); } + private InputStream getInputStream(@NonNull HttpURLConnection connection) throws IOException { + // todo check file signature correctly +// InputStream is = connection.getInputStream(); +// int header = Algorithms.readTwoInt(is); +// boolean isGzipFile = header == Algorithms.GZIP_FILE_SIGNATURE; +// if (isGzipFile) { +// return new GZIPInputStream(connection.getInputStream()); +// } + return connection.getInputStream(); + } + public void saveEngine(@NonNull OnlineRoutingEngine engine) { deleteInaccessibleParameters(engine); String key = createEngineKeyIfNeeded(engine); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java index 9936f8efbf..494f3aa7a1 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java @@ -6,6 +6,7 @@ import androidx.annotation.NonNull; import androidx.annotation.StringRes; public class VehicleType { + private final String key; @StringRes private final int titleId; diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java index 431ad33a3d..41e10b1dd3 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java @@ -3,23 +3,35 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.plus.onlinerouting.parser.GpxParser; +import net.osmand.plus.onlinerouting.parser.GraphhopperParser; +import net.osmand.plus.onlinerouting.parser.OrsParser; +import net.osmand.plus.onlinerouting.parser.OsrmParser; +import net.osmand.plus.onlinerouting.parser.ResponseParser; import net.osmand.util.Algorithms; public enum EngineType { - GRAPHHOPPER("Graphhopper"), - OSRM("OSRM"), - ORS("Openroute Service"); + GRAPHHOPPER("Graphhopper", GraphhopperParser.class), + OSRM("OSRM", OsrmParser.class), + ORS("Openroute Service", OrsParser.class), + GPX("GPX", GpxParser.class); private final String title; + private final Class parserClass; - EngineType(String title) { + EngineType(String title, Class parserClass) { this.title = title; + this.parserClass = parserClass; } public String getTitle() { return title; } + public Class getParserClass() { + return parserClass; + } + @NonNull public static EngineType getTypeByName(@Nullable String name) { if (!Algorithms.isEmpty(name)) { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java new file mode 100644 index 0000000000..557a98dc86 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java @@ -0,0 +1,57 @@ +package net.osmand.plus.onlinerouting.engine; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.data.LatLon; +import net.osmand.plus.onlinerouting.EngineParameter; +import net.osmand.plus.onlinerouting.VehicleType; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class GpxEngine extends OnlineRoutingEngine { + + public GpxEngine(@Nullable Map params) { + super(params); + } + + @NonNull + @Override + public EngineType getType() { + return EngineType.GPX; + } + + @Override + protected void makeFullUrl(@NonNull StringBuilder sb, + @NonNull List path) { + for (int i = 0; i < path.size(); i++) { + LatLon point = path.get(i); + sb.append(point.getLongitude()).append(',').append(point.getLatitude()); + if (i < path.size() - 1) { + sb.append(';'); + } + } + } + + @NonNull + @Override + public String getStandardUrl() { + return ""; // TODO will be determined in the future + } + + @Override + protected void collectAllowedVehicles(@NonNull List vehicles) { + + } + + @Override + protected void collectAllowedParameters(@NonNull Set params) { + params.add(EngineParameter.KEY); + params.add(EngineParameter.CUSTOM_NAME); + params.add(EngineParameter.NAME_INDEX); + params.add(EngineParameter.CUSTOM_URL); + } + +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java index 930ebcab8d..908973b6b4 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java @@ -3,23 +3,14 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import net.osmand.Location; import net.osmand.data.LatLon; -import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.routing.RouteDirectionInfo; -import net.osmand.router.TurnType; -import net.osmand.util.GeoPolylineParserUtil; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import static net.osmand.util.Algorithms.isEmpty; @@ -42,8 +33,13 @@ public class GraphhopperEngine extends OnlineRoutingEngine { } @Override - protected void collectAllowedParameters() { - allowParameters(EngineParameter.API_KEY); + protected void collectAllowedParameters(@NonNull Set params) { + params.add(EngineParameter.KEY); + params.add(EngineParameter.VEHICLE_KEY); + params.add(EngineParameter.CUSTOM_NAME); + params.add(EngineParameter.NAME_INDEX); + params.add(EngineParameter.CUSTOM_URL); + params.add(EngineParameter.API_KEY); } @Override @@ -81,146 +77,4 @@ public class GraphhopperEngine extends OnlineRoutingEngine { sb.append('&').append("details=").append("lanes"); } - @Nullable - @Override - public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException { - String encoded = root.getString("points"); - List points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); - if (isEmpty(points)) return null; - List route = convertRouteToLocationsList(points); - - JSONArray instructions = root.getJSONArray("instructions"); - List directions = new ArrayList<>(); - for (int i = 0; i < instructions.length(); i++) { - JSONObject instruction = instructions.getJSONObject(i); - int distance = (int) Math.round(instruction.getDouble("distance")); - String description = instruction.getString("text"); - String streetName = instruction.getString("street_name"); - int timeInSeconds = Math.round(instruction.getInt("time") / 1000f); - JSONArray interval = instruction.getJSONArray("interval"); - int startPointOffset = interval.getInt(0); - int endPointOffset = interval.getInt(1); - - float averageSpeed = (float) distance / timeInSeconds; - TurnType turnType = parseTurnType(instruction, leftSideNavigation); - RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); - - direction.routePointOffset = startPointOffset; - direction.setDescriptionRoute(description); - direction.setStreetName(streetName); - direction.setDistance(distance); - directions.add(direction); - } - return new OnlineRoutingResponse(route, directions); - } - - @NonNull - private TurnType parseTurnType(@NonNull JSONObject instruction, - boolean leftSide) throws JSONException { - int sign = instruction.getInt("sign"); - TurnType turnType = identifyTurnType(sign, leftSide); - - if (turnType == null) { - turnType = TurnType.straight(); - } else if (turnType.isRoundAbout()) { - if (instruction.has("exit_number")) { - int exit = instruction.getInt("exit_number"); - turnType.setExitOut(exit); - } - if (instruction.has("turn_angle")) { - float angle = (float) instruction.getDouble("turn_angle"); - turnType.setTurnAngle(angle); - } - } else { - // TODO turnType.setTurnAngle() - } - - return turnType; - } - - @Nullable - public static TurnType identifyTurnType(int sign, boolean leftSide) { - Integer id = null; - - if (sign == -98) { - // an U-turn without the knowledge - // if it is a right or left U-turn - id = TurnType.TU; - - } else if (sign == -8) { - // a left U-turn - leftSide = false; - id = TurnType.TU; - - } else if (sign == -7) { - // keep left - id = TurnType.KL; - - } else if (sign == -6) { - // not yet used: leave roundabout - - } else if (sign == -3) { - // turn sharp left - id = TurnType.TSHL; - - } else if (sign == -2) { - // turn left - id = TurnType.TL; - - } else if (sign == -1) { - // turn slight left - id = TurnType.TSLL; - - } else if (sign == 0) { - // continue on street - id = TurnType.C; - - } else if (sign == 1) { - // turn slight right - id = TurnType.TSLR; - - } else if (sign == 2) { - // turn right - id = TurnType.TR; - - } else if (sign == 3) { - // turn sharp right - id = TurnType.TSHR; - - } else if (sign == 4) { - // the finish instruction before the last point - id = TurnType.C; - - } else if (sign == 5) { - // the instruction before a via point - - } else if (sign == 6) { - // the instruction before entering a roundabout - id = TurnType.RNDB; - - } else if (sign == 7) { - // keep right - id = TurnType.KR; - - } else if (sign == 8) { - // a right U-turn - id = TurnType.TRU; - } - - return id != null ? TurnType.valueOf(id, leftSide) : null; - } - - @NonNull - @Override - protected String getErrorMessageKey() { - return "message"; - } - - @NonNull - @Override - protected String getRootArrayKey() { - return "paths"; - } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java index 0752282c70..119b63ee9c 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java @@ -7,22 +7,19 @@ import androidx.annotation.Nullable; import net.osmand.GPXUtilities.WptPt; import net.osmand.Location; +import net.osmand.PlatformUtil; import net.osmand.data.LatLon; -import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingFactory; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.routing.RouteDirectionInfo; +import net.osmand.plus.onlinerouting.parser.ResponseParser; import net.osmand.plus.routing.RouteProvider; import net.osmand.util.Algorithms; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; +import org.apache.commons.logging.Log; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -34,19 +31,22 @@ import static net.osmand.util.Algorithms.isEmpty; public abstract class OnlineRoutingEngine implements Cloneable { + protected static final Log LOG = PlatformUtil.getLog(OnlineRoutingEngine.class); + public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_"; public final static VehicleType CUSTOM_VEHICLE = new VehicleType("", R.string.shared_string_custom); private final Map params = new HashMap<>(); private final List allowedVehicles = new ArrayList<>(); private final Set allowedParameters = new HashSet<>(); + private ResponseParser responseParser; public OnlineRoutingEngine(@Nullable Map params) { if (!isEmpty(params)) { this.params.putAll(params); } collectAllowedVehiclesInternal(); - collectAllowedParametersInternal(); + collectAllowedParameters(allowedParameters); } @NonNull @@ -100,31 +100,25 @@ public abstract class OnlineRoutingEngine implements Cloneable { @NonNull public abstract String getStandardUrl(); - public OnlineRoutingResponse parseServerResponse(@NonNull String content, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException { - JSONObject root = parseRootResponseObject(content); - return root != null ? parseServerResponse(root, app, leftSideNavigation) : null; - } - - @Nullable - protected abstract OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException; - - @Nullable - protected JSONObject parseRootResponseObject(@NonNull String content) throws JSONException { - JSONObject fullJSON = new JSONObject(content); - String responseArrayKey = getRootArrayKey(); - JSONArray array = null; - if (fullJSON.has(responseArrayKey)) { - array = fullJSON.getJSONArray(responseArrayKey); + @NonNull + public ResponseParser getResponseParser() { + if (responseParser == null) { + responseParser = createParser(); } - return array != null && array.length() > 0 ? array.getJSONObject(0) : null; + return responseParser; } @NonNull - protected abstract String getRootArrayKey(); + protected ResponseParser createParser() { + try { + return getType().getParserClass().newInstance(); + } catch (IllegalAccessException e) { + LOG.debug("Error when create parser: " + e.getMessage()); + } catch (InstantiationException e) { + LOG.debug("Error when create parser: " + e.getMessage()); + } + return ResponseParser.emptyParser(); + } @NonNull protected List convertRouteToLocationsList(@NonNull List route) { @@ -171,23 +165,12 @@ public abstract class OnlineRoutingEngine implements Cloneable { return Collections.unmodifiableList(allowedVehicles); } - private void collectAllowedParametersInternal() { - allowedParameters.clear(); - allowParameters(EngineParameter.KEY, EngineParameter.VEHICLE_KEY, - EngineParameter.CUSTOM_NAME, EngineParameter.NAME_INDEX, EngineParameter.CUSTOM_URL); - collectAllowedParameters(); - } - - protected abstract void collectAllowedParameters(); + protected abstract void collectAllowedParameters(@NonNull Set params); public boolean isParameterAllowed(EngineParameter key) { return allowedParameters.contains(key); } - protected void allowParameters(@NonNull EngineParameter... allowedParams) { - allowedParameters.addAll(Arrays.asList(allowedParams)); - } - @Nullable private String getSelectedVehicleName(@NonNull Context ctx) { String key = get(EngineParameter.VEHICLE_KEY); @@ -216,20 +199,6 @@ public abstract class OnlineRoutingEngine implements Cloneable { return CUSTOM_VEHICLE; } - public boolean checkServerResponse(@NonNull StringBuilder errorMessage, - @NonNull String content) throws JSONException { - JSONObject obj = new JSONObject(content); - String messageKey = getErrorMessageKey(); - if (obj.has(messageKey)) { - String message = obj.getString(messageKey); - errorMessage.append(message); - } - return obj.has(getRootArrayKey()); - } - - @NonNull - protected abstract String getErrorMessageKey(); - @NonNull @Override public Object clone() { @@ -251,21 +220,4 @@ public abstract class OnlineRoutingEngine implements Cloneable { return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis(); } - public static class OnlineRoutingResponse { - private List route; - private List directions; - - public OnlineRoutingResponse(List route, List directions) { - this.route = route; - this.directions = directions; - } - - public List getRoute() { - return route; - } - - public List getDirections() { - return directions; - } - } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java index ed9168ccf9..61f3097b04 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java @@ -3,20 +3,14 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import net.osmand.Location; import net.osmand.data.LatLon; -import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import static net.osmand.util.Algorithms.isEmpty; @@ -39,8 +33,13 @@ public class OrsEngine extends OnlineRoutingEngine { } @Override - protected void collectAllowedParameters() { - allowParameters(EngineParameter.API_KEY); + protected void collectAllowedParameters(@NonNull Set params) { + params.add(EngineParameter.KEY); + params.add(EngineParameter.VEHICLE_KEY); + params.add(EngineParameter.CUSTOM_NAME); + params.add(EngineParameter.NAME_INDEX); + params.add(EngineParameter.CUSTOM_URL); + params.add(EngineParameter.API_KEY); } @Override @@ -78,35 +77,4 @@ public class OrsEngine extends OnlineRoutingEngine { } } - @Nullable - @Override - public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException { - JSONArray array = root.getJSONObject("geometry").getJSONArray("coordinates"); - List points = new ArrayList<>(); - for (int i = 0; i < array.length(); i++) { - JSONArray point = array.getJSONArray(i); - double lon = Double.parseDouble(point.getString(0)); - double lat = Double.parseDouble(point.getString(1)); - points.add(new LatLon(lat, lon)); - } - if (!isEmpty(points)) { - List route = convertRouteToLocationsList(points); - new OnlineRoutingResponse(route, null); - } - return null; - } - - @NonNull - @Override - protected String getErrorMessageKey() { - return "error"; - } - - @NonNull - @Override - protected String getRootArrayKey() { - return "features"; - } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java index 4d75b2b440..1da2ed215e 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java @@ -3,28 +3,16 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import net.osmand.Location; import net.osmand.data.LatLon; -import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.routing.RouteCalculationResult; -import net.osmand.plus.routing.RouteDirectionInfo; -import net.osmand.router.TurnType; -import net.osmand.util.GeoPolylineParserUtil; -import net.osmand.util.MapUtils; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import static net.osmand.util.Algorithms.isEmpty; -import static net.osmand.util.Algorithms.objectEquals; public class OsrmEngine extends OnlineRoutingEngine { @@ -45,7 +33,12 @@ public class OsrmEngine extends OnlineRoutingEngine { } @Override - protected void collectAllowedParameters() { + protected void collectAllowedParameters(@NonNull Set params) { + params.add(EngineParameter.KEY); + params.add(EngineParameter.VEHICLE_KEY); + params.add(EngineParameter.CUSTOM_NAME); + params.add(EngineParameter.NAME_INDEX); + params.add(EngineParameter.CUSTOM_URL); } @Override @@ -74,164 +67,4 @@ public class OsrmEngine extends OnlineRoutingEngine { sb.append('&').append("steps=true"); } - @Nullable - @Override - public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException { - String encodedPoints = root.getString("geometry"); - List points = GeoPolylineParserUtil.parse(encodedPoints, GeoPolylineParserUtil.PRECISION_5); - if (isEmpty(points)) return null; - - List route = convertRouteToLocationsList(points); - List directions = new ArrayList<>(); - int startSearchingId = 0; - JSONArray legs = root.getJSONArray("legs"); - for (int i = 0; i < legs.length(); i++) { - JSONObject leg = legs.getJSONObject(i); - if (!leg.has("steps")) continue; - - JSONArray steps = leg.getJSONArray("steps"); - for (int j = 0; j < steps.length(); j++) { - JSONObject instruction = steps.getJSONObject(j); - JSONObject maneuver = instruction.getJSONObject("maneuver"); - String maneuverType = maneuver.getString("type"); - - JSONArray location = maneuver.getJSONArray("location"); - double lon = location.getDouble(0); - double lat = location.getDouble(1); - Integer routePointOffset = getLocationIndexInList(route, startSearchingId, lat, lon); - if (routePointOffset == null) continue; - startSearchingId = routePointOffset; - - // in meters - int distance = (int) Math.round(instruction.getDouble("distance")); - // in seconds - int duration = (int) Math.round(instruction.getDouble("duration")); - - float averageSpeed = (float) distance / duration; - TurnType turnType = parseTurnType(maneuver, leftSideNavigation); - RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); - direction.setDistance(distance); - - String streetName = instruction.getString("name"); - String description = ""; - if (!objectEquals(maneuverType, "arrive")) { - description = RouteCalculationResult.toString(turnType, app, false) + " " + streetName; - } - description = description.trim(); - - direction.setStreetName(streetName); - direction.setDescriptionRoute(description); - direction.routePointOffset = routePointOffset; - directions.add(direction); - } - } - - return new OnlineRoutingResponse(route, directions); - } - - @Nullable - private Integer getLocationIndexInList(@NonNull List locations, - int startIndex, double lat, double lon) { - for (int i = startIndex; i < locations.size(); i++) { - Location l = locations.get(i); - if (MapUtils.areLatLonEqual(l, lat, lon)) { - return i; - } - } - return null; - } - - @NonNull - private TurnType parseTurnType(@NonNull JSONObject maneuver, - boolean leftSide) throws JSONException { - TurnType turnType = null; - - String type = maneuver.getString("type"); - String modifier = null; - if (maneuver.has("modifier")) { - modifier = maneuver.getString("modifier"); - } - - if (objectEquals(type, "roundabout") - || objectEquals(type, "rotary") - || objectEquals(type, "roundabout turn")) { - if (maneuver.has("exit")) { - int exit = maneuver.getInt("exit"); - turnType = TurnType.getExitTurn(exit, 0.0f, leftSide); - } else if (modifier != null) { - // for simple roundabout turn without "exit" parameter - turnType = identifyTurnType(modifier, leftSide); - } - } else { - // for other maneuver types find TurnType - // like a basic turn into direction of the modifier - if (modifier != null) { - turnType = identifyTurnType(modifier, leftSide); - } - } - if (turnType == null) { - turnType = TurnType.straight(); - } - - int bearingBefore = maneuver.getInt("bearing_before"); - int bearingAfter = maneuver.getInt("bearing_after"); - float angle = (float) MapUtils.degreesDiff(bearingAfter, bearingBefore); - turnType.setTurnAngle(angle); - - return turnType; - } - - @Nullable - private TurnType identifyTurnType(@NonNull String modifier, - boolean leftSide) { - Integer id = null; - switch (modifier) { - case "uturn": - id = TurnType.TU; - break; - - case "sharp right": - id = TurnType.TSHR; - break; - - case "right": - id = TurnType.TR; - break; - - case "slight right": - id = TurnType.TSLR; - break; - - case "straight": - id = TurnType.C; - break; - - case "slight left": - id = TurnType.TSLL; - break; - - case "left": - id = TurnType.TL; - break; - - case "sharp left": - id = TurnType.TSHL; - break; - } - return id != null ? TurnType.valueOf(id, leftSide) : null; - } - - @NonNull - @Override - protected String getErrorMessageKey() { - return "message"; - } - - @NonNull - @Override - protected String getRootArrayKey() { - return "routes"; - } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java new file mode 100644 index 0000000000..8f5db5fde7 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java @@ -0,0 +1,42 @@ +package net.osmand.plus.onlinerouting.parser; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.plus.OsmandApplication; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +public class GpxParser extends ResponseParser { + + @Override + @Nullable + public OnlineRoutingResponse parseResponse(@NonNull String content, + @NonNull OsmandApplication app, + boolean leftSideNavigation) { + GPXFile gpxFile = parseGpx(content); + return gpxFile != null ? new OnlineRoutingResponse(parseGpx(content)) : null; + } + + @Override + public boolean isResultOk(@NonNull StringBuilder errorMessage, + @NonNull String content) { + return parseGpx(content) != null; // TODO may be there should be another check + } + + private GPXFile parseGpx(@NonNull String content) { + InputStream gpxStream = null; + try { + gpxStream = new ByteArrayInputStream(content.getBytes("UTF-8")); + return GPXUtilities.loadGPXFile(gpxStream); + } catch (UnsupportedEncodingException e) { + LOG.debug("Error when parsing GPX from server response: " + e.getMessage()); + } + return null; + } + +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GraphhopperParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GraphhopperParser.java new file mode 100644 index 0000000000..331221ad09 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GraphhopperParser.java @@ -0,0 +1,165 @@ +package net.osmand.plus.onlinerouting.parser; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.Location; +import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.routing.RouteDirectionInfo; +import net.osmand.router.TurnType; +import net.osmand.util.GeoPolylineParserUtil; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +import static net.osmand.util.Algorithms.isEmpty; + +public class GraphhopperParser extends JSONParser { + + @Nullable + protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + String encoded = root.getString("points"); + List points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); + if (isEmpty(points)) return null; + List route = convertRouteToLocationsList(points); + + JSONArray instructions = root.getJSONArray("instructions"); + List directions = new ArrayList<>(); + for (int i = 0; i < instructions.length(); i++) { + JSONObject instruction = instructions.getJSONObject(i); + int distance = (int) Math.round(instruction.getDouble("distance")); + String description = instruction.getString("text"); + String streetName = instruction.getString("street_name"); + int timeInSeconds = Math.round(instruction.getInt("time") / 1000f); + JSONArray interval = instruction.getJSONArray("interval"); + int startPointOffset = interval.getInt(0); + int endPointOffset = interval.getInt(1); + + float averageSpeed = (float) distance / timeInSeconds; + TurnType turnType = parseTurnType(instruction, leftSideNavigation); + RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); + + direction.routePointOffset = startPointOffset; + direction.setDescriptionRoute(description); + direction.setStreetName(streetName); + direction.setDistance(distance); + directions.add(direction); + } + return new OnlineRoutingResponse(route, directions); + } + + @NonNull + private TurnType parseTurnType(@NonNull JSONObject instruction, + boolean leftSide) throws JSONException { + int sign = instruction.getInt("sign"); + TurnType turnType = identifyTurnType(sign, leftSide); + + if (turnType == null) { + turnType = TurnType.straight(); + } else if (turnType.isRoundAbout()) { + if (instruction.has("exit_number")) { + int exit = instruction.getInt("exit_number"); + turnType.setExitOut(exit); + } + if (instruction.has("turn_angle")) { + float angle = (float) instruction.getDouble("turn_angle"); + turnType.setTurnAngle(angle); + } + } else { + // TODO turnType.setTurnAngle() + } + + return turnType; + } + + @Nullable + public static TurnType identifyTurnType(int sign, boolean leftSide) { + Integer id = null; + + if (sign == -98) { + // an U-turn without the knowledge + // if it is a right or left U-turn + id = TurnType.TU; + + } else if (sign == -8) { + // a left U-turn + leftSide = false; + id = TurnType.TU; + + } else if (sign == -7) { + // keep left + id = TurnType.KL; + + } else if (sign == -6) { + // not yet used: leave roundabout + + } else if (sign == -3) { + // turn sharp left + id = TurnType.TSHL; + + } else if (sign == -2) { + // turn left + id = TurnType.TL; + + } else if (sign == -1) { + // turn slight left + id = TurnType.TSLL; + + } else if (sign == 0) { + // continue on street + id = TurnType.C; + + } else if (sign == 1) { + // turn slight right + id = TurnType.TSLR; + + } else if (sign == 2) { + // turn right + id = TurnType.TR; + + } else if (sign == 3) { + // turn sharp right + id = TurnType.TSHR; + + } else if (sign == 4) { + // the finish instruction before the last point + id = TurnType.C; + + } else if (sign == 5) { + // the instruction before a via point + + } else if (sign == 6) { + // the instruction before entering a roundabout + id = TurnType.RNDB; + + } else if (sign == 7) { + // keep right + id = TurnType.KR; + + } else if (sign == 8) { + // a right U-turn + id = TurnType.TRU; + } + + return id != null ? TurnType.valueOf(id, leftSide) : null; + } + + @NonNull + @Override + protected String getErrorMessageKey() { + return "message"; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "paths"; + } +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java new file mode 100644 index 0000000000..b01af0c444 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java @@ -0,0 +1,77 @@ +package net.osmand.plus.onlinerouting.parser; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.GPXUtilities.WptPt; +import net.osmand.Location; +import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.routing.RouteProvider; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +import static net.osmand.util.Algorithms.isEmpty; + +public abstract class JSONParser extends ResponseParser { + + @Nullable + public OnlineRoutingResponse parseResponse(@NonNull String content, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + JSONObject root = parseRootResponseObject(content); + return root != null ? parseServerResponse(root, app, leftSideNavigation) : null; + } + + @Nullable + protected JSONObject parseRootResponseObject(@NonNull String content) throws JSONException { + JSONObject fullJSON = new JSONObject(content); + String key = getRootArrayKey(); + JSONArray array = null; + if (fullJSON.has(key)) { + array = fullJSON.getJSONArray(key); + } + return array != null && array.length() > 0 ? array.getJSONObject(0) : null; + } + + public boolean isResultOk(@NonNull StringBuilder errorMessage, + @NonNull String content) throws JSONException { + JSONObject obj = new JSONObject(content); + String messageKey = getErrorMessageKey(); + if (obj.has(messageKey)) { + String message = obj.getString(messageKey); + errorMessage.append(message); + } + return obj.has(getRootArrayKey()); + } + + @NonNull + protected List convertRouteToLocationsList(@NonNull List route) { + List result = new ArrayList<>(); + if (!isEmpty(route)) { + for (LatLon pt : route) { + WptPt wpt = new WptPt(); + wpt.lat = pt.getLatitude(); + wpt.lon = pt.getLongitude(); + result.add(RouteProvider.createLocation(wpt)); + } + } + return result; + } + + @Nullable + protected abstract OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException; + + @NonNull + protected abstract String getRootArrayKey(); + + @NonNull + protected abstract String getErrorMessageKey(); +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/OrsParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/OrsParser.java new file mode 100644 index 0000000000..f067baf61e --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/OrsParser.java @@ -0,0 +1,52 @@ +package net.osmand.plus.onlinerouting.parser; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.Location; +import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +import static net.osmand.util.Algorithms.isEmpty; + +public class OrsParser extends JSONParser { + + @Nullable + @Override + public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + JSONArray array = root.getJSONObject("geometry").getJSONArray("coordinates"); + List points = new ArrayList<>(); + for (int i = 0; i < array.length(); i++) { + JSONArray point = array.getJSONArray(i); + double lon = Double.parseDouble(point.getString(0)); + double lat = Double.parseDouble(point.getString(1)); + points.add(new LatLon(lat, lon)); + } + if (!isEmpty(points)) { + List route = convertRouteToLocationsList(points); + new OnlineRoutingResponse(route, null); + } + return null; + } + + @NonNull + @Override + protected String getErrorMessageKey() { + return "error"; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "features"; + } +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/OsrmParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/OsrmParser.java new file mode 100644 index 0000000000..8c93f1750e --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/OsrmParser.java @@ -0,0 +1,187 @@ +package net.osmand.plus.onlinerouting.parser; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.Location; +import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.routing.RouteCalculationResult; +import net.osmand.plus.routing.RouteDirectionInfo; +import net.osmand.router.TurnType; +import net.osmand.util.GeoPolylineParserUtil; +import net.osmand.util.MapUtils; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +import static net.osmand.util.Algorithms.isEmpty; +import static net.osmand.util.Algorithms.objectEquals; + +public class OsrmParser extends JSONParser { + + @Nullable + @Override + protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + String encodedPoints = root.getString("geometry"); + List points = GeoPolylineParserUtil.parse(encodedPoints, GeoPolylineParserUtil.PRECISION_5); + if (isEmpty(points)) return null; + + List route = convertRouteToLocationsList(points); + List directions = new ArrayList<>(); + int startSearchingId = 0; + JSONArray legs = root.getJSONArray("legs"); + for (int i = 0; i < legs.length(); i++) { + JSONObject leg = legs.getJSONObject(i); + if (!leg.has("steps")) continue; + + JSONArray steps = leg.getJSONArray("steps"); + for (int j = 0; j < steps.length(); j++) { + JSONObject instruction = steps.getJSONObject(j); + JSONObject maneuver = instruction.getJSONObject("maneuver"); + String maneuverType = maneuver.getString("type"); + + JSONArray location = maneuver.getJSONArray("location"); + double lon = location.getDouble(0); + double lat = location.getDouble(1); + Integer routePointOffset = getLocationIndexInList(route, startSearchingId, lat, lon); + if (routePointOffset == null) continue; + startSearchingId = routePointOffset; + + // in meters + int distance = (int) Math.round(instruction.getDouble("distance")); + // in seconds + int duration = (int) Math.round(instruction.getDouble("duration")); + + float averageSpeed = (float) distance / duration; + TurnType turnType = parseTurnType(maneuver, leftSideNavigation); + RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); + direction.setDistance(distance); + + String streetName = instruction.getString("name"); + String description = ""; + if (!objectEquals(maneuverType, "arrive")) { + description = RouteCalculationResult.toString(turnType, app, false) + " " + streetName; + } + description = description.trim(); + + direction.setStreetName(streetName); + direction.setDescriptionRoute(description); + direction.routePointOffset = routePointOffset; + directions.add(direction); + } + } + + return new OnlineRoutingResponse(route, directions); + } + + @Nullable + private Integer getLocationIndexInList(@NonNull List locations, + int startIndex, double lat, double lon) { + for (int i = startIndex; i < locations.size(); i++) { + Location l = locations.get(i); + if (MapUtils.areLatLonEqual(l, lat, lon)) { + return i; + } + } + return null; + } + + @NonNull + private TurnType parseTurnType(@NonNull JSONObject maneuver, + boolean leftSide) throws JSONException { + TurnType turnType = null; + + String type = maneuver.getString("type"); + String modifier = null; + if (maneuver.has("modifier")) { + modifier = maneuver.getString("modifier"); + } + + if (objectEquals(type, "roundabout") + || objectEquals(type, "rotary") + || objectEquals(type, "roundabout turn")) { + if (maneuver.has("exit")) { + int exit = maneuver.getInt("exit"); + turnType = TurnType.getExitTurn(exit, 0.0f, leftSide); + } else if (modifier != null) { + // for simple roundabout turn without "exit" parameter + turnType = identifyTurnType(modifier, leftSide); + } + } else { + // for other maneuver types find TurnType + // like a basic turn into direction of the modifier + if (modifier != null) { + turnType = identifyTurnType(modifier, leftSide); + } + } + if (turnType == null) { + turnType = TurnType.straight(); + } + + int bearingBefore = maneuver.getInt("bearing_before"); + int bearingAfter = maneuver.getInt("bearing_after"); + float angle = (float) MapUtils.degreesDiff(bearingAfter, bearingBefore); + turnType.setTurnAngle(angle); + + return turnType; + } + + @Nullable + private TurnType identifyTurnType(@NonNull String modifier, + boolean leftSide) { + Integer id = null; + switch (modifier) { + case "uturn": + id = TurnType.TU; + break; + + case "sharp right": + id = TurnType.TSHR; + break; + + case "right": + id = TurnType.TR; + break; + + case "slight right": + id = TurnType.TSLR; + break; + + case "straight": + id = TurnType.C; + break; + + case "slight left": + id = TurnType.TSLL; + break; + + case "left": + id = TurnType.TL; + break; + + case "sharp left": + id = TurnType.TSHL; + break; + } + return id != null ? TurnType.valueOf(id, leftSide) : null; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "routes"; + } + + @NonNull + @Override + protected String getErrorMessageKey() { + return "message"; + } +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/ResponseParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/ResponseParser.java new file mode 100644 index 0000000000..62cf7e0f44 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/ResponseParser.java @@ -0,0 +1,77 @@ +package net.osmand.plus.onlinerouting.parser; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.Location; +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.routing.RouteDirectionInfo; + +import org.apache.commons.logging.Log; +import org.json.JSONException; + +import java.util.List; + +public abstract class ResponseParser { + + protected static final Log LOG = PlatformUtil.getLog(ResponseParser.class); + + @Nullable + public abstract OnlineRoutingResponse parseResponse(@NonNull String content, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException; + + public abstract boolean isResultOk(@NonNull StringBuilder errorMessage, + @NonNull String content) throws JSONException; + + public static ResponseParser emptyParser() { + return new ResponseParser() { + @Nullable + @Override + public OnlineRoutingResponse parseResponse(@NonNull String content, + @NonNull OsmandApplication app, + boolean leftSideNavigation) { + return null; + } + + @Override + public boolean isResultOk(@NonNull StringBuilder errorMessage, + @NonNull String content) { + return false; + } + }; + } + + public static class OnlineRoutingResponse { + + private List route; + private List directions; + private GPXFile gpxFile; + + // constructor for JSON responses + public OnlineRoutingResponse(List route, List directions) { + this.route = route; + this.directions = directions; + } + + // constructor for GPX responses + public OnlineRoutingResponse(GPXFile gpxFile) { + this.gpxFile = gpxFile; + } + + public List getRoute() { + return route; + } + + public List getDirections() { + return directions; + } + + public GPXFile getGpxFile() { + return gpxFile; + } + } + +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java index 008bb75852..4f626569d7 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java @@ -462,7 +462,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { boolean resultOk = false; try { String response = helper.makeRequest(exampleCard.getEditedText()); - resultOk = requestedEngine.checkServerResponse(errorMessage, response); + resultOk = requestedEngine.getResponseParser().isResultOk(errorMessage, response); } catch (IOException | JSONException e) { errorMessage.append(e.toString()); } @@ -514,6 +514,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } else { apiKeyCard.hide(); } + if (engine.isParameterAllowed(EngineParameter.VEHICLE_KEY)) { + vehicleCard.show(); + } else { + + vehicleCard.hide(); + } } else if (vehicleCard.equals(card)) { VehicleType vt = engine.getSelectedVehicleType(); diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 3f0a30c99f..0eb5a74e52 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -23,7 +23,7 @@ import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.onlinerouting.OnlineRoutingHelper; -import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse; +import net.osmand.plus.onlinerouting.parser.ResponseParser.OnlineRoutingResponse; import net.osmand.plus.render.NativeOsmandLibrary; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.CommonPreference; @@ -1228,16 +1228,28 @@ public class RouteProvider { } private RouteCalculationResult findOnlineRoute(RouteCalculationParams params) throws IOException, JSONException { - OnlineRoutingHelper helper = params.ctx.getOnlineRoutingHelper(); - String stringKey = params.mode.getRoutingProfile(); + OsmandApplication app = params.ctx; + OnlineRoutingHelper helper = app.getOnlineRoutingHelper(); + OsmandSettings settings = app.getSettings(); + String engineKey = params.mode.getRoutingProfile(); OnlineRoutingResponse response = - helper.calculateRouteOnline(stringKey, getPathFromParams(params), params.leftSide); + helper.calculateRouteOnline(engineKey, getPathFromParams(params), params.leftSide); + if (response != null) { - params.intermediates = null; - return new RouteCalculationResult(response.getRoute(), response.getDirections(), params, null, false); - } else { - return new RouteCalculationResult("Route is empty"); + if (response.getGpxFile() != null) { + GPXRouteParamsBuilder builder = new GPXRouteParamsBuilder(response.getGpxFile(), settings); + params.gpxRoute = builder.build(app); + return calculateGpxRoute(params); + } + List route = response.getRoute(); + List directions = response.getDirections(); + if (!Algorithms.isEmpty(route) && !Algorithms.isEmpty(directions)) { + params.intermediates = null; + return new RouteCalculationResult(route, directions, params, null, false); + } } + + return new RouteCalculationResult("Route is empty"); } private static List getPathFromParams(RouteCalculationParams params) { From e44f7634059159839181985319b516ced966f105 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 22 Feb 2021 13:14:10 +0200 Subject: [PATCH 02/29] Check ZIP and GZIP formats --- .../main/java/net/osmand/util/Algorithms.java | 30 +++++++++++++++++++ .../onlinerouting/OnlineRoutingHelper.java | 21 ++++++++----- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java index 247fc30ced..8954e2d61b 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java @@ -324,6 +324,24 @@ public class Algorithms { return test == ZIP_FILE_SIGNATURE; } + public static boolean checkFileSignature(InputStream inputStream, int fileSignature) throws IOException { + if (inputStream == null) return false; + int firstBytes; + if (isSmallFileSignature(fileSignature)) { + firstBytes = readSmallInt(inputStream); + } else { + firstBytes = readInt(inputStream); + } + if (inputStream.markSupported()) { + inputStream.reset(); + } + return firstBytes == fileSignature; + } + + public static boolean isSmallFileSignature(int fileSignature) { + return fileSignature == BZIP_FILE_SIGNATURE || fileSignature == GZIP_FILE_SIGNATURE; + } + /** * Checks, whether the child directory is a subdirectory of the parent * directory. @@ -547,6 +565,18 @@ public class Algorithms { } } + public static ByteArrayInputStream createByteArrayIS(InputStream inputStream) throws IOException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + int i = 0; + while ((i = inputStream.read()) != -1) { + outputStream.write(i); + } + inputStream.close(); + + byte[] byteArray = outputStream.toByteArray(); + return new ByteArrayInputStream(byteArray); + } + @SuppressWarnings("ResultOfMethodCallIgnored") public static void updateAllExistingImgTilesToOsmandFormat(File f) { if (f.isDirectory()) { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index 079cfd8a12..503977c7b7 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -19,6 +19,7 @@ import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -28,7 +29,10 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.zip.GZIPInputStream; +import java.util.zip.ZipInputStream; +import static net.osmand.util.Algorithms.GZIP_FILE_SIGNATURE; +import static net.osmand.util.Algorithms.ZIP_FILE_SIGNATURE; import static net.osmand.util.Algorithms.isEmpty; public class OnlineRoutingHelper { @@ -118,14 +122,15 @@ public class OnlineRoutingHelper { } private InputStream getInputStream(@NonNull HttpURLConnection connection) throws IOException { - // todo check file signature correctly -// InputStream is = connection.getInputStream(); -// int header = Algorithms.readTwoInt(is); -// boolean isGzipFile = header == Algorithms.GZIP_FILE_SIGNATURE; -// if (isGzipFile) { -// return new GZIPInputStream(connection.getInputStream()); -// } - return connection.getInputStream(); + ByteArrayInputStream localIS = Algorithms.createByteArrayIS(connection.getInputStream()); + if (Algorithms.checkFileSignature(localIS, ZIP_FILE_SIGNATURE)) { + ZipInputStream zipIS = new ZipInputStream(localIS); + zipIS.getNextEntry(); // set position to reading for the first item + return zipIS; + } else if (Algorithms.checkFileSignature(localIS, GZIP_FILE_SIGNATURE)) { + return new GZIPInputStream(localIS); + } + return localIS; } public void saveEngine(@NonNull OnlineRoutingEngine engine) { From fab1df33a6561a2ff52e9d9e6dc7314a0d57f4bf Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 22 Feb 2021 13:44:49 +0200 Subject: [PATCH 03/29] Refactoring: change parser location, remove todo --- .../plus/onlinerouting/engine/EngineType.java | 21 +- .../plus/onlinerouting/engine/GpxEngine.java | 9 +- .../engine/GraphhopperEngine.java | 162 +++++++++++++++ .../engine/OnlineRoutingEngine.java | 28 +-- .../plus/onlinerouting/engine/OrsEngine.java | 49 +++++ .../plus/onlinerouting/engine/OsrmEngine.java | 184 +++++++++++++++++ .../plus/onlinerouting/parser/GpxParser.java | 2 +- .../parser/GraphhopperParser.java | 165 ---------------- .../plus/onlinerouting/parser/JSONParser.java | 24 +-- .../plus/onlinerouting/parser/OrsParser.java | 52 ----- .../plus/onlinerouting/parser/OsrmParser.java | 187 ------------------ 11 files changed, 422 insertions(+), 461 deletions(-) delete mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/parser/GraphhopperParser.java delete mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/parser/OrsParser.java delete mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/parser/OsrmParser.java diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java index 41e10b1dd3..0efd91e759 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java @@ -3,35 +3,24 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import net.osmand.plus.onlinerouting.parser.GpxParser; -import net.osmand.plus.onlinerouting.parser.GraphhopperParser; -import net.osmand.plus.onlinerouting.parser.OrsParser; -import net.osmand.plus.onlinerouting.parser.OsrmParser; -import net.osmand.plus.onlinerouting.parser.ResponseParser; import net.osmand.util.Algorithms; public enum EngineType { - GRAPHHOPPER("Graphhopper", GraphhopperParser.class), - OSRM("OSRM", OsrmParser.class), - ORS("Openroute Service", OrsParser.class), - GPX("GPX", GpxParser.class); + GRAPHHOPPER("Graphhopper"), + OSRM("OSRM"), + ORS("Openroute Service"), + GPX("GPX"); private final String title; - private final Class parserClass; - EngineType(String title, Class parserClass) { + EngineType(String title) { this.title = title; - this.parserClass = parserClass; } public String getTitle() { return title; } - public Class getParserClass() { - return parserClass; - } - @NonNull public static EngineType getTypeByName(@Nullable String name) { if (!Algorithms.isEmpty(name)) { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java index 557a98dc86..1f6146273d 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java @@ -6,6 +6,8 @@ import androidx.annotation.Nullable; import net.osmand.data.LatLon; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; +import net.osmand.plus.onlinerouting.parser.GpxParser; +import net.osmand.plus.onlinerouting.parser.ResponseParser; import java.util.List; import java.util.Map; @@ -38,7 +40,7 @@ public class GpxEngine extends OnlineRoutingEngine { @NonNull @Override public String getStandardUrl() { - return ""; // TODO will be determined in the future + return ""; } @Override @@ -54,4 +56,9 @@ public class GpxEngine extends OnlineRoutingEngine { params.add(EngineParameter.CUSTOM_URL); } + @NonNull + @Override + protected ResponseParser createParser() { + return new GpxParser(); + } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java index 908973b6b4..14852e2633 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java @@ -3,11 +3,23 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.Location; import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; +import net.osmand.plus.onlinerouting.parser.JSONParser; +import net.osmand.plus.onlinerouting.parser.ResponseParser; +import net.osmand.plus.routing.RouteDirectionInfo; +import net.osmand.router.TurnType; +import net.osmand.util.GeoPolylineParserUtil; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; @@ -55,6 +67,12 @@ public class GraphhopperEngine extends OnlineRoutingEngine { vehicles.add(new VehicleType("small_truck", R.string.routing_engine_vehicle_type_small_truck)); } + @NonNull + @Override + protected ResponseParser createParser() { + return new GraphhopperParser(); + } + @Override protected void makeFullUrl(@NonNull StringBuilder sb, @NonNull List path) { @@ -77,4 +95,148 @@ public class GraphhopperEngine extends OnlineRoutingEngine { sb.append('&').append("details=").append("lanes"); } + private static class GraphhopperParser extends JSONParser { + + @Nullable + protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + String encoded = root.getString("points"); + List points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); + if (isEmpty(points)) return null; + List route = convertRouteToLocationsList(points); + + JSONArray instructions = root.getJSONArray("instructions"); + List directions = new ArrayList<>(); + for (int i = 0; i < instructions.length(); i++) { + JSONObject instruction = instructions.getJSONObject(i); + int distance = (int) Math.round(instruction.getDouble("distance")); + String description = instruction.getString("text"); + String streetName = instruction.getString("street_name"); + int timeInSeconds = Math.round(instruction.getInt("time") / 1000f); + JSONArray interval = instruction.getJSONArray("interval"); + int startPointOffset = interval.getInt(0); + int endPointOffset = interval.getInt(1); + + float averageSpeed = (float) distance / timeInSeconds; + TurnType turnType = parseTurnType(instruction, leftSideNavigation); + RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); + + direction.routePointOffset = startPointOffset; + direction.setDescriptionRoute(description); + direction.setStreetName(streetName); + direction.setDistance(distance); + directions.add(direction); + } + return new OnlineRoutingResponse(route, directions); + } + + @NonNull + private TurnType parseTurnType(@NonNull JSONObject instruction, + boolean leftSide) throws JSONException { + int sign = instruction.getInt("sign"); + TurnType turnType = identifyTurnType(sign, leftSide); + + if (turnType == null) { + turnType = TurnType.straight(); + } else if (turnType.isRoundAbout()) { + if (instruction.has("exit_number")) { + int exit = instruction.getInt("exit_number"); + turnType.setExitOut(exit); + } + if (instruction.has("turn_angle")) { + float angle = (float) instruction.getDouble("turn_angle"); + turnType.setTurnAngle(angle); + } + } else { + // TODO turnType.setTurnAngle() + } + + return turnType; + } + + @Nullable + public static TurnType identifyTurnType(int sign, boolean leftSide) { + Integer id = null; + + if (sign == -98) { + // an U-turn without the knowledge + // if it is a right or left U-turn + id = TurnType.TU; + + } else if (sign == -8) { + // a left U-turn + leftSide = false; + id = TurnType.TU; + + } else if (sign == -7) { + // keep left + id = TurnType.KL; + + } else if (sign == -6) { + // not yet used: leave roundabout + + } else if (sign == -3) { + // turn sharp left + id = TurnType.TSHL; + + } else if (sign == -2) { + // turn left + id = TurnType.TL; + + } else if (sign == -1) { + // turn slight left + id = TurnType.TSLL; + + } else if (sign == 0) { + // continue on street + id = TurnType.C; + + } else if (sign == 1) { + // turn slight right + id = TurnType.TSLR; + + } else if (sign == 2) { + // turn right + id = TurnType.TR; + + } else if (sign == 3) { + // turn sharp right + id = TurnType.TSHR; + + } else if (sign == 4) { + // the finish instruction before the last point + id = TurnType.C; + + } else if (sign == 5) { + // the instruction before a via point + + } else if (sign == 6) { + // the instruction before entering a roundabout + id = TurnType.RNDB; + + } else if (sign == 7) { + // keep right + id = TurnType.KR; + + } else if (sign == 8) { + // a right U-turn + id = TurnType.TRU; + } + + return id != null ? TurnType.valueOf(id, leftSide) : null; + } + + @NonNull + @Override + protected String getErrorMessageKey() { + return "message"; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "paths"; + } + } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java index 119b63ee9c..b2bba21ca6 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java @@ -5,8 +5,6 @@ import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import net.osmand.GPXUtilities.WptPt; -import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.data.LatLon; import net.osmand.plus.R; @@ -14,7 +12,6 @@ import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingFactory; import net.osmand.plus.onlinerouting.VehicleType; import net.osmand.plus.onlinerouting.parser.ResponseParser; -import net.osmand.plus.routing.RouteProvider; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; @@ -109,30 +106,7 @@ public abstract class OnlineRoutingEngine implements Cloneable { } @NonNull - protected ResponseParser createParser() { - try { - return getType().getParserClass().newInstance(); - } catch (IllegalAccessException e) { - LOG.debug("Error when create parser: " + e.getMessage()); - } catch (InstantiationException e) { - LOG.debug("Error when create parser: " + e.getMessage()); - } - return ResponseParser.emptyParser(); - } - - @NonNull - protected List convertRouteToLocationsList(@NonNull List route) { - List result = new ArrayList<>(); - if (!isEmpty(route)) { - for (LatLon pt : route) { - WptPt wpt = new WptPt(); - wpt.lat = pt.getLatitude(); - wpt.lon = pt.getLongitude(); - result.add(RouteProvider.createLocation(wpt)); - } - } - return result; - } + protected abstract ResponseParser createParser(); @NonNull public Map getParams() { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java index 61f3097b04..d80d3df3c1 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java @@ -3,11 +3,20 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.Location; import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; +import net.osmand.plus.onlinerouting.parser.JSONParser; +import net.osmand.plus.onlinerouting.parser.ResponseParser; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; @@ -55,6 +64,12 @@ public class OrsEngine extends OnlineRoutingEngine { vehicles.add(new VehicleType("wheelchair", R.string.routing_engine_vehicle_type_wheelchair)); } + @NonNull + @Override + protected ResponseParser createParser() { + return new OrsParser(); + } + @Override protected void makeFullUrl(@NonNull StringBuilder sb, @NonNull List path) { @@ -77,4 +92,38 @@ public class OrsEngine extends OnlineRoutingEngine { } } + private static class OrsParser extends JSONParser { + + @Nullable + @Override + public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + JSONArray array = root.getJSONObject("geometry").getJSONArray("coordinates"); + List points = new ArrayList<>(); + for (int i = 0; i < array.length(); i++) { + JSONArray point = array.getJSONArray(i); + double lon = Double.parseDouble(point.getString(0)); + double lat = Double.parseDouble(point.getString(1)); + points.add(new LatLon(lat, lon)); + } + if (!isEmpty(points)) { + List route = convertRouteToLocationsList(points); + new OnlineRoutingResponse(route, null); + } + return null; + } + + @NonNull + @Override + protected String getErrorMessageKey() { + return "error"; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "features"; + } + } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java index 1da2ed215e..19860ee15c 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java @@ -3,16 +3,31 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.Location; import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; +import net.osmand.plus.onlinerouting.parser.JSONParser; +import net.osmand.plus.onlinerouting.parser.ResponseParser; +import net.osmand.plus.routing.RouteCalculationResult; +import net.osmand.plus.routing.RouteDirectionInfo; +import net.osmand.router.TurnType; +import net.osmand.util.GeoPolylineParserUtil; +import net.osmand.util.MapUtils; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import static net.osmand.util.Algorithms.isEmpty; +import static net.osmand.util.Algorithms.objectEquals; public class OsrmEngine extends OnlineRoutingEngine { @@ -48,6 +63,12 @@ public class OsrmEngine extends OnlineRoutingEngine { vehicles.add(new VehicleType("foot", R.string.routing_engine_vehicle_type_foot)); } + @NonNull + @Override + protected ResponseParser createParser() { + return new OsrmParser(); + } + @Override protected void makeFullUrl(@NonNull StringBuilder sb, @NonNull List path) { @@ -67,4 +88,167 @@ public class OsrmEngine extends OnlineRoutingEngine { sb.append('&').append("steps=true"); } + private static class OsrmParser extends JSONParser { + + @Nullable + @Override + protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + String encodedPoints = root.getString("geometry"); + List points = GeoPolylineParserUtil.parse(encodedPoints, GeoPolylineParserUtil.PRECISION_5); + if (isEmpty(points)) return null; + + List route = convertRouteToLocationsList(points); + List directions = new ArrayList<>(); + int startSearchingId = 0; + JSONArray legs = root.getJSONArray("legs"); + for (int i = 0; i < legs.length(); i++) { + JSONObject leg = legs.getJSONObject(i); + if (!leg.has("steps")) continue; + + JSONArray steps = leg.getJSONArray("steps"); + for (int j = 0; j < steps.length(); j++) { + JSONObject instruction = steps.getJSONObject(j); + JSONObject maneuver = instruction.getJSONObject("maneuver"); + String maneuverType = maneuver.getString("type"); + + JSONArray location = maneuver.getJSONArray("location"); + double lon = location.getDouble(0); + double lat = location.getDouble(1); + Integer routePointOffset = getLocationIndexInList(route, startSearchingId, lat, lon); + if (routePointOffset == null) continue; + startSearchingId = routePointOffset; + + // in meters + int distance = (int) Math.round(instruction.getDouble("distance")); + // in seconds + int duration = (int) Math.round(instruction.getDouble("duration")); + + float averageSpeed = (float) distance / duration; + TurnType turnType = parseTurnType(maneuver, leftSideNavigation); + RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); + direction.setDistance(distance); + + String streetName = instruction.getString("name"); + String description = ""; + if (!objectEquals(maneuverType, "arrive")) { + description = RouteCalculationResult.toString(turnType, app, false) + " " + streetName; + } + description = description.trim(); + + direction.setStreetName(streetName); + direction.setDescriptionRoute(description); + direction.routePointOffset = routePointOffset; + directions.add(direction); + } + } + + return new OnlineRoutingResponse(route, directions); + } + + @Nullable + private Integer getLocationIndexInList(@NonNull List locations, + int startIndex, double lat, double lon) { + for (int i = startIndex; i < locations.size(); i++) { + Location l = locations.get(i); + if (MapUtils.areLatLonEqual(l, lat, lon)) { + return i; + } + } + return null; + } + + @NonNull + private TurnType parseTurnType(@NonNull JSONObject maneuver, + boolean leftSide) throws JSONException { + TurnType turnType = null; + + String type = maneuver.getString("type"); + String modifier = null; + if (maneuver.has("modifier")) { + modifier = maneuver.getString("modifier"); + } + + if (objectEquals(type, "roundabout") + || objectEquals(type, "rotary") + || objectEquals(type, "roundabout turn")) { + if (maneuver.has("exit")) { + int exit = maneuver.getInt("exit"); + turnType = TurnType.getExitTurn(exit, 0.0f, leftSide); + } else if (modifier != null) { + // for simple roundabout turn without "exit" parameter + turnType = identifyTurnType(modifier, leftSide); + } + } else { + // for other maneuver types find TurnType + // like a basic turn into direction of the modifier + if (modifier != null) { + turnType = identifyTurnType(modifier, leftSide); + } + } + if (turnType == null) { + turnType = TurnType.straight(); + } + + int bearingBefore = maneuver.getInt("bearing_before"); + int bearingAfter = maneuver.getInt("bearing_after"); + float angle = (float) MapUtils.degreesDiff(bearingAfter, bearingBefore); + turnType.setTurnAngle(angle); + + return turnType; + } + + @Nullable + private TurnType identifyTurnType(@NonNull String modifier, + boolean leftSide) { + Integer id = null; + switch (modifier) { + case "uturn": + id = TurnType.TU; + break; + + case "sharp right": + id = TurnType.TSHR; + break; + + case "right": + id = TurnType.TR; + break; + + case "slight right": + id = TurnType.TSLR; + break; + + case "straight": + id = TurnType.C; + break; + + case "slight left": + id = TurnType.TSLL; + break; + + case "left": + id = TurnType.TL; + break; + + case "sharp left": + id = TurnType.TSHL; + break; + } + return id != null ? TurnType.valueOf(id, leftSide) : null; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "routes"; + } + + @NonNull + @Override + protected String getErrorMessageKey() { + return "message"; + } + } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java index 8f5db5fde7..92621b2b3f 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java @@ -25,7 +25,7 @@ public class GpxParser extends ResponseParser { @Override public boolean isResultOk(@NonNull StringBuilder errorMessage, @NonNull String content) { - return parseGpx(content) != null; // TODO may be there should be another check + return parseGpx(content) != null; } private GPXFile parseGpx(@NonNull String content) { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GraphhopperParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GraphhopperParser.java deleted file mode 100644 index 331221ad09..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GraphhopperParser.java +++ /dev/null @@ -1,165 +0,0 @@ -package net.osmand.plus.onlinerouting.parser; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import net.osmand.Location; -import net.osmand.data.LatLon; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.routing.RouteDirectionInfo; -import net.osmand.router.TurnType; -import net.osmand.util.GeoPolylineParserUtil; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.List; - -import static net.osmand.util.Algorithms.isEmpty; - -public class GraphhopperParser extends JSONParser { - - @Nullable - protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException { - String encoded = root.getString("points"); - List points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); - if (isEmpty(points)) return null; - List route = convertRouteToLocationsList(points); - - JSONArray instructions = root.getJSONArray("instructions"); - List directions = new ArrayList<>(); - for (int i = 0; i < instructions.length(); i++) { - JSONObject instruction = instructions.getJSONObject(i); - int distance = (int) Math.round(instruction.getDouble("distance")); - String description = instruction.getString("text"); - String streetName = instruction.getString("street_name"); - int timeInSeconds = Math.round(instruction.getInt("time") / 1000f); - JSONArray interval = instruction.getJSONArray("interval"); - int startPointOffset = interval.getInt(0); - int endPointOffset = interval.getInt(1); - - float averageSpeed = (float) distance / timeInSeconds; - TurnType turnType = parseTurnType(instruction, leftSideNavigation); - RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); - - direction.routePointOffset = startPointOffset; - direction.setDescriptionRoute(description); - direction.setStreetName(streetName); - direction.setDistance(distance); - directions.add(direction); - } - return new OnlineRoutingResponse(route, directions); - } - - @NonNull - private TurnType parseTurnType(@NonNull JSONObject instruction, - boolean leftSide) throws JSONException { - int sign = instruction.getInt("sign"); - TurnType turnType = identifyTurnType(sign, leftSide); - - if (turnType == null) { - turnType = TurnType.straight(); - } else if (turnType.isRoundAbout()) { - if (instruction.has("exit_number")) { - int exit = instruction.getInt("exit_number"); - turnType.setExitOut(exit); - } - if (instruction.has("turn_angle")) { - float angle = (float) instruction.getDouble("turn_angle"); - turnType.setTurnAngle(angle); - } - } else { - // TODO turnType.setTurnAngle() - } - - return turnType; - } - - @Nullable - public static TurnType identifyTurnType(int sign, boolean leftSide) { - Integer id = null; - - if (sign == -98) { - // an U-turn without the knowledge - // if it is a right or left U-turn - id = TurnType.TU; - - } else if (sign == -8) { - // a left U-turn - leftSide = false; - id = TurnType.TU; - - } else if (sign == -7) { - // keep left - id = TurnType.KL; - - } else if (sign == -6) { - // not yet used: leave roundabout - - } else if (sign == -3) { - // turn sharp left - id = TurnType.TSHL; - - } else if (sign == -2) { - // turn left - id = TurnType.TL; - - } else if (sign == -1) { - // turn slight left - id = TurnType.TSLL; - - } else if (sign == 0) { - // continue on street - id = TurnType.C; - - } else if (sign == 1) { - // turn slight right - id = TurnType.TSLR; - - } else if (sign == 2) { - // turn right - id = TurnType.TR; - - } else if (sign == 3) { - // turn sharp right - id = TurnType.TSHR; - - } else if (sign == 4) { - // the finish instruction before the last point - id = TurnType.C; - - } else if (sign == 5) { - // the instruction before a via point - - } else if (sign == 6) { - // the instruction before entering a roundabout - id = TurnType.RNDB; - - } else if (sign == 7) { - // keep right - id = TurnType.KR; - - } else if (sign == 8) { - // a right U-turn - id = TurnType.TRU; - } - - return id != null ? TurnType.valueOf(id, leftSide) : null; - } - - @NonNull - @Override - protected String getErrorMessageKey() { - return "message"; - } - - @NonNull - @Override - protected String getRootArrayKey() { - return "paths"; - } -} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java index b01af0c444..e0676f68c2 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java @@ -50,8 +50,19 @@ public abstract class JSONParser extends ResponseParser { return obj.has(getRootArrayKey()); } + @Nullable + protected abstract OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException; + @NonNull - protected List convertRouteToLocationsList(@NonNull List route) { + protected abstract String getRootArrayKey(); + + @NonNull + protected abstract String getErrorMessageKey(); + + @NonNull + protected static List convertRouteToLocationsList(@NonNull List route) { List result = new ArrayList<>(); if (!isEmpty(route)) { for (LatLon pt : route) { @@ -63,15 +74,4 @@ public abstract class JSONParser extends ResponseParser { } return result; } - - @Nullable - protected abstract OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException; - - @NonNull - protected abstract String getRootArrayKey(); - - @NonNull - protected abstract String getErrorMessageKey(); } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/OrsParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/OrsParser.java deleted file mode 100644 index f067baf61e..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/OrsParser.java +++ /dev/null @@ -1,52 +0,0 @@ -package net.osmand.plus.onlinerouting.parser; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import net.osmand.Location; -import net.osmand.data.LatLon; -import net.osmand.plus.OsmandApplication; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.List; - -import static net.osmand.util.Algorithms.isEmpty; - -public class OrsParser extends JSONParser { - - @Nullable - @Override - public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException { - JSONArray array = root.getJSONObject("geometry").getJSONArray("coordinates"); - List points = new ArrayList<>(); - for (int i = 0; i < array.length(); i++) { - JSONArray point = array.getJSONArray(i); - double lon = Double.parseDouble(point.getString(0)); - double lat = Double.parseDouble(point.getString(1)); - points.add(new LatLon(lat, lon)); - } - if (!isEmpty(points)) { - List route = convertRouteToLocationsList(points); - new OnlineRoutingResponse(route, null); - } - return null; - } - - @NonNull - @Override - protected String getErrorMessageKey() { - return "error"; - } - - @NonNull - @Override - protected String getRootArrayKey() { - return "features"; - } -} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/OsrmParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/OsrmParser.java deleted file mode 100644 index 8c93f1750e..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/OsrmParser.java +++ /dev/null @@ -1,187 +0,0 @@ -package net.osmand.plus.onlinerouting.parser; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import net.osmand.Location; -import net.osmand.data.LatLon; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.routing.RouteCalculationResult; -import net.osmand.plus.routing.RouteDirectionInfo; -import net.osmand.router.TurnType; -import net.osmand.util.GeoPolylineParserUtil; -import net.osmand.util.MapUtils; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.List; - -import static net.osmand.util.Algorithms.isEmpty; -import static net.osmand.util.Algorithms.objectEquals; - -public class OsrmParser extends JSONParser { - - @Nullable - @Override - protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException { - String encodedPoints = root.getString("geometry"); - List points = GeoPolylineParserUtil.parse(encodedPoints, GeoPolylineParserUtil.PRECISION_5); - if (isEmpty(points)) return null; - - List route = convertRouteToLocationsList(points); - List directions = new ArrayList<>(); - int startSearchingId = 0; - JSONArray legs = root.getJSONArray("legs"); - for (int i = 0; i < legs.length(); i++) { - JSONObject leg = legs.getJSONObject(i); - if (!leg.has("steps")) continue; - - JSONArray steps = leg.getJSONArray("steps"); - for (int j = 0; j < steps.length(); j++) { - JSONObject instruction = steps.getJSONObject(j); - JSONObject maneuver = instruction.getJSONObject("maneuver"); - String maneuverType = maneuver.getString("type"); - - JSONArray location = maneuver.getJSONArray("location"); - double lon = location.getDouble(0); - double lat = location.getDouble(1); - Integer routePointOffset = getLocationIndexInList(route, startSearchingId, lat, lon); - if (routePointOffset == null) continue; - startSearchingId = routePointOffset; - - // in meters - int distance = (int) Math.round(instruction.getDouble("distance")); - // in seconds - int duration = (int) Math.round(instruction.getDouble("duration")); - - float averageSpeed = (float) distance / duration; - TurnType turnType = parseTurnType(maneuver, leftSideNavigation); - RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); - direction.setDistance(distance); - - String streetName = instruction.getString("name"); - String description = ""; - if (!objectEquals(maneuverType, "arrive")) { - description = RouteCalculationResult.toString(turnType, app, false) + " " + streetName; - } - description = description.trim(); - - direction.setStreetName(streetName); - direction.setDescriptionRoute(description); - direction.routePointOffset = routePointOffset; - directions.add(direction); - } - } - - return new OnlineRoutingResponse(route, directions); - } - - @Nullable - private Integer getLocationIndexInList(@NonNull List locations, - int startIndex, double lat, double lon) { - for (int i = startIndex; i < locations.size(); i++) { - Location l = locations.get(i); - if (MapUtils.areLatLonEqual(l, lat, lon)) { - return i; - } - } - return null; - } - - @NonNull - private TurnType parseTurnType(@NonNull JSONObject maneuver, - boolean leftSide) throws JSONException { - TurnType turnType = null; - - String type = maneuver.getString("type"); - String modifier = null; - if (maneuver.has("modifier")) { - modifier = maneuver.getString("modifier"); - } - - if (objectEquals(type, "roundabout") - || objectEquals(type, "rotary") - || objectEquals(type, "roundabout turn")) { - if (maneuver.has("exit")) { - int exit = maneuver.getInt("exit"); - turnType = TurnType.getExitTurn(exit, 0.0f, leftSide); - } else if (modifier != null) { - // for simple roundabout turn without "exit" parameter - turnType = identifyTurnType(modifier, leftSide); - } - } else { - // for other maneuver types find TurnType - // like a basic turn into direction of the modifier - if (modifier != null) { - turnType = identifyTurnType(modifier, leftSide); - } - } - if (turnType == null) { - turnType = TurnType.straight(); - } - - int bearingBefore = maneuver.getInt("bearing_before"); - int bearingAfter = maneuver.getInt("bearing_after"); - float angle = (float) MapUtils.degreesDiff(bearingAfter, bearingBefore); - turnType.setTurnAngle(angle); - - return turnType; - } - - @Nullable - private TurnType identifyTurnType(@NonNull String modifier, - boolean leftSide) { - Integer id = null; - switch (modifier) { - case "uturn": - id = TurnType.TU; - break; - - case "sharp right": - id = TurnType.TSHR; - break; - - case "right": - id = TurnType.TR; - break; - - case "slight right": - id = TurnType.TSLR; - break; - - case "straight": - id = TurnType.C; - break; - - case "slight left": - id = TurnType.TSLL; - break; - - case "left": - id = TurnType.TL; - break; - - case "sharp left": - id = TurnType.TSHL; - break; - } - return id != null ? TurnType.valueOf(id, leftSide) : null; - } - - @NonNull - @Override - protected String getRootArrayKey() { - return "routes"; - } - - @NonNull - @Override - protected String getErrorMessageKey() { - return "message"; - } -} From 10bab68413e748743003c62338e2e2d3004a9db2 Mon Sep 17 00:00:00 2001 From: cepprice Date: Sun, 21 Feb 2021 15:30:39 +0500 Subject: [PATCH 04/29] Implement custom color (without color picker yet) --- .../editors/PointEditorFragmentNew.java | 2 +- .../settings/backend/ApplicationMode.java | 32 ++++++++++++ .../plus/settings/backend/OsmandSettings.java | 4 ++ .../fragments/ProfileAppearanceFragment.java | 45 +++++++++++++---- .../src/net/osmand/plus/track/ColorsCard.java | 49 ++++++++++++++----- .../plus/track/TrackAppearanceFragment.java | 4 +- 6 files changed, 112 insertions(+), 24 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java index e59ce02373..84a1d64714 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java @@ -474,7 +474,7 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment implemen if (!ColorDialogs.isPaletteColor(customColor)) { colors.add(customColor); } - colorsCard = new ColorsCard(mapActivity, selectedColor, this, colors); + colorsCard = new ColorsCard(mapActivity, selectedColor, this, colors, app.getSettings().CUSTOM_TRACK_COLORS, null); colorsCard.setListener(this); LinearLayout selectColor = view.findViewById(R.id.select_color); selectColor.addView(colorsCard.build(view.getContext())); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java index efb02fefc0..45a1e7f0b6 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java @@ -479,6 +479,22 @@ public class ApplicationMode { } } + public List getCustomIconColors() { + return app.getSettings().CUSTOM_ICON_COLORS.getStringsListForProfile(this); + } + + public void setCustomIconColors(List customColors) { + app.getSettings().CUSTOM_ICON_COLORS.setModeValues(this, customColors); + } + + public Integer getCustomIconColorIndex() { + return app.getSettings().CUSTOM_ICON_COLOR_INDEX.getModeValue(this); + } + + public void setCustomIconColorIndex(int colorIndex) { + app.getSettings().CUSTOM_ICON_COLOR_INDEX.setModeValue(this, colorIndex); + } + public int getOrder() { return app.getSettings().APP_MODE_ORDER.getModeValue(this); } @@ -576,6 +592,8 @@ public class ApplicationMode { mode.setRoutingProfile(builder.routingProfile); mode.setRouteService(builder.routeService); mode.setIconColor(builder.iconColor); + mode.setCustomIconColors(builder.customIconColors); + mode.setCustomIconColorIndex(builder.customIconColorIndex); mode.setLocationIcon(builder.locationIcon); mode.setNavigationIcon(builder.navigationIcon); mode.setOrder(builder.order); @@ -693,6 +711,8 @@ public class ApplicationMode { private String routingProfile; private String iconResName; private ProfileIconColors iconColor; + private List customIconColors; + private int customIconColorIndex; private LocationIcon locationIcon; private NavigationIcon navigationIcon; private int order = -1; @@ -716,6 +736,8 @@ public class ApplicationMode { applicationMode.setRouteService(routeService); applicationMode.setRoutingProfile(routingProfile); applicationMode.setIconResName(iconResName); + applicationMode.setCustomIconColors(customIconColors); + applicationMode.setCustomIconColorIndex(customIconColorIndex); applicationMode.setIconColor(iconColor); applicationMode.setLocationIcon(locationIcon); applicationMode.setNavigationIcon(navigationIcon); @@ -764,6 +786,16 @@ public class ApplicationMode { return this; } + public ApplicationModeBuilder setCustomIconColors(List customIconColors) { + this.customIconColors = customIconColors; + return this; + } + + public ApplicationModeBuilder setCustomIconColorIndex(int index) { + this.customIconColorIndex = index; + return this; + } + public ApplicationModeBuilder setOrder(int order) { this.order = order; return this; diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 45cefd2723..6683529fff 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -984,6 +984,10 @@ public class OsmandSettings { public final CommonPreference ICON_COLOR = new EnumStringPreference<>(this, "app_mode_icon_color", ProfileIconColors.DEFAULT, ProfileIconColors.values()).makeProfile().cache(); + public final ListStringPreference CUSTOM_ICON_COLORS = (ListStringPreference) new ListStringPreference(this, "custom_icon_colors", null, ",").makeProfile().cache(); + + public final CommonPreference CUSTOM_ICON_COLOR_INDEX = new IntPreference(this, "custom_icon_color_index", -1).makeProfile().cache(); + public final CommonPreference USER_PROFILE_NAME = new StringPreference(this, "user_profile_name", "").makeProfile().cache(); public final CommonPreference PARENT_APP_MODE = new StringPreference(this, "parent_app_mode", null).makeProfile().cache(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java index 7e1277ca18..264a3404b6 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java @@ -41,6 +41,7 @@ import net.osmand.AndroidUtils; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.R; import net.osmand.plus.settings.backend.backup.ProfileSettingsItem; @@ -55,6 +56,7 @@ import net.osmand.plus.profiles.SelectProfileBottomSheet; import net.osmand.plus.profiles.SelectProfileBottomSheet.DialogMode; import net.osmand.plus.profiles.SelectProfileBottomSheet.OnSelectProfileCallback; import net.osmand.plus.routing.RouteProvider; +import net.osmand.plus.track.ColorsCard; import net.osmand.plus.widgets.FlowLayout; import net.osmand.plus.widgets.OsmandTextFieldBoxes; import net.osmand.util.Algorithms; @@ -64,6 +66,7 @@ import org.apache.commons.logging.Log; import java.io.File; import java.util.ArrayList; import java.util.Collections; +import java.util.List; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SETTINGS_ID; import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILES_LIST_UPDATED_ARG; @@ -90,6 +93,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O private static final String PROFILE_STRINGKEY_KEY = "profile_stringkey_key"; private static final String PROFILE_ICON_RES_KEY = "profile_icon_res_key"; private static final String PROFILE_COLOR_KEY = "profile_color_key"; + private static final String PROFILE_CUSTOM_COLOR_INDEX_KEY = "profile_custom_color_index_key"; private static final String PROFILE_PARENT_KEY = "profile_parent_key"; private static final String PROFILE_LOCATION_ICON_KEY = "profile_location_icon_key"; private static final String PROFILE_NAVIGATION_ICON_KEY = "profile_navigation_icon_key"; @@ -145,6 +149,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O changedProfile.name = profile.name; } changedProfile.color = profile.color; + changedProfile.customColorIndex = profile.customColorIndex; changedProfile.iconRes = profile.iconRes; changedProfile.routingProfile = profile.routingProfile; changedProfile.routeService = profile.routeService; @@ -164,6 +169,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O profile.parent = baseModeForNewProfile.getParent(); profile.name = baseModeForNewProfile.toHumanString(); profile.color = baseModeForNewProfile.getIconColorInfo(); + profile.customColorIndex = baseModeForNewProfile.getCustomIconColorIndex(); profile.iconRes = baseModeForNewProfile.getIconRes(); profile.routingProfile = baseModeForNewProfile.getRoutingProfile(); profile.routeService = baseModeForNewProfile.getRouteService(); @@ -300,6 +306,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O outState.putString(PROFILE_STRINGKEY_KEY, changedProfile.stringKey); outState.putInt(PROFILE_ICON_RES_KEY, changedProfile.iconRes); outState.putSerializable(PROFILE_COLOR_KEY, changedProfile.color); + outState.putInt(PROFILE_CUSTOM_COLOR_INDEX_KEY, changedProfile.customColorIndex); if (changedProfile.parent != null) { outState.putString(PROFILE_PARENT_KEY, changedProfile.parent.getStringKey()); } @@ -314,6 +321,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O changedProfile.stringKey = savedInstanceState.getString(PROFILE_STRINGKEY_KEY); changedProfile.iconRes = savedInstanceState.getInt(PROFILE_ICON_RES_KEY); changedProfile.color = (ProfileIconColors) savedInstanceState.getSerializable(PROFILE_COLOR_KEY); + changedProfile.customColorIndex = savedInstanceState.getInt(PROFILE_CUSTOM_COLOR_INDEX_KEY); String parentStringKey = savedInstanceState.getString(PROFILE_PARENT_KEY); changedProfile.parent = ApplicationMode.valueOfStringKey(parentStringKey, null); isBaseProfileImported = savedInstanceState.getBoolean(IS_BASE_PROFILE_IMPORTED); @@ -330,7 +338,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O } View profileButton = view.findViewById(R.id.profile_button); if (profileButton != null) { - int iconColor = ContextCompat.getColor(app, changedProfile.color.getColor(isNightMode())); + int iconColor = changedProfile.getActualColor(); AndroidUtils.setBackground(profileButton, UiUtilities.tintDrawable(AppCompatResources.getDrawable(app, R.drawable.circle_background_light), UiUtilities.getColorWithAlpha(iconColor, 0.1f))); ImageView profileIcon = view.findViewById(R.id.profile_icon); @@ -515,7 +523,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O private void updateProfileNameAppearance() { if (profileName != null) { if (profileName.isFocusable() && profileName.isFocusableInTouchMode()) { - int selectedColor = ContextCompat.getColor(app, changedProfile.color.getColor(isNightMode())); + int selectedColor = changedProfile.getActualColor(); profileNameOtfb.setPrimaryColor(selectedColor); profileName.getBackground().mutate().setColorFilter(selectedColor, PorterDuff.Mode.SRC_ATOP); } @@ -560,8 +568,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O private View createLocationIconView(final LocationIcon locationIcon, ViewGroup rootView) { FrameLayout locationIconView = (FrameLayout) UiUtilities.getInflater(getContext(), isNightMode()) .inflate(R.layout.preference_select_icon_button, rootView, false); - int changedProfileColor = ContextCompat.getColor(app, changedProfile.color.getColor( - app.getDaynightHelper().isNightModeForMapControls())); + int changedProfileColor = changedProfile.getActualColor(); LayerDrawable locationIconDrawable = (LayerDrawable) AppCompatResources.getDrawable(app, locationIcon.getIconId()); if (locationIconDrawable != null) { DrawableCompat.setTint(DrawableCompat.wrap(locationIconDrawable.getDrawable(1)), changedProfileColor); @@ -609,7 +616,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O LayerDrawable navigationIconDrawable = (LayerDrawable) AppCompatResources.getDrawable(app, navigationIcon.getIconId()); if (navigationIconDrawable != null) { DrawableCompat.setTint(DrawableCompat.wrap(navigationIconDrawable.getDrawable(1)), - ContextCompat.getColor(app, changedProfile.color.getColor(app.getDaynightHelper().isNightModeForMapControls()))); + changedProfile.getActualColor()); } ImageView imageView = navigationIconView.findViewById(R.id.icon); imageView.setImageDrawable(navigationIconDrawable); @@ -634,8 +641,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O }); ImageView outlineRect = navigationIconView.findViewById(R.id.outlineRect); GradientDrawable rectContourDrawable = (GradientDrawable) AppCompatResources.getDrawable(app, R.drawable.bg_select_icon_button_outline); - int changedProfileColor = ContextCompat.getColor(app, changedProfile.color.getColor( - app.getDaynightHelper().isNightModeForMapControls())); + int changedProfileColor = changedProfile.getActualColor(); if (rectContourDrawable != null) { rectContourDrawable.setStroke(AndroidUtils.dpToPx(app, 2), changedProfileColor); } @@ -660,13 +666,13 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O } private void setIconColor(int iconRes) { - int changedProfileColor = ContextCompat.getColor(app, changedProfile.color.getColor( - app.getDaynightHelper().isNightModeForMapControls())); + int changedProfileColor = changedProfile.getActualColor(); View iconItem = iconItems.findViewWithTag(iconRes); if (iconItem != null) { + int newColor = changedProfile.getActualColor(); AndroidUtils.setBackground(iconItem.findViewById(R.id.background), UiUtilities.tintDrawable(AppCompatResources.getDrawable(app, R.drawable.circle_background_light), - UiUtilities.getColorWithAlpha(ContextCompat.getColor(app, changedProfile.color.getColor(isNightMode())), 0.1f))); + UiUtilities.getColorWithAlpha(newColor, 0.1f))); ImageView outlineCircle = iconItem.findViewById(R.id.outline); GradientDrawable circleContourDrawable = (GradientDrawable) AppCompatResources.getDrawable(app, R.drawable.circle_contour_bg_light); if (circleContourDrawable != null) { @@ -775,6 +781,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O mode.setRoutingProfile(changedProfile.routingProfile); mode.setRouteService(changedProfile.routeService); mode.setIconColor(changedProfile.color); + mode.setCustomIconColorIndex(changedProfile.customColorIndex); mode.setLocationIcon(changedProfile.locationIcon); mode.setNavigationIcon(changedProfile.navigationIcon); @@ -795,6 +802,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O .setRoutingProfile(changedProfile.routingProfile) .setRouteService(changedProfile.routeService) .setIconColor(changedProfile.color) + .setCustomIconColorIndex(changedProfile.customColorIndex) .setLocationIcon(changedProfile.locationIcon) .setNavigationIcon(changedProfile.navigationIcon); @@ -963,12 +971,27 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O ApplicationMode parent = null; String name; ProfileIconColors color; + int customColorIndex = -1; int iconRes; String routingProfile; RouteProvider.RouteService routeService; NavigationIcon navigationIcon; LocationIcon locationIcon; + public int getActualColor() { + return customColorIndex != -1 ? customColorIndex : ContextCompat.getColor(app, color.getColor(isNightMode())); + } + + public ProfileIconColors getProfileColorByColorValue(int colorValue) { + for (ProfileIconColors color : ProfileIconColors.values()) { + if (ContextCompat.getColor(app, color.getColor(true)) == colorValue + || ContextCompat.getColor(app, color.getColor(false)) == colorValue) { + return color; + } + } + return ProfileIconColors.DEFAULT; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -982,6 +1005,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O if (parent != null ? !parent.equals(that.parent) : that.parent != null) return false; if (name != null ? !name.equals(that.name) : that.name != null) return false; if (color != that.color) return false; + if (customColorIndex != that.customColorIndex) return false; if (routingProfile != null ? !routingProfile.equals(that.routingProfile) : that.routingProfile != null) return false; if (routeService != that.routeService) return false; @@ -995,6 +1019,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O result = 31 * result + (parent != null ? parent.hashCode() : 0); result = 31 * result + (name != null ? name.hashCode() : 0); result = 31 * result + (color != null ? color.hashCode() : 0); + result = 31 * result + customColorIndex; result = 31 * result + iconRes; result = 31 * result + (routingProfile != null ? routingProfile.hashCode() : 0); result = 31 * result + (routeService != null ? routeService.hashCode() : 0); diff --git a/OsmAnd/src/net/osmand/plus/track/ColorsCard.java b/OsmAnd/src/net/osmand/plus/track/ColorsCard.java index 9fee9408c4..5f83dfc6c8 100644 --- a/OsmAnd/src/net/osmand/plus/track/ColorsCard.java +++ b/OsmAnd/src/net/osmand/plus/track/ColorsCard.java @@ -7,12 +7,6 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; -import androidx.annotation.ColorInt; -import androidx.annotation.NonNull; -import androidx.core.content.ContextCompat; -import androidx.core.graphics.ColorUtils; -import androidx.fragment.app.Fragment; - import com.google.android.material.internal.FlowLayout; import net.osmand.AndroidUtils; @@ -22,6 +16,8 @@ import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.plus.settings.backend.ListStringPreference; import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener; import net.osmand.util.Algorithms; @@ -30,6 +26,11 @@ import org.apache.commons.logging.Log; import java.util.ArrayList; import java.util.List; +import androidx.annotation.ColorInt; +import androidx.core.content.ContextCompat; +import androidx.core.graphics.ColorUtils; +import androidx.fragment.app.Fragment; + public class ColorsCard extends BaseCard implements ColorPickerListener { public static final int MAX_CUSTOM_COLORS = 6; @@ -41,6 +42,9 @@ public class ColorsCard extends BaseCard implements ColorPickerListener { private Fragment targetFragment; + private ApplicationMode appMode; + private ListStringPreference colorsListPreference; + private List colors; private List customColors; @@ -51,12 +55,14 @@ public class ColorsCard extends BaseCard implements ColorPickerListener { return R.layout.colors_card; } - public ColorsCard(MapActivity mapActivity, int selectedColor, Fragment targetFragment, List colors) { + public ColorsCard(MapActivity mapActivity, int selectedColor, Fragment targetFragment, List colors, ListStringPreference colorsListPreference, ApplicationMode appMode) { super(mapActivity); this.targetFragment = targetFragment; this.selectedColor = selectedColor; this.colors = colors; - customColors = getCustomColors(app); + this.colorsListPreference = colorsListPreference; + this.customColors = getCustomColors(colorsListPreference, appMode); + this.appMode = appMode; } public int getSelectedColor() { @@ -215,9 +221,18 @@ public class ColorsCard extends BaseCard implements ColorPickerListener { return app.getUIUtilities().getPaintedIcon(R.drawable.ic_bg_transparency, transparencyColor); } - public static List getCustomColors(@NonNull OsmandApplication app) { + public static List getCustomColors(ListStringPreference colorsListPreference) { + return getCustomColors(colorsListPreference, null); + } + + public static List getCustomColors(ListStringPreference colorsListPreference, ApplicationMode appMode) { List colors = new ArrayList<>(); - List colorNames = app.getSettings().CUSTOM_TRACK_COLORS.getStringsList(); + List colorNames; + if (appMode == null) { + colorNames = colorsListPreference.getStringsList(); + } else { + colorNames = colorsListPreference.getStringsListForProfile(appMode); + } if (colorNames != null) { for (String colorHex : colorNames) { try { @@ -233,12 +248,24 @@ public class ColorsCard extends BaseCard implements ColorPickerListener { return colors; } + public int getIndexOfSelectedColor() { + return customColors.indexOf(selectedColor); + } + + public boolean isBaseColor(int color) { + return colors.contains(color); + } + private void saveCustomColors() { List colorNames = new ArrayList<>(); for (Integer color : customColors) { String colorHex = Algorithms.colorToString(color); colorNames.add(colorHex); } - app.getSettings().CUSTOM_TRACK_COLORS.setStringsList(colorNames); + if (appMode == null) { + colorsListPreference.setStringsList(colorNames); + } else { + colorsListPreference.setStringsListForProfile(appMode, colorNames); + } } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java index 522103ac02..c081c67897 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java @@ -358,7 +358,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement @Override public void onColorSelected(Integer prevColor, int newColor) { if (prevColor != null) { - List customColors = ColorsCard.getCustomColors(app); + List customColors = ColorsCard.getCustomColors(app.getSettings().CUSTOM_TRACK_COLORS); int index = customColors.indexOf(prevColor); if (index != ColorsCard.INVALID_VALUE) { saveCustomColorsToTracks(prevColor, newColor); @@ -666,7 +666,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { List colors = getTrackColors(); - colorsCard = new ColorsCard(mapActivity, trackDrawInfo.getColor(), this, colors); + colorsCard = new ColorsCard(mapActivity, trackDrawInfo.getColor(), this, colors, app.getSettings().CUSTOM_TRACK_COLORS, null); colorsCard.setListener(this); cardsContainer.addView(colorsCard.build(mapActivity)); } From 7c22585d437135648507679ce987e7100a79f59a Mon Sep 17 00:00:00 2001 From: cepprice Date: Mon, 22 Feb 2021 20:01:25 +0500 Subject: [PATCH 05/29] Add color picker and color selection --- OsmAnd/res/xml/profile_appearance.xml | 2 +- .../fragments/ProfileAppearanceFragment.java | 137 +++++++++++------- 2 files changed, 83 insertions(+), 56 deletions(-) diff --git a/OsmAnd/res/xml/profile_appearance.xml b/OsmAnd/res/xml/profile_appearance.xml index 9c042ddeaa..53a1fa2a1c 100644 --- a/OsmAnd/res/xml/profile_appearance.xml +++ b/OsmAnd/res/xml/profile_appearance.xml @@ -21,7 +21,7 @@ colors = new ArrayList<>(); + for (ProfileIconColors color : ProfileIconColors.values()) { + colors.add(ContextCompat.getColor(app, color.getColor(isNightMode()))); } - updateProfileNameAppearance(); - updateProfileButton(); + colorsCard = new ColorsCard(mapActivity, selectedColor, this, colors, app.getSettings().CUSTOM_ICON_COLORS, getSelectedAppMode()); + colorsCard.setListener(this); + parentView.removeAllViews(); + parentView.addView(colorsCard.build(app)); + updateColorName(); } private void updateProfileNameAppearance() { @@ -939,6 +906,18 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O } } + private void updateColorName() { + if (colorsCard == null || colorName == null) { + return; + } + int selectedColor = colorsCard.getSelectedColor(); + if (colorsCard.isBaseColor(selectedColor)) { + colorName.setText(changedProfile.getProfileColorByColorValue(selectedColor).getName()); + } else { + colorName.setText(R.string.custom_color); + } + } + @Override public void onProfileSelected(Bundle args) { String profileKey = args.getString(PROFILE_KEY_ARG); @@ -946,6 +925,54 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O updateParentProfile(profileKey, imported); } + @Override + public void onCardLayoutNeeded(@NonNull BaseCard card) { + } + + @Override + public void onCardPressed(@NonNull BaseCard card) { + if (card instanceof ColorsCard) { + ColorsCard cardOfColors = (ColorsCard) card; + int color = cardOfColors.getSelectedColor(); + + if (color == changedProfile.getActualColor()) { + return; + } + + + if (cardOfColors.isBaseColor(color)) { + changedProfile.customColorIndex = -1; + changedProfile.color = changedProfile.getProfileColorByColorValue(color); + } else { + changedProfile.customColorIndex = color; + changedProfile.color = null; + } + + if (iconItems != null) { + updateIconColor(changedProfile.iconRes); + } + + updateColorName(); + updateProfileNameAppearance(); + updateProfileButton(); + setVerticalScrollBarEnabled(false); + updatePreference(findPreference(MASTER_PROFILE)); + updatePreference(findPreference(LOCATION_ICON_ITEMS)); + updatePreference(findPreference(NAV_ICON_ITEMS)); + setVerticalScrollBarEnabled(true); + } + } + + @Override + public void onCardButtonPressed(@NonNull BaseCard card, int buttonIndex) { + } + + @Override + public void onColorSelected(Integer prevColor, int newColor) { + colorsCard.onColorSelected(prevColor, newColor); + this.onCardPressed(colorsCard); + } + public static boolean showInstance(FragmentActivity activity, SettingsScreenType screenType, @Nullable String appMode, boolean imported) { try { Fragment fragment = Fragment.instantiate(activity, screenType.fragmentName); From 1be6bc7eea2ebb7e86996fbaac9b4674061e0d58 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 22 Feb 2021 17:04:38 +0200 Subject: [PATCH 06/29] Refactoring: inheritance instead of composition --- .../onlinerouting/OnlineRoutingHelper.java | 6 +- .../plus/onlinerouting/engine/GpxEngine.java | 34 +- .../engine/GraphhopperEngine.java | 286 ++++++++-------- .../JsonOnlineRoutingEngine.java} | 9 +- .../engine/OnlineRoutingEngine.java | 52 ++- .../plus/onlinerouting/engine/OrsEngine.java | 70 ++-- .../plus/onlinerouting/engine/OsrmEngine.java | 312 +++++++++--------- .../plus/onlinerouting/parser/GpxParser.java | 42 --- .../onlinerouting/parser/ResponseParser.java | 77 ----- .../ui/OnlineRoutingEngineFragment.java | 2 +- .../osmand/plus/routing/RouteProvider.java | 2 +- 11 files changed, 400 insertions(+), 492 deletions(-) rename OsmAnd/src/net/osmand/plus/onlinerouting/{parser/JSONParser.java => engine/JsonOnlineRoutingEngine.java} (90%) delete mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java delete mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/parser/ResponseParser.java diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index 503977c7b7..9ae8f5cb02 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -9,8 +9,7 @@ import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.Version; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; -import net.osmand.plus.onlinerouting.parser.ResponseParser; -import net.osmand.plus.onlinerouting.parser.ResponseParser.OnlineRoutingResponse; +import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; @@ -95,8 +94,7 @@ public class OnlineRoutingHelper { boolean leftSideNavigation) throws IOException, JSONException { String url = engine.getFullUrl(path); String content = makeRequest(url); - ResponseParser parser = engine.getResponseParser(); - return parser.parseResponse(content, app, leftSideNavigation); + return engine.parseResponse(content, app, leftSideNavigation); } @NonNull diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java index 1f6146273d..676ea6ba48 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java @@ -3,12 +3,16 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.onlinerouting.parser.GpxParser; -import net.osmand.plus.onlinerouting.parser.ResponseParser; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.util.List; import java.util.Map; import java.util.Set; @@ -56,9 +60,29 @@ public class GpxEngine extends OnlineRoutingEngine { params.add(EngineParameter.CUSTOM_URL); } - @NonNull @Override - protected ResponseParser createParser() { - return new GpxParser(); + @Nullable + public OnlineRoutingResponse parseResponse(@NonNull String content, + @NonNull OsmandApplication app, + boolean leftSideNavigation) { + GPXFile gpxFile = parseGpx(content); + return gpxFile != null ? new OnlineRoutingResponse(parseGpx(content)) : null; + } + + @Override + public boolean isResultOk(@NonNull StringBuilder errorMessage, + @NonNull String content) { + return parseGpx(content) != null; + } + + private GPXFile parseGpx(@NonNull String content) { + InputStream gpxStream = null; + try { + gpxStream = new ByteArrayInputStream(content.getBytes("UTF-8")); + return GPXUtilities.loadGPXFile(gpxStream); + } catch (UnsupportedEncodingException e) { + LOG.debug("Error when parsing GPX from server response: " + e.getMessage()); + } + return null; } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java index 14852e2633..68122b3bdd 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java @@ -9,8 +9,6 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.onlinerouting.parser.JSONParser; -import net.osmand.plus.onlinerouting.parser.ResponseParser; import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.router.TurnType; import net.osmand.util.GeoPolylineParserUtil; @@ -26,7 +24,7 @@ import java.util.Set; import static net.osmand.util.Algorithms.isEmpty; -public class GraphhopperEngine extends OnlineRoutingEngine { +public class GraphhopperEngine extends JsonOnlineRoutingEngine { public GraphhopperEngine(@Nullable Map params) { super(params); @@ -67,12 +65,6 @@ public class GraphhopperEngine extends OnlineRoutingEngine { vehicles.add(new VehicleType("small_truck", R.string.routing_engine_vehicle_type_small_truck)); } - @NonNull - @Override - protected ResponseParser createParser() { - return new GraphhopperParser(); - } - @Override protected void makeFullUrl(@NonNull StringBuilder sb, @NonNull List path) { @@ -95,148 +87,146 @@ public class GraphhopperEngine extends OnlineRoutingEngine { sb.append('&').append("details=").append("lanes"); } - private static class GraphhopperParser extends JSONParser { + @Nullable + protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + String encoded = root.getString("points"); + List points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); + if (isEmpty(points)) return null; + List route = convertRouteToLocationsList(points); - @Nullable - protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException { - String encoded = root.getString("points"); - List points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); - if (isEmpty(points)) return null; - List route = convertRouteToLocationsList(points); + JSONArray instructions = root.getJSONArray("instructions"); + List directions = new ArrayList<>(); + for (int i = 0; i < instructions.length(); i++) { + JSONObject instruction = instructions.getJSONObject(i); + int distance = (int) Math.round(instruction.getDouble("distance")); + String description = instruction.getString("text"); + String streetName = instruction.getString("street_name"); + int timeInSeconds = Math.round(instruction.getInt("time") / 1000f); + JSONArray interval = instruction.getJSONArray("interval"); + int startPointOffset = interval.getInt(0); + int endPointOffset = interval.getInt(1); - JSONArray instructions = root.getJSONArray("instructions"); - List directions = new ArrayList<>(); - for (int i = 0; i < instructions.length(); i++) { - JSONObject instruction = instructions.getJSONObject(i); - int distance = (int) Math.round(instruction.getDouble("distance")); - String description = instruction.getString("text"); - String streetName = instruction.getString("street_name"); - int timeInSeconds = Math.round(instruction.getInt("time") / 1000f); - JSONArray interval = instruction.getJSONArray("interval"); - int startPointOffset = interval.getInt(0); - int endPointOffset = interval.getInt(1); + float averageSpeed = (float) distance / timeInSeconds; + TurnType turnType = parseTurnType(instruction, leftSideNavigation); + RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); - float averageSpeed = (float) distance / timeInSeconds; - TurnType turnType = parseTurnType(instruction, leftSideNavigation); - RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); - - direction.routePointOffset = startPointOffset; - direction.setDescriptionRoute(description); - direction.setStreetName(streetName); - direction.setDistance(distance); - directions.add(direction); - } - return new OnlineRoutingResponse(route, directions); - } - - @NonNull - private TurnType parseTurnType(@NonNull JSONObject instruction, - boolean leftSide) throws JSONException { - int sign = instruction.getInt("sign"); - TurnType turnType = identifyTurnType(sign, leftSide); - - if (turnType == null) { - turnType = TurnType.straight(); - } else if (turnType.isRoundAbout()) { - if (instruction.has("exit_number")) { - int exit = instruction.getInt("exit_number"); - turnType.setExitOut(exit); - } - if (instruction.has("turn_angle")) { - float angle = (float) instruction.getDouble("turn_angle"); - turnType.setTurnAngle(angle); - } - } else { - // TODO turnType.setTurnAngle() - } - - return turnType; - } - - @Nullable - public static TurnType identifyTurnType(int sign, boolean leftSide) { - Integer id = null; - - if (sign == -98) { - // an U-turn without the knowledge - // if it is a right or left U-turn - id = TurnType.TU; - - } else if (sign == -8) { - // a left U-turn - leftSide = false; - id = TurnType.TU; - - } else if (sign == -7) { - // keep left - id = TurnType.KL; - - } else if (sign == -6) { - // not yet used: leave roundabout - - } else if (sign == -3) { - // turn sharp left - id = TurnType.TSHL; - - } else if (sign == -2) { - // turn left - id = TurnType.TL; - - } else if (sign == -1) { - // turn slight left - id = TurnType.TSLL; - - } else if (sign == 0) { - // continue on street - id = TurnType.C; - - } else if (sign == 1) { - // turn slight right - id = TurnType.TSLR; - - } else if (sign == 2) { - // turn right - id = TurnType.TR; - - } else if (sign == 3) { - // turn sharp right - id = TurnType.TSHR; - - } else if (sign == 4) { - // the finish instruction before the last point - id = TurnType.C; - - } else if (sign == 5) { - // the instruction before a via point - - } else if (sign == 6) { - // the instruction before entering a roundabout - id = TurnType.RNDB; - - } else if (sign == 7) { - // keep right - id = TurnType.KR; - - } else if (sign == 8) { - // a right U-turn - id = TurnType.TRU; - } - - return id != null ? TurnType.valueOf(id, leftSide) : null; - } - - @NonNull - @Override - protected String getErrorMessageKey() { - return "message"; - } - - @NonNull - @Override - protected String getRootArrayKey() { - return "paths"; + direction.routePointOffset = startPointOffset; + direction.setDescriptionRoute(description); + direction.setStreetName(streetName); + direction.setDistance(distance); + directions.add(direction); } + return new OnlineRoutingResponse(route, directions); } + + @NonNull + private TurnType parseTurnType(@NonNull JSONObject instruction, + boolean leftSide) throws JSONException { + int sign = instruction.getInt("sign"); + TurnType turnType = identifyTurnType(sign, leftSide); + + if (turnType == null) { + turnType = TurnType.straight(); + } else if (turnType.isRoundAbout()) { + if (instruction.has("exit_number")) { + int exit = instruction.getInt("exit_number"); + turnType.setExitOut(exit); + } + if (instruction.has("turn_angle")) { + float angle = (float) instruction.getDouble("turn_angle"); + turnType.setTurnAngle(angle); + } + } else { + // TODO turnType.setTurnAngle() + } + + return turnType; + } + + @Nullable + public static TurnType identifyTurnType(int sign, boolean leftSide) { + Integer id = null; + + if (sign == -98) { + // an U-turn without the knowledge + // if it is a right or left U-turn + id = TurnType.TU; + + } else if (sign == -8) { + // a left U-turn + leftSide = false; + id = TurnType.TU; + + } else if (sign == -7) { + // keep left + id = TurnType.KL; + + } else if (sign == -6) { + // not yet used: leave roundabout + + } else if (sign == -3) { + // turn sharp left + id = TurnType.TSHL; + + } else if (sign == -2) { + // turn left + id = TurnType.TL; + + } else if (sign == -1) { + // turn slight left + id = TurnType.TSLL; + + } else if (sign == 0) { + // continue on street + id = TurnType.C; + + } else if (sign == 1) { + // turn slight right + id = TurnType.TSLR; + + } else if (sign == 2) { + // turn right + id = TurnType.TR; + + } else if (sign == 3) { + // turn sharp right + id = TurnType.TSHR; + + } else if (sign == 4) { + // the finish instruction before the last point + id = TurnType.C; + + } else if (sign == 5) { + // the instruction before a via point + + } else if (sign == 6) { + // the instruction before entering a roundabout + id = TurnType.RNDB; + + } else if (sign == 7) { + // keep right + id = TurnType.KR; + + } else if (sign == 8) { + // a right U-turn + id = TurnType.TRU; + } + + return id != null ? TurnType.valueOf(id, leftSide) : null; + } + + @NonNull + @Override + protected String getErrorMessageKey() { + return "message"; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "paths"; + } + } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/JsonOnlineRoutingEngine.java similarity index 90% rename from OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java rename to OsmAnd/src/net/osmand/plus/onlinerouting/engine/JsonOnlineRoutingEngine.java index e0676f68c2..dcd191da19 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/JsonOnlineRoutingEngine.java @@ -1,4 +1,4 @@ -package net.osmand.plus.onlinerouting.parser; +package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -15,10 +15,15 @@ import org.json.JSONObject; import java.util.ArrayList; import java.util.List; +import java.util.Map; import static net.osmand.util.Algorithms.isEmpty; -public abstract class JSONParser extends ResponseParser { +public abstract class JsonOnlineRoutingEngine extends OnlineRoutingEngine { + + public JsonOnlineRoutingEngine(@Nullable Map params) { + super(params); + } @Nullable public OnlineRoutingResponse parseResponse(@NonNull String content, diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java index b2bba21ca6..85514dec85 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java @@ -5,16 +5,20 @@ import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingFactory; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.onlinerouting.parser.ResponseParser; +import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; +import org.json.JSONException; import java.util.ArrayList; import java.util.Collections; @@ -36,7 +40,6 @@ public abstract class OnlineRoutingEngine implements Cloneable { private final Map params = new HashMap<>(); private final List allowedVehicles = new ArrayList<>(); private final Set allowedParameters = new HashSet<>(); - private ResponseParser responseParser; public OnlineRoutingEngine(@Nullable Map params) { if (!isEmpty(params)) { @@ -97,16 +100,13 @@ public abstract class OnlineRoutingEngine implements Cloneable { @NonNull public abstract String getStandardUrl(); - @NonNull - public ResponseParser getResponseParser() { - if (responseParser == null) { - responseParser = createParser(); - } - return responseParser; - } + @Nullable + public abstract OnlineRoutingResponse parseResponse(@NonNull String content, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException; - @NonNull - protected abstract ResponseParser createParser(); + public abstract boolean isResultOk(@NonNull StringBuilder errorMessage, + @NonNull String content) throws JSONException; @NonNull public Map getParams() { @@ -194,4 +194,34 @@ public abstract class OnlineRoutingEngine implements Cloneable { return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis(); } + public static class OnlineRoutingResponse { + + private List route; + private List directions; + private GPXFile gpxFile; + + // constructor for JSON responses + public OnlineRoutingResponse(List route, List directions) { + this.route = route; + this.directions = directions; + } + + // constructor for GPX responses + public OnlineRoutingResponse(GPXFile gpxFile) { + this.gpxFile = gpxFile; + } + + public List getRoute() { + return route; + } + + public List getDirections() { + return directions; + } + + public GPXFile getGpxFile() { + return gpxFile; + } + } + } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java index d80d3df3c1..9a16be62ee 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java @@ -9,8 +9,6 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.onlinerouting.parser.JSONParser; -import net.osmand.plus.onlinerouting.parser.ResponseParser; import org.json.JSONArray; import org.json.JSONException; @@ -23,7 +21,7 @@ import java.util.Set; import static net.osmand.util.Algorithms.isEmpty; -public class OrsEngine extends OnlineRoutingEngine { +public class OrsEngine extends JsonOnlineRoutingEngine { public OrsEngine(@Nullable Map params) { super(params); @@ -64,12 +62,6 @@ public class OrsEngine extends OnlineRoutingEngine { vehicles.add(new VehicleType("wheelchair", R.string.routing_engine_vehicle_type_wheelchair)); } - @NonNull - @Override - protected ResponseParser createParser() { - return new OrsParser(); - } - @Override protected void makeFullUrl(@NonNull StringBuilder sb, @NonNull List path) { @@ -92,38 +84,36 @@ public class OrsEngine extends OnlineRoutingEngine { } } - private static class OrsParser extends JSONParser { - - @Nullable - @Override - public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException { - JSONArray array = root.getJSONObject("geometry").getJSONArray("coordinates"); - List points = new ArrayList<>(); - for (int i = 0; i < array.length(); i++) { - JSONArray point = array.getJSONArray(i); - double lon = Double.parseDouble(point.getString(0)); - double lat = Double.parseDouble(point.getString(1)); - points.add(new LatLon(lat, lon)); - } - if (!isEmpty(points)) { - List route = convertRouteToLocationsList(points); - new OnlineRoutingResponse(route, null); - } - return null; + @Nullable + @Override + public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + JSONArray array = root.getJSONObject("geometry").getJSONArray("coordinates"); + List points = new ArrayList<>(); + for (int i = 0; i < array.length(); i++) { + JSONArray point = array.getJSONArray(i); + double lon = Double.parseDouble(point.getString(0)); + double lat = Double.parseDouble(point.getString(1)); + points.add(new LatLon(lat, lon)); } - - @NonNull - @Override - protected String getErrorMessageKey() { - return "error"; - } - - @NonNull - @Override - protected String getRootArrayKey() { - return "features"; + if (!isEmpty(points)) { + List route = convertRouteToLocationsList(points); + new OnlineRoutingResponse(route, null); } + return null; } + + @NonNull + @Override + protected String getErrorMessageKey() { + return "error"; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "features"; + } + } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java index 19860ee15c..4219204cca 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java @@ -9,8 +9,6 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.onlinerouting.parser.JSONParser; -import net.osmand.plus.onlinerouting.parser.ResponseParser; import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.router.TurnType; @@ -29,7 +27,7 @@ import java.util.Set; import static net.osmand.util.Algorithms.isEmpty; import static net.osmand.util.Algorithms.objectEquals; -public class OsrmEngine extends OnlineRoutingEngine { +public class OsrmEngine extends JsonOnlineRoutingEngine { public OsrmEngine(@Nullable Map params) { super(params); @@ -63,12 +61,6 @@ public class OsrmEngine extends OnlineRoutingEngine { vehicles.add(new VehicleType("foot", R.string.routing_engine_vehicle_type_foot)); } - @NonNull - @Override - protected ResponseParser createParser() { - return new OsrmParser(); - } - @Override protected void makeFullUrl(@NonNull StringBuilder sb, @NonNull List path) { @@ -88,167 +80,165 @@ public class OsrmEngine extends OnlineRoutingEngine { sb.append('&').append("steps=true"); } - private static class OsrmParser extends JSONParser { + @Nullable + @Override + protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + String encodedPoints = root.getString("geometry"); + List points = GeoPolylineParserUtil.parse(encodedPoints, GeoPolylineParserUtil.PRECISION_5); + if (isEmpty(points)) return null; - @Nullable - @Override - protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException { - String encodedPoints = root.getString("geometry"); - List points = GeoPolylineParserUtil.parse(encodedPoints, GeoPolylineParserUtil.PRECISION_5); - if (isEmpty(points)) return null; + List route = convertRouteToLocationsList(points); + List directions = new ArrayList<>(); + int startSearchingId = 0; + JSONArray legs = root.getJSONArray("legs"); + for (int i = 0; i < legs.length(); i++) { + JSONObject leg = legs.getJSONObject(i); + if (!leg.has("steps")) continue; - List route = convertRouteToLocationsList(points); - List directions = new ArrayList<>(); - int startSearchingId = 0; - JSONArray legs = root.getJSONArray("legs"); - for (int i = 0; i < legs.length(); i++) { - JSONObject leg = legs.getJSONObject(i); - if (!leg.has("steps")) continue; + JSONArray steps = leg.getJSONArray("steps"); + for (int j = 0; j < steps.length(); j++) { + JSONObject instruction = steps.getJSONObject(j); + JSONObject maneuver = instruction.getJSONObject("maneuver"); + String maneuverType = maneuver.getString("type"); - JSONArray steps = leg.getJSONArray("steps"); - for (int j = 0; j < steps.length(); j++) { - JSONObject instruction = steps.getJSONObject(j); - JSONObject maneuver = instruction.getJSONObject("maneuver"); - String maneuverType = maneuver.getString("type"); + JSONArray location = maneuver.getJSONArray("location"); + double lon = location.getDouble(0); + double lat = location.getDouble(1); + Integer routePointOffset = getLocationIndexInList(route, startSearchingId, lat, lon); + if (routePointOffset == null) continue; + startSearchingId = routePointOffset; - JSONArray location = maneuver.getJSONArray("location"); - double lon = location.getDouble(0); - double lat = location.getDouble(1); - Integer routePointOffset = getLocationIndexInList(route, startSearchingId, lat, lon); - if (routePointOffset == null) continue; - startSearchingId = routePointOffset; + // in meters + int distance = (int) Math.round(instruction.getDouble("distance")); + // in seconds + int duration = (int) Math.round(instruction.getDouble("duration")); - // in meters - int distance = (int) Math.round(instruction.getDouble("distance")); - // in seconds - int duration = (int) Math.round(instruction.getDouble("duration")); + float averageSpeed = (float) distance / duration; + TurnType turnType = parseTurnType(maneuver, leftSideNavigation); + RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); + direction.setDistance(distance); - float averageSpeed = (float) distance / duration; - TurnType turnType = parseTurnType(maneuver, leftSideNavigation); - RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); - direction.setDistance(distance); - - String streetName = instruction.getString("name"); - String description = ""; - if (!objectEquals(maneuverType, "arrive")) { - description = RouteCalculationResult.toString(turnType, app, false) + " " + streetName; - } - description = description.trim(); - - direction.setStreetName(streetName); - direction.setDescriptionRoute(description); - direction.routePointOffset = routePointOffset; - directions.add(direction); + String streetName = instruction.getString("name"); + String description = ""; + if (!objectEquals(maneuverType, "arrive")) { + description = RouteCalculationResult.toString(turnType, app, false) + " " + streetName; } - } + description = description.trim(); - return new OnlineRoutingResponse(route, directions); + direction.setStreetName(streetName); + direction.setDescriptionRoute(description); + direction.routePointOffset = routePointOffset; + directions.add(direction); + } } - @Nullable - private Integer getLocationIndexInList(@NonNull List locations, - int startIndex, double lat, double lon) { - for (int i = startIndex; i < locations.size(); i++) { - Location l = locations.get(i); - if (MapUtils.areLatLonEqual(l, lat, lon)) { - return i; - } - } - return null; - } - - @NonNull - private TurnType parseTurnType(@NonNull JSONObject maneuver, - boolean leftSide) throws JSONException { - TurnType turnType = null; - - String type = maneuver.getString("type"); - String modifier = null; - if (maneuver.has("modifier")) { - modifier = maneuver.getString("modifier"); - } - - if (objectEquals(type, "roundabout") - || objectEquals(type, "rotary") - || objectEquals(type, "roundabout turn")) { - if (maneuver.has("exit")) { - int exit = maneuver.getInt("exit"); - turnType = TurnType.getExitTurn(exit, 0.0f, leftSide); - } else if (modifier != null) { - // for simple roundabout turn without "exit" parameter - turnType = identifyTurnType(modifier, leftSide); - } - } else { - // for other maneuver types find TurnType - // like a basic turn into direction of the modifier - if (modifier != null) { - turnType = identifyTurnType(modifier, leftSide); - } - } - if (turnType == null) { - turnType = TurnType.straight(); - } - - int bearingBefore = maneuver.getInt("bearing_before"); - int bearingAfter = maneuver.getInt("bearing_after"); - float angle = (float) MapUtils.degreesDiff(bearingAfter, bearingBefore); - turnType.setTurnAngle(angle); - - return turnType; - } - - @Nullable - private TurnType identifyTurnType(@NonNull String modifier, - boolean leftSide) { - Integer id = null; - switch (modifier) { - case "uturn": - id = TurnType.TU; - break; - - case "sharp right": - id = TurnType.TSHR; - break; - - case "right": - id = TurnType.TR; - break; - - case "slight right": - id = TurnType.TSLR; - break; - - case "straight": - id = TurnType.C; - break; - - case "slight left": - id = TurnType.TSLL; - break; - - case "left": - id = TurnType.TL; - break; - - case "sharp left": - id = TurnType.TSHL; - break; - } - return id != null ? TurnType.valueOf(id, leftSide) : null; - } - - @NonNull - @Override - protected String getRootArrayKey() { - return "routes"; - } - - @NonNull - @Override - protected String getErrorMessageKey() { - return "message"; - } + return new OnlineRoutingResponse(route, directions); } + + @Nullable + private Integer getLocationIndexInList(@NonNull List locations, + int startIndex, double lat, double lon) { + for (int i = startIndex; i < locations.size(); i++) { + Location l = locations.get(i); + if (MapUtils.areLatLonEqual(l, lat, lon)) { + return i; + } + } + return null; + } + + @NonNull + private TurnType parseTurnType(@NonNull JSONObject maneuver, + boolean leftSide) throws JSONException { + TurnType turnType = null; + + String type = maneuver.getString("type"); + String modifier = null; + if (maneuver.has("modifier")) { + modifier = maneuver.getString("modifier"); + } + + if (objectEquals(type, "roundabout") + || objectEquals(type, "rotary") + || objectEquals(type, "roundabout turn")) { + if (maneuver.has("exit")) { + int exit = maneuver.getInt("exit"); + turnType = TurnType.getExitTurn(exit, 0.0f, leftSide); + } else if (modifier != null) { + // for simple roundabout turn without "exit" parameter + turnType = identifyTurnType(modifier, leftSide); + } + } else { + // for other maneuver types find TurnType + // like a basic turn into direction of the modifier + if (modifier != null) { + turnType = identifyTurnType(modifier, leftSide); + } + } + if (turnType == null) { + turnType = TurnType.straight(); + } + + int bearingBefore = maneuver.getInt("bearing_before"); + int bearingAfter = maneuver.getInt("bearing_after"); + float angle = (float) MapUtils.degreesDiff(bearingAfter, bearingBefore); + turnType.setTurnAngle(angle); + + return turnType; + } + + @Nullable + private TurnType identifyTurnType(@NonNull String modifier, + boolean leftSide) { + Integer id = null; + switch (modifier) { + case "uturn": + id = TurnType.TU; + break; + + case "sharp right": + id = TurnType.TSHR; + break; + + case "right": + id = TurnType.TR; + break; + + case "slight right": + id = TurnType.TSLR; + break; + + case "straight": + id = TurnType.C; + break; + + case "slight left": + id = TurnType.TSLL; + break; + + case "left": + id = TurnType.TL; + break; + + case "sharp left": + id = TurnType.TSHL; + break; + } + return id != null ? TurnType.valueOf(id, leftSide) : null; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "routes"; + } + + @NonNull + @Override + protected String getErrorMessageKey() { + return "message"; + } + } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java deleted file mode 100644 index 92621b2b3f..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.osmand.plus.onlinerouting.parser; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import net.osmand.GPXUtilities; -import net.osmand.GPXUtilities.GPXFile; -import net.osmand.plus.OsmandApplication; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; - -public class GpxParser extends ResponseParser { - - @Override - @Nullable - public OnlineRoutingResponse parseResponse(@NonNull String content, - @NonNull OsmandApplication app, - boolean leftSideNavigation) { - GPXFile gpxFile = parseGpx(content); - return gpxFile != null ? new OnlineRoutingResponse(parseGpx(content)) : null; - } - - @Override - public boolean isResultOk(@NonNull StringBuilder errorMessage, - @NonNull String content) { - return parseGpx(content) != null; - } - - private GPXFile parseGpx(@NonNull String content) { - InputStream gpxStream = null; - try { - gpxStream = new ByteArrayInputStream(content.getBytes("UTF-8")); - return GPXUtilities.loadGPXFile(gpxStream); - } catch (UnsupportedEncodingException e) { - LOG.debug("Error when parsing GPX from server response: " + e.getMessage()); - } - return null; - } - -} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/ResponseParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/ResponseParser.java deleted file mode 100644 index 62cf7e0f44..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/ResponseParser.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.osmand.plus.onlinerouting.parser; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import net.osmand.GPXUtilities.GPXFile; -import net.osmand.Location; -import net.osmand.PlatformUtil; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.routing.RouteDirectionInfo; - -import org.apache.commons.logging.Log; -import org.json.JSONException; - -import java.util.List; - -public abstract class ResponseParser { - - protected static final Log LOG = PlatformUtil.getLog(ResponseParser.class); - - @Nullable - public abstract OnlineRoutingResponse parseResponse(@NonNull String content, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException; - - public abstract boolean isResultOk(@NonNull StringBuilder errorMessage, - @NonNull String content) throws JSONException; - - public static ResponseParser emptyParser() { - return new ResponseParser() { - @Nullable - @Override - public OnlineRoutingResponse parseResponse(@NonNull String content, - @NonNull OsmandApplication app, - boolean leftSideNavigation) { - return null; - } - - @Override - public boolean isResultOk(@NonNull StringBuilder errorMessage, - @NonNull String content) { - return false; - } - }; - } - - public static class OnlineRoutingResponse { - - private List route; - private List directions; - private GPXFile gpxFile; - - // constructor for JSON responses - public OnlineRoutingResponse(List route, List directions) { - this.route = route; - this.directions = directions; - } - - // constructor for GPX responses - public OnlineRoutingResponse(GPXFile gpxFile) { - this.gpxFile = gpxFile; - } - - public List getRoute() { - return route; - } - - public List getDirections() { - return directions; - } - - public GPXFile getGpxFile() { - return gpxFile; - } - } - -} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java index 4f626569d7..fee3d02524 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java @@ -462,7 +462,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { boolean resultOk = false; try { String response = helper.makeRequest(exampleCard.getEditedText()); - resultOk = requestedEngine.getResponseParser().isResultOk(errorMessage, response); + resultOk = requestedEngine.isResultOk(errorMessage, response); } catch (IOException | JSONException e) { errorMessage.append(e.toString()); } diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 0eb5a74e52..19d0fcd3f7 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -23,7 +23,7 @@ import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.onlinerouting.OnlineRoutingHelper; -import net.osmand.plus.onlinerouting.parser.ResponseParser.OnlineRoutingResponse; +import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse; import net.osmand.plus.render.NativeOsmandLibrary; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.CommonPreference; From cea1fa60e798f04971afad6ac89eb85014898cf9 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 22 Feb 2021 19:09:30 +0200 Subject: [PATCH 07/29] Refactoring: remove enum EngineType, use OnlineRoutingEngine constants instead --- .../onlinerouting/OnlineRoutingFactory.java | 39 ------------------- .../onlinerouting/OnlineRoutingUtils.java | 8 ++-- .../plus/onlinerouting/engine/EngineType.java | 39 ++++++++++--------- .../plus/onlinerouting/engine/GpxEngine.java | 23 ++++++++++- .../engine/GraphhopperEngine.java | 22 ++++++++++- .../engine/OnlineRoutingEngine.java | 13 +++++-- .../plus/onlinerouting/engine/OrsEngine.java | 22 ++++++++++- .../plus/onlinerouting/engine/OsrmEngine.java | 24 ++++++++++-- .../ui/OnlineRoutingEngineFragment.java | 30 +++++++------- 9 files changed, 133 insertions(+), 87 deletions(-) delete mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingFactory.java diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingFactory.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingFactory.java deleted file mode 100644 index 71ea72f5e4..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingFactory.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.osmand.plus.onlinerouting; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import net.osmand.plus.onlinerouting.engine.EngineType; -import net.osmand.plus.onlinerouting.engine.GpxEngine; -import net.osmand.plus.onlinerouting.engine.GraphhopperEngine; -import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; -import net.osmand.plus.onlinerouting.engine.OrsEngine; -import net.osmand.plus.onlinerouting.engine.OsrmEngine; - -import java.util.Map; - -public class OnlineRoutingFactory { - - public static OnlineRoutingEngine createEngine(@NonNull EngineType type) { - return createEngine(type, null); - } - - @NonNull - public static OnlineRoutingEngine createEngine(@NonNull EngineType type, - @Nullable Map params) { - switch (type) { - case GRAPHHOPPER: - return new GraphhopperEngine(params); - case OSRM: - return new OsrmEngine(params); - case ORS: - return new OrsEngine(params); - case GPX: - return new GpxEngine(params); - default: - throw new IllegalArgumentException( - "Online routing type {" + type.name() + "} not supported"); - } - } - -} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingUtils.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingUtils.java index 90eb4ea83c..ce8ea65f7c 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingUtils.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingUtils.java @@ -7,8 +7,8 @@ import androidx.annotation.NonNull; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; -import net.osmand.plus.onlinerouting.engine.EngineType; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; +import net.osmand.plus.onlinerouting.engine.EngineType; import net.osmand.util.Algorithms; import org.json.JSONArray; @@ -60,10 +60,10 @@ public class OnlineRoutingUtils { for (int i = 0; i < itemsJson.length(); i++) { JSONObject object = itemsJson.getJSONObject(i); if (object.has(TYPE) && object.has(PARAMS)) { - EngineType type = EngineType.getTypeByName(object.getString(TYPE)); + OnlineRoutingEngine type = EngineType.getTypeByName(object.getString(TYPE)); String paramsString = object.getString(PARAMS); HashMap params = gson.fromJson(paramsString, typeToken); - OnlineRoutingEngine engine = OnlineRoutingFactory.createEngine(type, params); + OnlineRoutingEngine engine = type.newInstance(params); if (!Algorithms.isEmpty(engine.getStringKey())) { engines.add(engine); } @@ -82,7 +82,7 @@ public class OnlineRoutingUtils { continue; } JSONObject jsonObject = new JSONObject(); - jsonObject.put(TYPE, engine.getType().name()); + jsonObject.put(TYPE, engine.getTypeName()); jsonObject.put(PARAMS, gson.toJson(engine.getParams(), type)); jsonArray.put(jsonObject); } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java index 0efd91e759..5b6614691e 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java @@ -1,35 +1,38 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import net.osmand.util.Algorithms; -public enum EngineType { - GRAPHHOPPER("Graphhopper"), - OSRM("OSRM"), - ORS("Openroute Service"), - GPX("GPX"); +public class EngineType { - private final String title; + public final static OnlineRoutingEngine GRAPHHOPPER_TYPE = new GraphhopperEngine(null); + public final static OnlineRoutingEngine OSRM_TYPE = new OsrmEngine(null); + public final static OnlineRoutingEngine ORS_TYPE = new OrsEngine(null); + public final static OnlineRoutingEngine GPX_TYPE = new GpxEngine(null); - EngineType(String title) { - this.title = title; - } + private static OnlineRoutingEngine[] enginesTypes; - public String getTitle() { - return title; + public static OnlineRoutingEngine[] values() { + if (enginesTypes == null) { + enginesTypes = new OnlineRoutingEngine[]{ + GRAPHHOPPER_TYPE, + OSRM_TYPE, + ORS_TYPE, + GPX_TYPE + }; + } + return enginesTypes; } @NonNull - public static EngineType getTypeByName(@Nullable String name) { - if (!Algorithms.isEmpty(name)) { - for (EngineType type : values()) { - if (type.name().equals(name)) { - return type; - } + public static OnlineRoutingEngine getTypeByName(@NonNull String typeName) { + for (OnlineRoutingEngine type : values()) { + if (Algorithms.objectEquals(type.getTypeName(), typeName)) { + return type; } } return values()[0]; } + } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java index 676ea6ba48..eac4771ba3 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java @@ -17,6 +17,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import static net.osmand.plus.onlinerouting.engine.EngineType.GPX_TYPE; + public class GpxEngine extends OnlineRoutingEngine { public GpxEngine(@Nullable Map params) { @@ -25,8 +27,20 @@ public class GpxEngine extends OnlineRoutingEngine { @NonNull @Override - public EngineType getType() { - return EngineType.GPX; + public OnlineRoutingEngine getType() { + return GPX_TYPE; + } + + @Override + @NonNull + public String getTitle() { + return "GPX"; + } + + @NonNull + @Override + public String getTypeName() { + return "GPX"; } @Override @@ -60,6 +74,11 @@ public class GpxEngine extends OnlineRoutingEngine { params.add(EngineParameter.CUSTOM_URL); } + @Override + public OnlineRoutingEngine newInstance(Map params) { + return new GpxEngine(params); + } + @Override @Nullable public OnlineRoutingResponse parseResponse(@NonNull String content, diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java index 68122b3bdd..ae62b8c71d 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import static net.osmand.plus.onlinerouting.engine.EngineType.GRAPHHOPPER_TYPE; import static net.osmand.util.Algorithms.isEmpty; public class GraphhopperEngine extends JsonOnlineRoutingEngine { @@ -32,8 +33,20 @@ public class GraphhopperEngine extends JsonOnlineRoutingEngine { @NonNull @Override - public EngineType getType() { - return EngineType.GRAPHHOPPER; + public OnlineRoutingEngine getType() { + return GRAPHHOPPER_TYPE; + } + + @Override + @NonNull + public String getTitle() { + return "Graphhopper"; + } + + @NonNull + @Override + public String getTypeName() { + return "GRAPHHOPPER"; } @NonNull @@ -52,6 +65,11 @@ public class GraphhopperEngine extends JsonOnlineRoutingEngine { params.add(EngineParameter.API_KEY); } + @Override + public OnlineRoutingEngine newInstance(Map params) { + return new GraphhopperEngine(params); + } + @Override protected void collectAllowedVehicles(@NonNull List vehicles) { vehicles.add(new VehicleType("car", R.string.routing_engine_vehicle_type_car)); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java index 85514dec85..670375c0b5 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java @@ -12,7 +12,6 @@ import net.osmand.data.LatLon; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; -import net.osmand.plus.onlinerouting.OnlineRoutingFactory; import net.osmand.plus.onlinerouting.VehicleType; import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.util.Algorithms; @@ -50,7 +49,13 @@ public abstract class OnlineRoutingEngine implements Cloneable { } @NonNull - public abstract EngineType getType(); + public abstract OnlineRoutingEngine getType(); + + @NonNull + public abstract String getTitle(); + + @NonNull + public abstract String getTypeName(); @Nullable public String getStringKey() { @@ -176,7 +181,7 @@ public abstract class OnlineRoutingEngine implements Cloneable { @NonNull @Override public Object clone() { - return OnlineRoutingFactory.createEngine(getType(), getParams()); + return newInstance(getParams()); } @Override @@ -189,6 +194,8 @@ public abstract class OnlineRoutingEngine implements Cloneable { return Algorithms.objectEquals(getParams(), engine.getParams()); } + public abstract OnlineRoutingEngine newInstance(Map params); + @NonNull public static String generateKey() { return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis(); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java index 9a16be62ee..16a5452caa 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import static net.osmand.plus.onlinerouting.engine.EngineType.ORS_TYPE; import static net.osmand.util.Algorithms.isEmpty; public class OrsEngine extends JsonOnlineRoutingEngine { @@ -29,8 +30,20 @@ public class OrsEngine extends JsonOnlineRoutingEngine { @NonNull @Override - public EngineType getType() { - return EngineType.ORS; + public OnlineRoutingEngine getType() { + return ORS_TYPE; + } + + @Override + @NonNull + public String getTitle() { + return "Openroute Service"; + } + + @NonNull + @Override + public String getTypeName() { + return "ORS"; } @NonNull @@ -49,6 +62,11 @@ public class OrsEngine extends JsonOnlineRoutingEngine { params.add(EngineParameter.API_KEY); } + @Override + public OnlineRoutingEngine newInstance(Map params) { + return new OrsEngine(params); + } + @Override protected void collectAllowedVehicles(@NonNull List vehicles) { vehicles.add(new VehicleType("driving-car", R.string.routing_engine_vehicle_type_car)); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java index 4219204cca..20d98c0daf 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import static net.osmand.plus.onlinerouting.engine.EngineType.OSRM_TYPE; import static net.osmand.util.Algorithms.isEmpty; import static net.osmand.util.Algorithms.objectEquals; @@ -34,9 +35,21 @@ public class OsrmEngine extends JsonOnlineRoutingEngine { } @Override - public @NonNull - EngineType getType() { - return EngineType.OSRM; + @NonNull + public OnlineRoutingEngine getType() { + return OSRM_TYPE; + } + + @Override + @NonNull + public String getTitle() { + return "OSRM"; + } + + @NonNull + @Override + public String getTypeName() { + return "OSRM"; } @NonNull @@ -54,6 +67,11 @@ public class OsrmEngine extends JsonOnlineRoutingEngine { params.add(EngineParameter.CUSTOM_URL); } + @Override + public OnlineRoutingEngine newInstance(Map params) { + return new OsrmEngine(params); + } + @Override protected void collectAllowedVehicles(@NonNull List vehicles) { vehicles.add(new VehicleType("car", R.string.routing_engine_vehicle_type_car)); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java index fee3d02524..175e22016e 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java @@ -39,12 +39,11 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; import net.osmand.plus.onlinerouting.EngineParameter; -import net.osmand.plus.onlinerouting.OnlineRoutingFactory; import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import net.osmand.plus.onlinerouting.OnlineRoutingUtils; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.onlinerouting.engine.EngineType; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; +import net.osmand.plus.onlinerouting.engine.EngineType; import net.osmand.plus.onlinerouting.ui.OnlineRoutingCard.OnTextChangedListener; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.settings.backend.ApplicationMode; @@ -54,7 +53,9 @@ import org.json.JSONException; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.CUSTOM_VEHICLE; @@ -201,15 +202,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { typeCard = new OnlineRoutingCard(mapActivity, isNightMode(), appMode); typeCard.build(mapActivity); typeCard.setHeaderTitle(getString(R.string.shared_string_type)); - List serverItems = new ArrayList<>(); - for (EngineType server : EngineType.values()) { - serverItems.add(new HorizontalSelectionItem(server.getTitle(), server)); + List typeItems = new ArrayList<>(); + for (OnlineRoutingEngine type : EngineType.values()) { + typeItems.add(new HorizontalSelectionItem(type.getTitle(), type)); } - typeCard.setSelectionMenu(serverItems, engine.getType().getTitle(), + typeCard.setSelectionMenu(typeItems, engine.getType().getTitle(), new CallbackWithObject() { @Override public boolean processResult(HorizontalSelectionItem result) { - EngineType type = (EngineType) result.getObject(); + OnlineRoutingEngine type = (OnlineRoutingEngine) result.getObject(); if (engine.getType() != type) { changeEngineType(type); return true; @@ -366,9 +367,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { }); } - private void changeEngineType(EngineType type) { + private void changeEngineType(OnlineRoutingEngine type) { OnlineRoutingEngine tmp = (OnlineRoutingEngine) engine.clone(); - engine = OnlineRoutingFactory.createEngine(type, tmp.getParams()); + engine = type.newInstance(tmp.getParams()); // after changing the type, select the vehicle // with the same name that was selected before @@ -615,7 +616,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private void saveState(@NonNull Bundle outState) { - outState.putString(ENGINE_TYPE_KEY, engine.getType().name()); + outState.putString(ENGINE_TYPE_KEY, engine.getTypeName()); for (EngineParameter key : EngineParameter.values()) { String value = engine.get(key); if (value != null) { @@ -632,14 +633,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { editedEngineKey = savedState.getString(EngineParameter.KEY.name()); initEngine = createInitStateEngine(); String typeKey = savedState.getString(ENGINE_TYPE_KEY); - EngineType type = EngineType.getTypeByName(typeKey); - engine = OnlineRoutingFactory.createEngine(type); + OnlineRoutingEngine type = EngineType.getTypeByName(typeKey); + Map params = new HashMap<>(); for (EngineParameter key : EngineParameter.values()) { String value = savedState.getString(key.name()); if (value != null) { - engine.put(key, value); + params.put(key.name(), value); } } + engine = type.newInstance(params); customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY); selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY)); appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null); @@ -662,7 +664,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { if (editedEngine != null) { engine = (OnlineRoutingEngine) editedEngine.clone(); } else { - engine = OnlineRoutingFactory.createEngine(EngineType.values()[0]); + engine = EngineType.values()[0].newInstance(null); String vehicle = engine.getAllowedVehicles().get(0).getKey(); engine.put(EngineParameter.VEHICLE_KEY, vehicle); if (editedEngineKey != null) { From f75a8f8b58a7831d2c14eddd34466b3966761e09 Mon Sep 17 00:00:00 2001 From: cepprice Date: Tue, 23 Feb 2021 13:45:16 +0500 Subject: [PATCH 08/29] =?UTF-8?q?Easy=20repla=D1=81ement=20of=20color=20fr?= =?UTF-8?q?om=20@ColorRes=20to=20@ColorInt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../net/osmand/plus/OsmAndLocationSimulation.java | 2 +- OsmAnd/src/net/osmand/plus/UiUtilities.java | 2 +- .../osmand/plus/activities/MapActivityLayers.java | 2 +- .../plus/activities/actions/AppModeDialog.java | 14 +++++++------- .../plus/activities/actions/StartGPSStatus.java | 2 +- .../net/osmand/plus/dialogs/ConfigureMapMenu.java | 7 +++---- .../plus/mapillary/MapillaryFiltersFragment.java | 11 +++++------ .../plus/mapsource/InputZoomLevelsBottomSheet.java | 3 +-- .../measurementtool/MeasurementToolFragment.java | 2 +- .../osmand/plus/measurementtool/ProfileCard.java | 2 +- ...outeBetweenPointsBottomSheetDialogFragment.java | 2 +- .../SnapToRoadBottomSheetDialogFragment.java | 2 +- .../plus/monitoring/OsmandMonitoringPlugin.java | 2 +- .../plus/monitoring/TripRecordingBottomSheet.java | 3 +-- .../plus/onlinerouting/ui/OnlineRoutingCard.java | 2 +- .../src/net/osmand/plus/osmedit/OsmNotesMenu.java | 2 +- .../plus/poi/RearrangePoiFiltersFragment.java | 5 ++--- .../profiles/SelectCopyProfilesMenuAdapter.java | 5 ++--- .../plus/profiles/SelectProfileMenuAdapter.java | 5 ++--- .../plus/quickaction/QuickActionListFragment.java | 3 +-- .../plus/rastermaps/OsmandRasterMapsPlugin.java | 2 +- .../routepreparationmenu/RoutingOptionsHelper.java | 4 ++-- .../ShowAlongTheRouteBottomSheet.java | 4 ++-- .../plus/settings/backend/ApplicationMode.java | 9 +++++++++ .../bottomsheets/AnnouncementTimeBottomSheet.java | 2 +- .../RecalculateRouteInDeviationBottomSheet.java | 3 +-- .../bottomsheets/ResetProfilePrefsBottomSheet.java | 3 +-- .../settings/bottomsheets/WakeTimeBottomSheet.java | 3 +-- .../settings/fragments/GlobalSettingsFragment.java | 3 +-- .../settings/fragments/MainSettingsFragment.java | 5 ++--- .../fragments/RouteParametersFragment.java | 2 +- .../fragments/VehicleParametersFragment.java | 2 +- .../src/net/osmand/plus/srtmplugin/SRTMPlugin.java | 2 +- .../osmand/plus/srtmplugin/TerrainFragment.java | 6 ++---- .../osmand/plus/transport/TransportLinesMenu.java | 7 +++---- .../osmand/plus/views/layers/MapControlsLayer.java | 3 +-- .../plus/views/mapwidgets/MapWidgetRegistry.java | 5 ++--- 37 files changed, 67 insertions(+), 76 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java b/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java index 0b2683fcc6..2dbd4f6dd9 100644 --- a/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java @@ -59,7 +59,7 @@ public class OsmAndLocationSimulation { boolean nightMode = app.getDaynightHelper().isNightModeForMapControls(); int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme; ApplicationMode appMode = app.getSettings().getApplicationMode(); - int selectedModeColor = ContextCompat.getColor(app, appMode.getIconColorInfo().getColor(nightMode)); + int selectedModeColor = appMode.getProfileColor(nightMode); AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(ma, themeRes)); builder.setTitle(R.string.animate_route); diff --git a/OsmAnd/src/net/osmand/plus/UiUtilities.java b/OsmAnd/src/net/osmand/plus/UiUtilities.java index aaa9d01f8b..269800c630 100644 --- a/OsmAnd/src/net/osmand/plus/UiUtilities.java +++ b/OsmAnd/src/net/osmand/plus/UiUtilities.java @@ -553,7 +553,7 @@ public class UiUtilities { switch (type) { case PROFILE_DEPENDENT: ApplicationMode appMode = app.getSettings().getApplicationMode(); - activeColor = ContextCompat.getColor(app, appMode.getIconColorInfo().getColor(nightMode)); + activeColor = appMode.getProfileColor(nightMode); break; case TOOLBAR: activeColor = Color.WHITE; diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java index 442e2f41a1..ce2f1f95bf 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java @@ -490,7 +490,7 @@ public class MapActivityLayers { OsmandApplication app = getApplication(); boolean nightMode = isNightMode(app); int themeRes = getThemeRes(app); - int selectedModeColor = ContextCompat.getColor(app, settings.getApplicationMode().getIconColorInfo().getColor(nightMode)); + int selectedModeColor = settings.getApplicationMode().getProfileColor(nightMode); DialogListItemAdapter dialogAdapter = DialogListItemAdapter.createSingleChoiceAdapter( items, nightMode, selectedItem, app, selectedModeColor, themeRes, new View.OnClickListener() { @Override diff --git a/OsmAnd/src/net/osmand/plus/activities/actions/AppModeDialog.java b/OsmAnd/src/net/osmand/plus/activities/actions/AppModeDialog.java index 44222d5586..639bed2bdf 100644 --- a/OsmAnd/src/net/osmand/plus/activities/actions/AppModeDialog.java +++ b/OsmAnd/src/net/osmand/plus/activities/actions/AppModeDialog.java @@ -120,13 +120,13 @@ public class AppModeDialog { final View selection = tb.findViewById(R.id.selection); ImageView iv = (ImageView) tb.findViewById(R.id.app_mode_icon); if (checked) { - iv.setImageDrawable(ctx.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode))); + iv.setImageDrawable(ctx.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode))); iv.setContentDescription(String.format("%s %s", mode.toHumanString(), ctx.getString(R.string.item_checked))); - selection.setBackgroundResource(mode.getIconColorInfo().getColor(nightMode)); + selection.setBackgroundColor(mode.getProfileColor(nightMode)); selection.setVisibility(View.VISIBLE); } else { if (useMapTheme) { - iv.setImageDrawable(ctx.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode))); + iv.setImageDrawable(ctx.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode))); iv.setBackgroundResource(AndroidUtils.resolveAttribute(themedCtx, android.R.attr.selectableItemBackground)); } else { iv.setImageDrawable(ctx.getUIUtilities().getThemedIcon(mode.getIconRes())); @@ -171,7 +171,7 @@ public class AppModeDialog { final boolean checked = selected.contains(mode); ImageView iv = (ImageView) tb.findViewById(R.id.app_mode_icon); ImageView selection = tb.findViewById(R.id.selection); - Drawable drawable = ctx.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode)); + Drawable drawable = ctx.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode)); if (checked) { iv.setImageDrawable(drawable); iv.setContentDescription(String.format("%s %s", mode.toHumanString(), ctx.getString(R.string.item_checked))); @@ -184,7 +184,7 @@ public class AppModeDialog { } else { if (useMapTheme) { if (Build.VERSION.SDK_INT >= 21) { - Drawable active = ctx.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode)); + Drawable active = ctx.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode)); drawable = AndroidUtils.createPressedStateListDrawable(drawable, active); } iv.setImageDrawable(drawable); @@ -195,7 +195,7 @@ public class AppModeDialog { AndroidUtils.setBackground(ctx, selection, nightMode, R.drawable.btn_border_pressed_trans_light, R.drawable.btn_border_pressed_trans_light); } } else { - iv.setImageDrawable(ctx.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode))); + iv.setImageDrawable(ctx.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode))); } iv.setContentDescription(String.format("%s %s", mode.toHumanString(), ctx.getString(R.string.item_unchecked))); } @@ -232,7 +232,7 @@ public class AppModeDialog { int metricsY = (int) ctx.getResources().getDimension(R.dimen.route_info_modes_height); View tb = layoutInflater.inflate(layoutId, null); ImageView iv = (ImageView) tb.findViewById(R.id.app_mode_icon); - iv.setImageDrawable(ctx.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(isNightMode(ctx, useMapTheme)))); + iv.setImageDrawable(ctx.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(isNightMode(ctx, useMapTheme)))); iv.setContentDescription(mode.toHumanString()); // tb.setCompoundDrawablesWithIntrinsicBounds(null, ctx.getIconsCache().getIcon(mode.getIconId(), R.color.app_mode_icon_color), null, null); LayoutParams lp = new LinearLayout.LayoutParams(metricsX, metricsY); diff --git a/OsmAnd/src/net/osmand/plus/activities/actions/StartGPSStatus.java b/OsmAnd/src/net/osmand/plus/activities/actions/StartGPSStatus.java index c8c9a70785..4728c0bce3 100644 --- a/OsmAnd/src/net/osmand/plus/activities/actions/StartGPSStatus.java +++ b/OsmAnd/src/net/osmand/plus/activities/actions/StartGPSStatus.java @@ -121,7 +121,7 @@ public class StartGPSStatus extends OsmAndAction { cb.setLayoutParams(lp); cb.setPadding(dp8, 0, 0, 0); int textColorPrimary = ContextCompat.getColor(activity, isNightMode() ? R.color.text_color_primary_dark : R.color.text_color_primary_light); - int selectedModeColor = ContextCompat.getColor(activity, getSettings().getApplicationMode().getIconColorInfo().getColor(isNightMode())); + int selectedModeColor = getSettings().getApplicationMode().getProfileColor(isNightMode()); cb.setTextColor(textColorPrimary); UiUtilities.setupCompoundButton(isNightMode(), selectedModeColor, cb); diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java index 5b8f38d2b9..1ae5e49e43 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java @@ -172,7 +172,7 @@ public class ConfigureMapMenu { final MapActivity activity, final int themeRes, final boolean nightMode) { final OsmandApplication app = activity.getMyApplication(); final OsmandSettings settings = app.getSettings(); - final int selectedProfileColorRes = settings.getApplicationMode().getIconColorInfo().getColor(nightMode); + final int selectedProfileColor = settings.getApplicationMode().getProfileColor(nightMode); MapLayerMenuListener l = new MapLayerMenuListener(activity, adapter); adapter.addItem(new ContextMenuItem.ItemBuilder() .setId(SHOW_CATEGORY_ID) @@ -217,7 +217,7 @@ public class ConfigureMapMenu { .setIcon(R.drawable.ic_action_transport_bus) .setSecondaryIcon(R.drawable.ic_action_additional_option) .setSelected(selected) - .setColor(selected ? selectedProfileColorRes : ContextMenuItem.INVALID_ID) + .setColor(selected ? selectedProfileColor : ContextMenuItem.INVALID_ID) .setListener(l).createItem()); selected = app.getSelectedGpxHelper().isShowingAnyGpxFiles(); @@ -267,8 +267,7 @@ public class ConfigureMapMenu { final int themeRes, final boolean nightMode) { final OsmandApplication app = activity.getMyApplication(); final OsmandSettings settings = app.getSettings(); - final int selectedProfileColorRes = settings.APPLICATION_MODE.get().getIconColorInfo().getColor(nightMode); - final int selectedProfileColor = ContextCompat.getColor(app, selectedProfileColorRes); + final int selectedProfileColor = settings.APPLICATION_MODE.get().getProfileColor(nightMode); adapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_map_rendering, activity) .setId(MAP_RENDERING_CATEGORY_ID) diff --git a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryFiltersFragment.java b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryFiltersFragment.java index 6b03cd3a6a..3cf0398d87 100644 --- a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryFiltersFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryFiltersFragment.java @@ -61,8 +61,7 @@ public class MapillaryFiltersFragment extends BaseOsmAndFragment { final int backgroundColor = ContextCompat.getColor(getActivity(), nightMode ? R.color.activity_background_color_dark : R.color.activity_background_color_light); final DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM); - final int currentModeColorRes = getMyApplication().getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode); - final int currentModeColor = ContextCompat.getColor(getActivity(), currentModeColorRes); + final int currentModeColor = getMyApplication().getSettings().getApplicationMode().getProfileColor(nightMode); final View view = View.inflate(new ContextThemeWrapper(getContext(), themeRes), R.layout.fragment_mapillary_filters, null); view.findViewById(R.id.mapillary_filters_linear_layout).setBackgroundColor(backgroundColor); @@ -71,17 +70,17 @@ public class MapillaryFiltersFragment extends BaseOsmAndFragment { final View toggleRow = view.findViewById(R.id.toggle_row); final boolean selected = settings.SHOW_MAPILLARY.get(); final int toggleActionStringId = selected ? R.string.shared_string_on : R.string.shared_string_off; - int toggleIconColorId; + int toggleIconColor; int toggleIconId; if (selected) { toggleIconId = R.drawable.ic_action_view; - toggleIconColorId = currentModeColorRes; + toggleIconColor = currentModeColor; } else { toggleIconId = R.drawable.ic_action_hide; - toggleIconColorId = nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; + toggleIconColor = ContextCompat.getColor(getContext(), nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light); } ((AppCompatTextView) toggleRow.findViewById(R.id.toggle_row_title)).setText(toggleActionStringId); - final Drawable drawable = getIcon(toggleIconId, toggleIconColorId); + final Drawable drawable = getPaintedContentIcon(toggleIconId, toggleIconColor); ((AppCompatImageView) toggleRow.findViewById(R.id.toggle_row_icon)).setImageDrawable(drawable); final CompoundButton toggle = (CompoundButton) toggleRow.findViewById(R.id.toggle_row_toggle); toggle.setOnCheckedChangeListener(null); diff --git a/OsmAnd/src/net/osmand/plus/mapsource/InputZoomLevelsBottomSheet.java b/OsmAnd/src/net/osmand/plus/mapsource/InputZoomLevelsBottomSheet.java index fcf881c0eb..2d883e223c 100644 --- a/OsmAnd/src/net/osmand/plus/mapsource/InputZoomLevelsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/mapsource/InputZoomLevelsBottomSheet.java @@ -99,8 +99,7 @@ public class InputZoomLevelsBottomSheet extends MenuBottomSheetDialogFragment { final TextView maxZoomValue = sliderView.findViewById(R.id.zoom_value_max); maxZoomValue.setText(String.valueOf(maxZoom)); RangeSlider slider = sliderView.findViewById(R.id.zoom_slider); - int colorProfileRes = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode); - int colorProfile = ContextCompat.getColor(app, colorProfileRes); + int colorProfile = app.getSettings().getApplicationMode().getProfileColor(nightMode); UiUtilities.setupSlider(slider, nightMode, colorProfile, true); slider.setValueFrom(SLIDER_FROM); slider.setValueTo(SLIDER_TO); diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index cc17d2ac9f..b78434dab9 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -1338,7 +1338,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route snapToRoadBtn.setVisibility(View.VISIBLE); profileWithConfig.setVisibility(View.GONE); } else { - icon = getIcon(appMode.getIconRes(), appMode.getIconColorInfo().getColor(nightMode)); + icon = getPaintedContentIcon(appMode.getIconRes(), appMode.getProfileColor(nightMode)); snapToRoadBtn.setVisibility(View.GONE); profileWithConfig.setVisibility(View.VISIBLE); } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/ProfileCard.java b/OsmAnd/src/net/osmand/plus/measurementtool/ProfileCard.java index 8fc3be3037..179ad54645 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/ProfileCard.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/ProfileCard.java @@ -49,7 +49,7 @@ public class ProfileCard extends BaseCard { for (int i = 0; i < modes.size(); i++) { ApplicationMode mode = modes.get(i); LinearLayout container = view.findViewById(R.id.content_container); - Drawable icon = app.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode)); + Drawable icon = app.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode)); String title = mode.toHumanString(); View.OnClickListener onClickListener = new View.OnClickListener() { @Override diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java index 54bc3469be..12eff78327 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java @@ -117,7 +117,7 @@ public class RouteBetweenPointsBottomSheetDialogFragment extends BottomSheetBeha for (int i = 0; i < modes.size(); i++) { ApplicationMode mode = modes.get(i); if (!"public_transport".equals(mode.getRoutingProfile())) { - icon = app.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode)); + icon = app.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode)); addProfileView(navigationType, onClickListener, i, icon, mode.toHumanString(), mode.equals(appMode)); } } diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SnapToRoadBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SnapToRoadBottomSheetDialogFragment.java index 35f3bc47cd..082633a854 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SnapToRoadBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SnapToRoadBottomSheetDialogFragment.java @@ -106,7 +106,7 @@ public class SnapToRoadBottomSheetDialogFragment extends BottomSheetDialogFragme for (int i = 0; i < modes.size(); i++) { ApplicationMode mode = modes.get(i); - Drawable icon = app.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColorInfo().getColor(nightMode)); + Drawable icon = app.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getProfileColor(nightMode)); addProfileView(container, onClickListener, i, icon, mode.toHumanString()); } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java index 42bae2ab62..b5e557816d 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java @@ -544,7 +544,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { ApplicationMode appMode = app.getSettings().getApplicationMode(); int textColorPrimary = ContextCompat.getColor(app, nightMode ? R.color.text_color_primary_dark : R.color.text_color_primary_light); int textColorSecondary = ContextCompat.getColor(app, nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light); - int selectedModeColor = ContextCompat.getColor(uiCtx, appMode.getIconColorInfo().getColor(nightMode)); + int selectedModeColor = appMode.getProfileColor(nightMode); LinearLayout ll = new LinearLayout(uiCtx); final int dp24 = AndroidUtils.dpToPx(uiCtx, 24f); final int dp8 = AndroidUtils.dpToPx(uiCtx, 8f); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java index 178e662176..e4663b5609 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -115,8 +115,7 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { container = itemView.findViewById(R.id.always_ask_and_range_slider_container); RangeSlider intervalSlider = itemView.findViewById(R.id.interval_slider); intervalSlider.setValueTo(secondsLength + minutesLength - 1); - int currentModeColorRes = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode); - int currentModeColor = ContextCompat.getColor(app, currentModeColorRes); + int currentModeColor = app.getSettings().getApplicationMode().getProfileColor(nightMode); UiUtilities.setupSlider(intervalSlider, nightMode, currentModeColor, true); container.setVisibility(View.GONE); intervalSlider.addOnChangeListener(new RangeSlider.OnChangeListener() { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java index 39951b4c2c..1a2be2b134 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java @@ -78,7 +78,7 @@ public class OnlineRoutingCard extends BaseCard { bottomDivider = view.findViewById(R.id.bottom_divider); button = view.findViewById(R.id.button); - int activeColor = ContextCompat.getColor(app, appMode.getIconColorInfo().getColor(nightMode)); + int activeColor = appMode.getProfileColor(nightMode); textFieldBoxes.setPrimaryColor(activeColor); textFieldBoxes.setGravityFloatingLabel(Gravity.START); diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java index 3c7c387a36..0279955801 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java @@ -46,7 +46,7 @@ public class OsmNotesMenu { final boolean nightMode = isNightMode(app); final int themeRes = getThemeRes(app); - final int selectedModeColor = ContextCompat.getColor(app, settings.getApplicationMode().getIconColorInfo().getColor(nightMode)); + final int selectedModeColor = settings.getApplicationMode().getProfileColor(nightMode); final int osmNotesStringId = R.string.layer_osm_bugs; final int showZoomLevelStringId = R.string.show_from_zoom_level; diff --git a/OsmAnd/src/net/osmand/plus/poi/RearrangePoiFiltersFragment.java b/OsmAnd/src/net/osmand/plus/poi/RearrangePoiFiltersFragment.java index 8ddd677be2..55d8d350e1 100644 --- a/OsmAnd/src/net/osmand/plus/poi/RearrangePoiFiltersFragment.java +++ b/OsmAnd/src/net/osmand/plus/poi/RearrangePoiFiltersFragment.java @@ -310,13 +310,12 @@ public class RearrangePoiFiltersFragment extends DialogFragment implements Selec ImageView profileIcon = (ImageView) view.findViewById(R.id.profile_icon); if (profileIcon != null) { int iconRes = selectedAppMode.getIconRes(); - int iconColor = selectedAppMode.getIconColorInfo().getColor(nightMode); - profileIcon.setImageDrawable(uiUtilities.getPaintedIcon(iconRes, iconColor)); + profileIcon.setImageDrawable(uiUtilities.getPaintedIcon(iconRes, selectedAppMode.getProfileColor(nightMode))); } View profileButton = view.findViewById(R.id.profile_button); if (profileButton != null) { - int iconColor = getSelectedAppMode().getIconColorInfo().getColor(nightMode); + int iconColor = getSelectedAppMode().getProfileColor(nightMode); int bgColor = ContextCompat.getColor(app, nightMode ? R.color.divider_color_dark : R.color.active_buttons_and_links_text_light); int selectedColor = UiUtilities.getColorWithAlpha(iconColor, 0.3f); diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectCopyProfilesMenuAdapter.java b/OsmAnd/src/net/osmand/plus/profiles/SelectCopyProfilesMenuAdapter.java index efe1b00a2e..53dbef23bd 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectCopyProfilesMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectCopyProfilesMenuAdapter.java @@ -67,10 +67,9 @@ public class SelectCopyProfilesMenuAdapter extends AbstractProfileMenuAdapter Date: Tue, 23 Feb 2021 18:42:26 +0500 Subject: [PATCH 09/29] Small fixes --- .../net/osmand/plus/settings/backend/ApplicationMode.java | 7 +++++-- .../plus/settings/fragments/ProfileAppearanceFragment.java | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java index f259884d6c..0348bf3eb7 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java @@ -1,5 +1,6 @@ package net.osmand.plus.settings.backend; +import androidx.annotation.ColorInt; import androidx.annotation.DrawableRes; import androidx.core.content.ContextCompat; @@ -464,12 +465,14 @@ public class ApplicationMode { return app.getSettings().LOCATION_ICON.getModeValue(this); } + @ColorInt public int getProfileColor(boolean nightMode) { int index = getCustomIconColorIndex(); - if (index == -1) { + List customColors = getCustomIconColors(); + if (index < 0 || index >= customColors.size()) { return ContextCompat.getColor(app, getIconColorInfo().getColor(nightMode)); } - return Integer.parseInt(getCustomIconColors().get(index)); + return Algorithms.parseColor(customColors.get(index)); } public void setLocationIcon(LocationIcon locationIcon) { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java index eda8bb5f97..1e8f689178 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java @@ -944,7 +944,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O changedProfile.customColorIndex = -1; changedProfile.color = changedProfile.getProfileColorByColorValue(color); } else { - changedProfile.customColorIndex = color; + changedProfile.customColorIndex = cardOfColors.getIndexOfSelectedColor(); changedProfile.color = null; } @@ -1006,7 +1006,9 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O LocationIcon locationIcon; public int getActualColor() { - return customColorIndex != -1 ? customColorIndex : ContextCompat.getColor(app, color.getColor(isNightMode())); + return customColorIndex != -1 ? + Algorithms.parseColor(settings.CUSTOM_ICON_COLORS.getStringsListForProfile(getSelectedAppMode()).get(customColorIndex)) : + ContextCompat.getColor(app, color.getColor(isNightMode())); } public ProfileIconColors getProfileColorByColorValue(int colorValue) { From b0bb03fa8f71b127e452644845ad50d22d09c721 Mon Sep 17 00:00:00 2001 From: cepprice Date: Tue, 23 Feb 2021 22:13:48 +0500 Subject: [PATCH 10/29] The rest custom color implementations --- OsmAnd/src/net/osmand/AndroidUtils.java | 37 ++++++++++++++++ .../net/osmand/plus/ContextMenuAdapter.java | 44 ++++++++++++------- .../src/net/osmand/plus/ContextMenuItem.java | 18 +++++++- .../plus/activities/MapActivityActions.java | 6 +-- .../plus/base/BottomSheetDialogFragment.java | 11 +++++ .../BottomSheetItemWithCompoundButton.java | 16 ++++++- .../plus/dialogs/DetailsBottomSheet.java | 6 +-- .../SelectMapViewQuickActionsBottomSheet.java | 4 +- .../OptionsBottomSheetDialogFragment.java | 2 +- ...electedPointBottomSheetDialogFragment.java | 2 +- .../EditTrackGroupDialogFragment.java | 2 +- .../plus/profiles/AppProfileArrayAdapter.java | 2 +- .../profiles/ConfigureProfileMenuAdapter.java | 13 +++--- .../plus/profiles/EditProfilesFragment.java | 13 +++--- .../OnlineRoutingEngineDataObject.java | 2 +- .../plus/profiles/ProfileDataObject.java | 17 ++++--- .../plus/profiles/ProfileDataUtils.java | 2 +- .../plus/profiles/ProfileIconColors.java | 1 + .../profiles/RoutingProfileDataObject.java | 2 +- .../SelectMultipleProfilesBottomSheet.java | 7 +-- .../profiles/SelectProfileBottomSheet.java | 5 ++- .../profiles/SelectProfileMenuAdapter.java | 31 +++++++------ .../plus/quickaction/SwitchableAction.java | 13 +++--- .../actions/SwitchProfileAction.java | 8 ++-- .../AvoidRoadsBottomSheetDialogFragment.java | 8 ++++ .../RouteOptionsBottomSheet.java | 22 +++++----- .../settings/backend/ApplicationMode.java | 33 ++++++++------ .../plus/settings/backend/OsmandSettings.java | 2 +- .../backend/backup/ProfileSettingsItem.java | 1 + .../BooleanPreferenceBottomSheet.java | 5 +-- .../ElevationDateBottomSheet.java | 6 ++- .../MultiSelectPreferencesBottomSheet.java | 2 +- ...ecalculateRouteInDeviationBottomSheet.java | 2 +- .../ResetProfilePrefsBottomSheet.java | 6 +-- .../SingleSelectPreferenceBottomSheet.java | 8 +++- .../fragments/BaseSettingsFragment.java | 14 +++--- .../fragments/DuplicatesSettingsAdapter.java | 7 ++- .../fragments/ExportItemsBottomSheet.java | 5 ++- .../fragments/ProfileAppearanceFragment.java | 31 ++++++------- .../plus/views/layers/MapControlsLayer.java | 39 ++++++++++++++-- .../plus/views/layers/PointLocationLayer.java | 19 +++++--- .../SelectWikiLanguagesBottomSheet.java | 12 ++--- 42 files changed, 329 insertions(+), 157 deletions(-) diff --git a/OsmAnd/src/net/osmand/AndroidUtils.java b/OsmAnd/src/net/osmand/AndroidUtils.java index 545e7b7391..298032704d 100644 --- a/OsmAnd/src/net/osmand/AndroidUtils.java +++ b/OsmAnd/src/net/osmand/AndroidUtils.java @@ -333,6 +333,43 @@ public class AndroidUtils { ); } + public static ColorStateList createCheckedColorIntStateList(@ColorInt int normal, @ColorInt int checked) { + return createCheckedColorIntStateList(false, normal, checked, 0, 0); + } + + public static ColorStateList createCheckedColorIntStateList(boolean night, + @ColorInt int lightNormal, @ColorInt int lightChecked, + @ColorInt int darkNormal, @ColorInt int darkChecked) { + return createColorIntStateList(night, android.R.attr.state_checked, + lightNormal, lightChecked, darkNormal, darkChecked); + } + + public static ColorStateList createEnabledColorIntStateList(@ColorInt int normal, @ColorInt int pressed) { + return createEnabledColorIntStateList(false, normal, pressed, 0, 0); + } + + public static ColorStateList createEnabledColorIntStateList(boolean night, + @ColorInt int lightNormal, @ColorInt int lightPressed, + @ColorInt int darkNormal, @ColorInt int darkPressed) { + return createColorIntStateList(night, android.R.attr.state_enabled, + lightNormal, lightPressed, darkNormal, darkPressed); + } + + private static ColorStateList createColorIntStateList(boolean night, int state, + @ColorInt int lightNormal, @ColorInt int lightState, + @ColorInt int darkNormal, @ColorInt int darkState) { + return new ColorStateList( + new int[][]{ + new int[]{state}, + new int[]{} + }, + new int[]{ + night ? darkState : lightState, + night ? darkNormal : lightNormal + } + ); + } + public static StateListDrawable createCheckedStateListDrawable(Drawable normal, Drawable checked) { return createStateListDrawable(normal, checked, android.R.attr.state_checked); } diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java index 381125e0ec..12eec8af31 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java @@ -249,8 +249,7 @@ public class ContextMenuAdapter { final ContextMenuItem item = getItem(position); int layoutId = item.getLayout(); layoutId = layoutId != ContextMenuItem.INVALID_ID ? layoutId : DEFAULT_LAYOUT_ID; - int currentModeColorRes = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode); - int currentModeColor = ContextCompat.getColor(app, currentModeColorRes); + int currentModeColor = app.getSettings().getApplicationMode().getProfileColor(nightMode); if (layoutId == R.layout.mode_toggles) { final Set selected = new LinkedHashSet<>(); return AppModeDialog.prepareAppModeDrawerView((Activity) getContext(), @@ -278,15 +277,20 @@ public class ContextMenuAdapter { } if (layoutId == R.layout.main_menu_drawer_btn_switch_profile || layoutId == R.layout.main_menu_drawer_btn_configure_profile) { - int colorResId = item.getColorRes(); - int colorNoAlpha = ContextCompat.getColor(app, colorResId); + int colorNoAlpha; + if (item.getColor() != null) { + colorNoAlpha = item.getColor(); + } else { + int colorResId = item.getColorRes(); + colorNoAlpha = ContextCompat.getColor(app, colorResId); + } TextView title = convertView.findViewById(R.id.title); title.setText(item.getTitle()); if (layoutId == R.layout.main_menu_drawer_btn_switch_profile) { ImageView icon = convertView.findViewById(R.id.icon); - icon.setImageDrawable(mIconsCache.getIcon(item.getIcon(), colorResId)); + icon.setImageDrawable(mIconsCache.getPaintedIcon(item.getIcon(), colorNoAlpha)); ImageView icArrow = convertView.findViewById(R.id.ic_expand_list); icArrow.setImageDrawable(mIconsCache.getIcon(item.getSecondaryIcon())); TextView desc = convertView.findViewById(R.id.description); @@ -309,8 +313,13 @@ public class ContextMenuAdapter { int tag = item.getTag(); - int colorResId = item.getColorRes(); - int colorNoAlpha = ContextCompat.getColor(app, colorResId); + int colorNoAlpha; + if (item.getColor() != null) { + colorNoAlpha = item.getColor(); + } else { + int colorResId = item.getColorRes(); + colorNoAlpha = ContextCompat.getColor(app, colorResId); + } TextView title = convertView.findViewById(R.id.title); TextView desc = convertView.findViewById(R.id.description); ImageView icon = convertView.findViewById(R.id.icon); @@ -331,7 +340,7 @@ public class ContextMenuAdapter { AndroidUiHelper.updateVisibility(icon, true); AndroidUiHelper.updateVisibility(desc, true); AndroidUtils.setTextPrimaryColor(app, title, nightMode); - icon.setImageDrawable(mIconsCache.getIcon(item.getIcon(), colorResId)); + icon.setImageDrawable(mIconsCache.getPaintedIcon(item.getIcon(), colorNoAlpha)); desc.setText(item.getDescription()); boolean selectedMode = tag == PROFILES_CHOSEN_PROFILE_TAG; if (selectedMode) { @@ -420,16 +429,19 @@ public class ContextMenuAdapter { } else { if (item.getIcon() != ContextMenuItem.INVALID_ID) { int colorRes = item.getColorRes(); - if (colorRes == ContextMenuItem.INVALID_ID) { - if (!item.shouldSkipPainting()) { - colorRes = lightTheme ? R.color.icon_color_default_light : R.color.icon_color_default_dark; - } else { - colorRes = 0; + Drawable drawable; + if (profileDependent) { + drawable = mIconsCache.getPaintedIcon(item.getIcon(), currentModeColor); + } else { + if (colorRes == ContextMenuItem.INVALID_ID) { + if (!item.shouldSkipPainting()) { + colorRes = lightTheme ? R.color.icon_color_default_light : R.color.icon_color_default_dark; + } else { + colorRes = 0; + } } - } else if (profileDependent) { - colorRes = currentModeColorRes; + drawable = mIconsCache.getIcon(item.getIcon(), colorRes); } - final Drawable drawable = mIconsCache.getIcon(item.getIcon(), colorRes); ((AppCompatImageView) convertView.findViewById(R.id.icon)).setImageDrawable(drawable); convertView.findViewById(R.id.icon).setVisibility(View.VISIBLE); } else if (convertView.findViewById(R.id.icon) != null) { diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuItem.java b/OsmAnd/src/net/osmand/plus/ContextMenuItem.java index 3718169532..a4b846613d 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuItem.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuItem.java @@ -21,6 +21,8 @@ public class ContextMenuItem { private int mIcon; @ColorRes private int colorRes; + @ColorInt + private Integer color; @DrawableRes private int secondaryIcon; private Boolean selected; @@ -49,6 +51,7 @@ public class ContextMenuItem { String title, @DrawableRes int icon, @ColorRes int colorRes, + @ColorInt Integer color, @DrawableRes int secondaryIcon, Boolean selected, int progress, @@ -73,6 +76,7 @@ public class ContextMenuItem { this.title = title; this.mIcon = icon; this.colorRes = colorRes; + this.color = color; this.secondaryIcon = secondaryIcon; this.selected = selected; this.progress = progress; @@ -114,6 +118,11 @@ public class ContextMenuItem { return colorRes; } + @ColorInt + Integer getColor() { + return color; + } + @ColorRes public int getThemedColorRes(Context context) { if (skipPaintingWithoutColor || getColorRes() != INVALID_ID) { @@ -270,6 +279,8 @@ public class ContextMenuItem { private int mIcon = INVALID_ID; @ColorRes private int mColorRes = INVALID_ID; + @ColorInt + private Integer mColor = null; @DrawableRes private int mSecondaryIcon = INVALID_ID; private Boolean mSelected = null; @@ -312,6 +323,11 @@ public class ContextMenuItem { return this; } + public ItemBuilder setColorInt(@ColorInt int color) { + mColor = color; + return this; + } + public ItemBuilder setIcon(@DrawableRes int icon) { mIcon = icon; return this; @@ -422,7 +438,7 @@ public class ContextMenuItem { } public ContextMenuItem createItem() { - ContextMenuItem item = new ContextMenuItem(mTitleId, mTitle, mIcon, mColorRes, mSecondaryIcon, + ContextMenuItem item = new ContextMenuItem(mTitleId, mTitle, mIcon, mColorRes, mColor, mSecondaryIcon, mSelected, mProgress, mLayout, mLoading, mIsCategory, mIsClickable, mSkipPaintingWithoutColor, mOrder, mDescription, mOnUpdateCallback, mItemClickListener, mIntegerListener, mProgressListener, mItemDeleteAction, mHideDivider, mHideCompoundButton, mMinHeight, mTag, mId); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 258ed7be38..acc557ed09 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -749,7 +749,7 @@ public class MapActivityActions implements DialogProvider { optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.profile_list_item) .setIcon(appMode.getIconRes()) - .setColor(appMode.getIconColorInfo().getColor(nightMode)) + .setColorInt(appMode.getProfileColor(nightMode)) .setTag(tag) .setTitle(appMode.toHumanString()) .setDescription(modeDescription) @@ -1059,7 +1059,7 @@ public class MapActivityActions implements DialogProvider { .setId(DRAWER_SWITCH_PROFILE_ID) .setIcon(currentMode.getIconRes()) .setSecondaryIcon(icArrowResId) - .setColor(currentMode.getIconColorInfo().getColor(nightMode)) + .setColorInt(currentMode.getProfileColor(nightMode)) .setTitle(currentMode.toHumanString()) .setDescription(modeDescription) .setListener(new ItemClickListener() { @@ -1073,7 +1073,7 @@ public class MapActivityActions implements DialogProvider { .createItem()); optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.main_menu_drawer_btn_configure_profile) .setId(DRAWER_CONFIGURE_PROFILE_ID) - .setColor(currentMode.getIconColorInfo().getColor(nightMode)) + .setColorInt(currentMode.getProfileColor(nightMode)) .setTitle(getString(R.string.configure_profile)) .setListener(new ItemClickListener() { @Override diff --git a/OsmAnd/src/net/osmand/plus/base/BottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/base/BottomSheetDialogFragment.java index c33b183b65..4a9924fd0e 100644 --- a/OsmAnd/src/net/osmand/plus/base/BottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/base/BottomSheetDialogFragment.java @@ -10,6 +10,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.Window; +import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; @@ -91,6 +92,16 @@ public abstract class BottomSheetDialogFragment extends DialogFragment { } } + @Nullable + protected Drawable getPaintedIcon(@DrawableRes int drawableRes, @ColorInt int color) { + OsmandApplication app = getMyApplication(); + if (app != null) { + return app.getUIUtilities().getPaintedIcon(drawableRes, color); + } else { + return null; + } + } + @Nullable protected Drawable getContentIcon(@DrawableRes int drawableRes) { OsmandApplication app = getMyApplication(); diff --git a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithCompoundButton.java b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithCompoundButton.java index 10fa8a461e..a8c508433e 100644 --- a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithCompoundButton.java +++ b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithCompoundButton.java @@ -8,6 +8,7 @@ import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; +import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; import androidx.annotation.LayoutRes; import androidx.core.content.ContextCompat; @@ -22,6 +23,7 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri private ColorStateList buttonTintList; private OnCheckedChangeListener onCheckedChangeListener; @ColorRes private int compoundButtonColorId; + @ColorInt private Integer compoundButtonColor; private CompoundButton compoundButton; @@ -80,6 +82,10 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri this.compoundButtonColorId = compoundButtonColorId; } + public void setCompoundButtonColor(@ColorInt int compoundButtonColor) { + this.compoundButtonColor = compoundButtonColor; + } + public CompoundButton getCompoundButton() { return compoundButton; } @@ -91,7 +97,9 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri if (compoundButton != null) { compoundButton.setChecked(checked); compoundButton.setOnCheckedChangeListener(onCheckedChangeListener); - if (compoundButtonColorId != INVALID_ID) { + if (compoundButtonColor != null) { + UiUtilities.setupCompoundButton(nightMode, compoundButtonColor, compoundButton); + } else if (compoundButtonColorId != INVALID_ID) { UiUtilities.setupCompoundButton(nightMode, ContextCompat.getColor(context, compoundButtonColorId), compoundButton); } else { CompoundButtonCompat.setButtonTintList(compoundButton, buttonTintList); @@ -105,6 +113,7 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri protected ColorStateList buttonTintList; protected OnCheckedChangeListener onCheckedChangeListener; @ColorRes protected int compoundButtonColorId = INVALID_ID; + @ColorInt protected Integer compoundButtonColor = null; public Builder setChecked(boolean checked) { this.checked = checked; @@ -125,6 +134,11 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri this.compoundButtonColorId = compoundButtonColorId; return this; } + + public Builder setCompoundButtonColor(@ColorInt int compoundButtonColor) { + this.compoundButtonColor = compoundButtonColor; + return this; + } public BottomSheetItemWithCompoundButton create() { return new BottomSheetItemWithCompoundButton(customView, diff --git a/OsmAnd/src/net/osmand/plus/dialogs/DetailsBottomSheet.java b/OsmAnd/src/net/osmand/plus/dialogs/DetailsBottomSheet.java index 673f1ce3e7..b80acfedb0 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/DetailsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/DetailsBottomSheet.java @@ -98,7 +98,7 @@ public class DetailsBottomSheet extends BasePreferenceBottomSheet { @Override public void createMenuItems(Bundle savedInstanceState) { - int selectedProfileColorRes = app.getSettings().APPLICATION_MODE.get().getIconColorInfo().getColor(nightMode); + int selectedProfileColor = app.getSettings().APPLICATION_MODE.get().getProfileColor(nightMode); float spacing = getResources().getDimension(R.dimen.line_spacing_extra_description); LinearLayout linearLayout = new LinearLayout(app); linearLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); @@ -139,7 +139,7 @@ public class DetailsBottomSheet extends BasePreferenceBottomSheet { streetLightsNightPref.set(!onLeftClick); } }) - .setCompoundButtonColorId(selectedProfileColorRes) + .setCompoundButtonColor(selectedProfileColor) .setChecked(pref.get()) .setTitle(propertyName) .setIconHidden(true) @@ -160,7 +160,7 @@ public class DetailsBottomSheet extends BasePreferenceBottomSheet { } else if (!STREET_LIGHTING_NIGHT.equals(property.getAttrName())) { final BottomSheetItemWithCompoundButton[] item = new BottomSheetItemWithCompoundButton[1]; item[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() - .setCompoundButtonColorId(selectedProfileColorRes) + .setCompoundButtonColor(selectedProfileColor) .setChecked(pref.get()) .setTitle(propertyName) .setIconHidden(true) diff --git a/OsmAnd/src/net/osmand/plus/dialogs/SelectMapViewQuickActionsBottomSheet.java b/OsmAnd/src/net/osmand/plus/dialogs/SelectMapViewQuickActionsBottomSheet.java index 4c5f199824..5b7ba9cc9e 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/SelectMapViewQuickActionsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/SelectMapViewQuickActionsBottomSheet.java @@ -174,8 +174,8 @@ public class SelectMapViewQuickActionsBottomSheet extends MenuBottomSheetDialogF if (appMode != null) { boolean selected = key.equals(selectedItem); int iconId = appMode.getIconRes(); - int colorId = appMode.getIconColorInfo().getColor(nightMode); - Drawable icon = getIcon(iconId, colorId); + int color = appMode.getProfileColor(nightMode); + Drawable icon = getPaintedIcon(iconId, color); String translatedName = appMode.toHumanString(); createItemRow(selected, counter, icon, translatedName, key); counter++; diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/OptionsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/OptionsBottomSheetDialogFragment.java index 35397f269e..8c8eacee67 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/OptionsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/OptionsBottomSheetDialogFragment.java @@ -55,7 +55,7 @@ public class OptionsBottomSheetDialogFragment extends MenuBottomSheetDialogFragm icon = getContentIcon(R.drawable.ic_action_split_interval); } else { description = routeAppMode.toHumanString(); - icon = getIcon(routeAppMode.getIconRes(), routeAppMode.getIconColorInfo().getColor(nightMode)); + icon = getPaintedIcon(routeAppMode.getIconRes(), routeAppMode.getProfileColor(nightMode)); } } else { description = getString(R.string.shared_string_undefined); diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/SelectedPointBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/SelectedPointBottomSheetDialogFragment.java index b18592edb8..d482299931 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/SelectedPointBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/SelectedPointBottomSheetDialogFragment.java @@ -403,7 +403,7 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo if (MeasurementEditingContext.DEFAULT_APP_MODE.equals(routeAppMode)) { icon = getContentIcon(R.drawable.ic_action_split_interval); } else { - icon = getIcon(routeAppMode.getIconRes(), routeAppMode.getIconColorInfo().getColor(nightMode)); + icon = getPaintedIcon(routeAppMode.getIconRes(), routeAppMode.getProfileColor(nightMode)); } return icon; } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java index 1e8efe343b..674ee76042 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java @@ -121,7 +121,7 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment final ApplicationMode mode = app.getSettings().getApplicationMode(); final BottomSheetItemWithCompoundButton[] showOnMapItem = new BottomSheetItemWithCompoundButton[1]; showOnMapItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() - .setCompoundButtonColorId(mode.getIconColorInfo().getColor(nightMode)) + .setCompoundButtonColor(mode.getProfileColor(nightMode)) .setChecked(checked) .setTitle(getString(R.string.shared_string_show_on_map)) .setCustomView(getCustomButtonView(app, mode, checked, nightMode)) diff --git a/OsmAnd/src/net/osmand/plus/profiles/AppProfileArrayAdapter.java b/OsmAnd/src/net/osmand/plus/profiles/AppProfileArrayAdapter.java index 58f1c721ab..6107476426 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/AppProfileArrayAdapter.java +++ b/OsmAnd/src/net/osmand/plus/profiles/AppProfileArrayAdapter.java @@ -67,7 +67,7 @@ public class AppProfileArrayAdapter extends ArrayAdapter { Drawable iconDrawable; boolean lightContent = app.getSettings().isLightContent(); if (mode.isSelected()) { - iconDrawable = app.getUIUtilities().getIcon(mode.getIconRes(), mode.getIconColor(!lightContent)); + iconDrawable = app.getUIUtilities().getPaintedIcon(mode.getIconRes(), mode.getIconColor(!lightContent)); } else { iconDrawable = app.getUIUtilities().getIcon(mode.getIconRes(), lightContent); } diff --git a/OsmAnd/src/net/osmand/plus/profiles/ConfigureProfileMenuAdapter.java b/OsmAnd/src/net/osmand/plus/profiles/ConfigureProfileMenuAdapter.java index a2e024f860..6a92563647 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/ConfigureProfileMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/profiles/ConfigureProfileMenuAdapter.java @@ -6,10 +6,12 @@ import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; +import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.view.ContextThemeWrapper; +import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; import net.osmand.PlatformUtil; @@ -35,8 +37,8 @@ public class ConfigureProfileMenuAdapter extends AbstractProfileMenuAdapter getItems() { @@ -137,9 +140,9 @@ public class ConfigureProfileMenuAdapter extends AbstractProfileMenuAdapter() { @@ -274,8 +275,9 @@ public class EditProfilesFragment extends BaseOsmAndFragment { private boolean deleted; private boolean customProfile; - EditProfileDataObject(String stringKey, String name, String descr, int iconRes, boolean isSelected, boolean customProfile, boolean deleted, ProfileIconColors iconColor, int order) { - super(name, descr, stringKey, iconRes, isSelected, iconColor); + EditProfileDataObject(String stringKey, String name, String descr, int iconRes, boolean isSelected, + boolean customProfile, boolean deleted, @ColorInt int iconColorLight, @ColorInt int iconColorDark, int order) { + super(name, descr, stringKey, iconRes, isSelected, iconColorLight, iconColorDark); this.customProfile = customProfile; this.deleted = deleted; this.order = order; @@ -365,10 +367,9 @@ public class EditProfilesFragment extends BaseOsmAndFragment { if (iconRes == 0 || iconRes == -1) { iconRes = R.drawable.ic_action_world_globe; } - int profileColorResId = mode.getIconColor(nightMode); - int colorNoAlpha = ContextCompat.getColor(app, profileColorResId); + int colorNoAlpha = mode.getIconColor(nightMode); - profileViewHolder.icon.setImageDrawable(uiUtilities.getIcon(iconRes, profileColorResId)); + profileViewHolder.icon.setImageDrawable(uiUtilities.getPaintedIcon(iconRes, colorNoAlpha)); //set up cell color Drawable drawable = UiUtilities.getColoredSelectableDrawable(app, colorNoAlpha, 0.3f); diff --git a/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java b/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java index fd0f593462..ea513b405c 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java +++ b/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java @@ -12,7 +12,7 @@ public class OnlineRoutingEngineDataObject extends ProfileDataObject { String description, String stringKey, int order) { - super(name, description, stringKey, R.drawable.ic_world_globe_dark, false, null); + super(name, description, stringKey, R.drawable.ic_world_globe_dark, false, null, null); this.order = order; } diff --git a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataObject.java b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataObject.java index 35b5be5620..048c7693d1 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataObject.java +++ b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataObject.java @@ -1,5 +1,6 @@ package net.osmand.plus.profiles; +import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; import androidx.annotation.NonNull; @@ -12,15 +13,20 @@ public class ProfileDataObject implements Comparable { private String stringKey; private boolean isSelected; private boolean isEnabled; - private ProfileIconColors iconColor; + @ColorInt + private Integer iconColorLight; + @ColorInt + private Integer iconColorDark; - public ProfileDataObject(String name, String description, String stringKey, int iconRes, boolean isSelected, ProfileIconColors iconColor) { + public ProfileDataObject(String name, String description, String stringKey, int iconRes, boolean isSelected, + @ColorInt Integer iconColorLight, @ColorInt Integer iconColorDark) { this.name = name; this.iconRes = iconRes; this.description = description; this.isSelected = isSelected; this.stringKey = stringKey; - this.iconColor = iconColor; + this.iconColorLight = iconColorLight; + this.iconColorDark = iconColorDark; } public String getName() { @@ -55,8 +61,9 @@ public class ProfileDataObject implements Comparable { return stringKey; } - @ColorRes public int getIconColor(boolean isNightMode) { - return iconColor.getColor(isNightMode); + @ColorInt + public int getIconColor(boolean isNightMode) { + return isNightMode ? iconColorDark : iconColorLight; } @Override diff --git a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java index 6306dee9cc..bc939546cf 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java +++ b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java @@ -33,7 +33,7 @@ public class ProfileDataUtils { description = getAppModeDescription(app, mode); } profiles.add(new ProfileDataObject(mode.toHumanString(), description, - mode.getStringKey(), mode.getIconRes(), false, mode.getIconColorInfo())); + mode.getStringKey(), mode.getIconRes(), false, mode.getProfileColor(false), mode.getProfileColor(true))); } return profiles; } diff --git a/OsmAnd/src/net/osmand/plus/profiles/ProfileIconColors.java b/OsmAnd/src/net/osmand/plus/profiles/ProfileIconColors.java index 3fd97cc523..e7bccfde64 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/ProfileIconColors.java +++ b/OsmAnd/src/net/osmand/plus/profiles/ProfileIconColors.java @@ -31,6 +31,7 @@ public enum ProfileIconColors { return name; } + @ColorRes public int getColor(boolean nightMode) { return nightMode ? nightColor : dayColor; } diff --git a/OsmAnd/src/net/osmand/plus/profiles/RoutingProfileDataObject.java b/OsmAnd/src/net/osmand/plus/profiles/RoutingProfileDataObject.java index ab808de360..43c3b80953 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/RoutingProfileDataObject.java +++ b/OsmAnd/src/net/osmand/plus/profiles/RoutingProfileDataObject.java @@ -11,7 +11,7 @@ public class RoutingProfileDataObject extends ProfileDataObject { private String fileName; public RoutingProfileDataObject(String stringKey, String name, String descr, int iconRes, boolean isSelected, String fileName) { - super(name, descr, stringKey, iconRes, isSelected, null); + super(name, descr, stringKey, iconRes, isSelected, null, null); this.fileName = fileName; } diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectMultipleProfilesBottomSheet.java b/OsmAnd/src/net/osmand/plus/profiles/SelectMultipleProfilesBottomSheet.java index 7687f3386b..15593a9f8d 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectMultipleProfilesBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectMultipleProfilesBottomSheet.java @@ -77,11 +77,12 @@ public class SelectMultipleProfilesBottomSheet extends BasePreferenceBottomSheet View itemView = UiUtilities.getInflater(app, nightMode) .inflate(R.layout.bottom_sheet_item_with_descr_and_checkbox_56dp, null); - int profileColorId = profile.getIconColor(nightMode); + int profileColor = profile.getIconColor(nightMode); int activeColorId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; int disableColorId = nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; + int disableColor = ContextCompat.getColor(app, disableColorId); boolean enable = profile.isEnabled(); TextView tvTitle = itemView.findViewById(R.id.title); @@ -97,8 +98,8 @@ public class SelectMultipleProfilesBottomSheet extends BasePreferenceBottomSheet tvDescription.setTextColor(ContextCompat.getColor(app, disableColorId)); } - Drawable drawableIcon = app.getUIUtilities().getIcon( - profile.getIconRes(), enable ? profileColorId : disableColorId); + Drawable drawableIcon = app.getUIUtilities().getPaintedIcon( + profile.getIconRes(), enable ? profileColor : disableColor); ivIcon.setImageDrawable(drawableIcon); UiUtilities.setupCompoundButton(nightMode, ContextCompat.getColor(app, enable ? activeColorId : disableColorId), compoundButton); diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java index eb97a8ae85..5c78ecd04e 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java @@ -254,12 +254,13 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { boolean isSelected = setupSelected && Algorithms.objectEquals(profile.getStringKey(), selectedItemKey); int iconColor; if (dialogMode == DialogMode.NAVIGATION_PROFILE) { - iconColor = isSelected ? activeColorResId : iconDefaultColorResId; + int iconColorResId = isSelected ? activeColorResId : iconDefaultColorResId; + iconColor = ContextCompat.getColor(app, iconColorResId); } else { iconColor = profile.getIconColor(nightMode); } - Drawable drawableIcon = app.getUIUtilities().getIcon(profile.getIconRes(), iconColor); + Drawable drawableIcon = app.getUIUtilities().getPaintedIcon(profile.getIconRes(), iconColor); ivIcon.setImageDrawable(drawableIcon); compoundButton.setChecked(isSelected); UiUtilities.setupCompoundButton(compoundButton, nightMode, UiUtilities.CompoundButtonType.GLOBAL); diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileMenuAdapter.java b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileMenuAdapter.java index 25b2388875..475f3482c4 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileMenuAdapter.java @@ -6,19 +6,12 @@ import android.graphics.drawable.LayerDrawable; import android.view.View; import android.view.ViewGroup; -import androidx.annotation.ColorRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.view.ContextThemeWrapper; -import androidx.core.content.ContextCompat; -import androidx.recyclerview.widget.RecyclerView; - import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; -import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; +import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; @@ -26,6 +19,13 @@ import org.apache.commons.logging.Log; import java.util.ArrayList; import java.util.List; +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.view.ContextThemeWrapper; +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.RecyclerView; + public class SelectProfileMenuAdapter extends AbstractProfileMenuAdapter { private static final Log LOG = PlatformUtil.getLog(SelectProfileMenuAdapter.class); @@ -33,8 +33,8 @@ public class SelectProfileMenuAdapter extends AbstractProfileMenuAdapter items = new ArrayList<>(); private final OsmandApplication app; private ApplicationMode appMode; - @ColorRes - private int selectedIconColorRes; + @ColorInt + private int selectedIconColor; private boolean bottomButton; private String bottomButtonText; private static final String BUTTON_ITEM = "button_item"; @@ -53,9 +53,8 @@ public class SelectProfileMenuAdapter extends AbstractProfileMenuAdapter getItems() { @@ -101,7 +100,7 @@ public class SelectProfileMenuAdapter extends AbstractProfileMenuAdapter extends QuickAction { OsmandApplication app = (OsmandApplication) context.getApplicationContext(); - Drawable icon = app.getUIUtilities().getIcon( - getItemIconRes(app, item), getItemIconColorRes(app, item)); + Drawable icon = app.getUIUtilities().getPaintedIcon( + getItemIconRes(app, item), getItemIconColor(app, item)); holder.icon.setImageDrawable(icon); holder.title.setText(getItemName(context, item)); @@ -310,10 +312,11 @@ public abstract class SwitchableAction extends QuickAction { return R.drawable.ic_map; } - @ColorRes - protected int getItemIconColorRes(OsmandApplication app, T item) { + @ColorInt + protected int getItemIconColor(OsmandApplication app, T item) { boolean nightMode = !app.getSettings().isLightContent(); - return nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; + int colorRes = nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; + return ContextCompat.getColor(app, colorRes); } protected abstract diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/SwitchProfileAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/SwitchProfileAction.java index 3710f9832b..da31b61466 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/SwitchProfileAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/SwitchProfileAction.java @@ -5,6 +5,7 @@ import android.text.TextUtils; import android.view.View; import android.widget.Toast; +import androidx.annotation.ColorInt; import androidx.appcompat.widget.SwitchCompat; import com.google.gson.Gson; @@ -182,13 +183,14 @@ public class SwitchProfileAction extends SwitchableAction { } @Override - protected int getItemIconColorRes(OsmandApplication app, String item) { + @ColorInt + protected int getItemIconColor(OsmandApplication app, String item) { ApplicationMode appMode = getModeForKey(item); if (appMode != null) { boolean nightMode = !app.getSettings().isLightContent(); - return appMode.getIconColorInfo().getColor(nightMode); + return appMode.getProfileColor(nightMode); } - return super.getItemIconColorRes(app, item); + return super.getItemIconColor(app, item); } @Override diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/AvoidRoadsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/AvoidRoadsBottomSheetDialogFragment.java index 38f6053887..447e011c2d 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/AvoidRoadsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/AvoidRoadsBottomSheetDialogFragment.java @@ -11,6 +11,7 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -66,6 +67,8 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr private boolean hideImpassableRoads; @ColorRes private int compoundButtonColorId = INVALID_ID; + @ColorInt + private Integer compoundButtonColor = null; private ApplicationMode appMode; public void setHideImpassableRoads(boolean hideImpassableRoads) { @@ -237,6 +240,7 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr final BottomSheetItemWithCompoundButton[] item = new BottomSheetItemWithCompoundButton[1]; item[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() .setCompoundButtonColorId(compoundButtonColorId) + .setCompoundButtonColor(compoundButtonColor) .setChecked(selected) .setTitle(parameterName) .setLayoutId(R.layout.bottom_sheet_item_with_switch_no_icon) @@ -258,6 +262,10 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr this.compoundButtonColorId = compoundButtonColorId; } + public void setCompoundButtonColor(@ColorInt int compoundButtonColor) { + this.compoundButtonColor = compoundButtonColor; + } + @Override public void onResume() { super.onResume(); diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java index 8ba86dfe35..25c158a042 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/RouteOptionsBottomSheet.java @@ -11,6 +11,7 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; import androidx.appcompat.widget.SwitchCompat; import androidx.core.content.ContextCompat; @@ -84,8 +85,8 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { private RoutingHelper routingHelper; private RoutingOptionsHelper routingOptionsHelper; private ApplicationMode applicationMode; - @ColorRes - private int selectedModeColorId; + @ColorInt + private int selectedModeColor; private boolean currentMuteState; private boolean currentUseHeightState; private MapActivity mapActivity; @@ -149,7 +150,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { if (dialogMode == null) { dialogMode = DialogMode.DIRECTIONS; } - selectedModeColorId = applicationMode.getIconColorInfo().getColor(nightMode); + selectedModeColor = applicationMode.getProfileColor(nightMode); voiceMuteChangeListener = new StateChangedListener() { @Override public void stateChanged(Boolean change) { @@ -271,7 +272,6 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { private BaseBottomSheetItem createMuteSoundItem(final LocalRoutingParameter optionsItem) { boolean active = !routingHelper.getVoiceRouter().isMuteForMode(applicationMode); - int selectedModeColor = ContextCompat.getColor(app, selectedModeColorId); final View itemView = UiUtilities.getInflater(app, nightMode).inflate( R.layout.bottom_sheet_item_with_descr_switch_and_additional_button_56dp, null, false); final ImageView icon = itemView.findViewById(R.id.icon); @@ -310,7 +310,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { Drawable drawable = app.getUIUtilities().getIcon(R.drawable.ic_action_settings, nightMode ? R.color.route_info_control_icon_color_dark : R.color.route_info_control_icon_color_light); if (Build.VERSION.SDK_INT >= 21) { - Drawable activeDrawable = app.getUIUtilities().getIcon(R.drawable.ic_action_settings, selectedModeColorId); + Drawable activeDrawable = app.getUIUtilities().getPaintedIcon(R.drawable.ic_action_settings, selectedModeColor); drawable = AndroidUtils.createPressedStateListDrawable(drawable, activeDrawable); } voicePromptsBtnImage.setImageDrawable(drawable); @@ -358,7 +358,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { item[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() .setChecked(!active) - .setCompoundButtonColorId(selectedModeColorId) + .setCompoundButtonColor(selectedModeColor) .setDescription(getElevationDescription(parameter)) .setIcon(getContentIcon(active ? parameter.getActiveIconId() : parameter.getDisabledIconId())) .setTitle(getString(R.string.routing_attr_height_obstacles_name)) @@ -387,7 +387,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { private BaseBottomSheetItem createTimeConditionalRoutingItem(final LocalRoutingParameter optionsItem) { final BottomSheetItemWithCompoundButton[] timeConditionalRoutingItem = new BottomSheetItemWithCompoundButton[1]; timeConditionalRoutingItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() - .setCompoundButtonColorId(selectedModeColorId) + .setCompoundButtonColor(selectedModeColor) .setChecked(settings.ENABLE_TIME_CONDITIONAL_ROUTING.getModeValue(applicationMode)) .setIcon(getContentIcon((optionsItem.getActiveIconId()))) .setTitle(getString(R.string.temporary_conditional_routing)) @@ -433,7 +433,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { private BaseBottomSheetItem createRouteSimulationItem(final LocalRoutingParameter optionsItem) { final BottomSheetItemWithCompoundButton[] simulateNavigationItem = new BottomSheetItemWithCompoundButton[1]; simulateNavigationItem[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() - .setCompoundButtonColorId(selectedModeColorId) + .setCompoundButtonColor(selectedModeColor) .setChecked(settings.simulateNavigation) .setIcon(getContentIcon(R.drawable.ic_action_start_navigation)) .setTitle(getString(R.string.simulate_navigation)) @@ -470,7 +470,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { routingOptionsHelper.addNewRouteMenuParameter(applicationMode, optionsItem); AvoidRoadsBottomSheetDialogFragment avoidRoadsFragment = new AvoidRoadsBottomSheetDialogFragment(); avoidRoadsFragment.setTargetFragment(RouteOptionsBottomSheet.this, AvoidRoadsBottomSheetDialogFragment.REQUEST_CODE); - avoidRoadsFragment.setCompoundButtonColorId(selectedModeColorId); + avoidRoadsFragment.setCompoundButtonColor(selectedModeColor); avoidRoadsFragment.setApplicationMode(applicationMode); avoidRoadsFragment.show(mapActivity.getSupportFragmentManager(), AvoidRoadsBottomSheetDialogFragment.TAG); updateMenu(); @@ -492,7 +492,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { AvoidRoadsBottomSheetDialogFragment avoidRoadsFragment = new AvoidRoadsBottomSheetDialogFragment(); avoidRoadsFragment.setHideImpassableRoads(true); avoidRoadsFragment.setTargetFragment(RouteOptionsBottomSheet.this, AvoidRoadsBottomSheetDialogFragment.REQUEST_CODE); - avoidRoadsFragment.setCompoundButtonColorId(selectedModeColorId); + avoidRoadsFragment.setCompoundButtonColor(selectedModeColor); avoidRoadsFragment.show(mapActivity.getSupportFragmentManager(), AvoidRoadsBottomSheetDialogFragment.TAG); updateMenu(); } @@ -565,7 +565,7 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment { if (parameter != null) { final BottomSheetItemWithCompoundButton[] item = new BottomSheetItemWithCompoundButton[1]; BottomSheetItemWithCompoundButton.Builder builder = new BottomSheetItemWithCompoundButton.Builder(); - builder.setCompoundButtonColorId(selectedModeColorId); + builder.setCompoundButtonColor(selectedModeColor); int iconId = -1; if (parameter.routingParameter != null || parameter instanceof RoutingOptionsHelper.OtherLocalRoutingParameter) { builder.setTitle(parameter.getText(mapActivity)); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java index 0348bf3eb7..8cbcd4824b 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java @@ -467,12 +467,11 @@ public class ApplicationMode { @ColorInt public int getProfileColor(boolean nightMode) { - int index = getCustomIconColorIndex(); - List customColors = getCustomIconColors(); - if (index < 0 || index >= customColors.size()) { - return ContextCompat.getColor(app, getIconColorInfo().getColor(nightMode)); + Integer customProfileColor = getCustomIconColor(); + if (customProfileColor != null) { + return customProfileColor; } - return Algorithms.parseColor(customColors.get(index)); + return ContextCompat.getColor(app, getIconColorInfo().getColor(nightMode)); } public void setLocationIcon(LocationIcon locationIcon) { @@ -499,12 +498,14 @@ public class ApplicationMode { app.getSettings().CUSTOM_ICON_COLORS.setModeValues(this, customColors); } - public Integer getCustomIconColorIndex() { - return app.getSettings().CUSTOM_ICON_COLOR_INDEX.getModeValue(this); + public Integer getCustomIconColor() { + String customColor = app.getSettings().CUSTOM_ICON_COLOR.getModeValue(this); + return customColor == null ? null : Integer.valueOf(customColor); } - public void setCustomIconColorIndex(int colorIndex) { - app.getSettings().CUSTOM_ICON_COLOR_INDEX.setModeValue(this, colorIndex); + public void setCustomIconColor(Integer customIconColor) { + String valueToSave = customIconColor == null ? null : String.valueOf(customIconColor); + app.getSettings().CUSTOM_ICON_COLOR.setModeValue(this, valueToSave); } public int getOrder() { @@ -605,7 +606,7 @@ public class ApplicationMode { mode.setRouteService(builder.routeService); mode.setIconColor(builder.iconColor); mode.setCustomIconColors(builder.customIconColors); - mode.setCustomIconColorIndex(builder.customIconColorIndex); + mode.setCustomIconColor(builder.customIconColor); mode.setLocationIcon(builder.locationIcon); mode.setNavigationIcon(builder.navigationIcon); mode.setOrder(builder.order); @@ -628,6 +629,7 @@ public class ApplicationMode { builder.setUserProfileName(modeBean.userProfileName); builder.setIconResName(modeBean.iconName); builder.setIconColor(modeBean.iconColor); + builder.setCustomIconColor(modeBean.customIconColor); builder.setRoutingProfile(modeBean.routingProfile); builder.setRouteService(modeBean.routeService); builder.setLocationIcon(modeBean.locIcon); @@ -647,6 +649,7 @@ public class ApplicationMode { mb.stringKey = stringKey; mb.userProfileName = getUserProfileName(); mb.iconColor = getIconColorInfo(); + mb.customIconColor = getCustomIconColor(); mb.iconName = getIconName(); mb.parent = parentAppMode != null ? parentAppMode.getStringKey() : null; mb.routeService = getRouteService(); @@ -724,7 +727,7 @@ public class ApplicationMode { private String iconResName; private ProfileIconColors iconColor; private List customIconColors; - private int customIconColorIndex; + private Integer customIconColor; private LocationIcon locationIcon; private NavigationIcon navigationIcon; private int order = -1; @@ -749,7 +752,7 @@ public class ApplicationMode { applicationMode.setRoutingProfile(routingProfile); applicationMode.setIconResName(iconResName); applicationMode.setCustomIconColors(customIconColors); - applicationMode.setCustomIconColorIndex(customIconColorIndex); + applicationMode.setCustomIconColor(customIconColor); applicationMode.setIconColor(iconColor); applicationMode.setLocationIcon(locationIcon); applicationMode.setNavigationIcon(navigationIcon); @@ -803,8 +806,8 @@ public class ApplicationMode { return this; } - public ApplicationModeBuilder setCustomIconColorIndex(int index) { - this.customIconColorIndex = index; + public ApplicationModeBuilder setCustomIconColor(Integer customIconColor) { + this.customIconColor = customIconColor; return this; } @@ -836,6 +839,8 @@ public class ApplicationMode { @Expose public ProfileIconColors iconColor = ProfileIconColors.DEFAULT; @Expose + public Integer customIconColor = null; + @Expose public String routingProfile = null; @Expose public RouteService routeService = RouteService.OSMAND; diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 6683529fff..c516e76ae0 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -986,7 +986,7 @@ public class OsmandSettings { public final ListStringPreference CUSTOM_ICON_COLORS = (ListStringPreference) new ListStringPreference(this, "custom_icon_colors", null, ",").makeProfile().cache(); - public final CommonPreference CUSTOM_ICON_COLOR_INDEX = new IntPreference(this, "custom_icon_color_index", -1).makeProfile().cache(); + public final CommonPreference CUSTOM_ICON_COLOR = new StringPreference(this, "custom_icon_color", null).makeProfile().cache(); public final CommonPreference USER_PROFILE_NAME = new StringPreference(this, "user_profile_name", "").makeProfile().cache(); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java index 88405fd010..203c0a2323 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/ProfileSettingsItem.java @@ -301,6 +301,7 @@ public class ProfileSettingsItem extends OsmandSettingsItem { OsmandSettings settings = app.getSettings(); return new String[] { settings.ICON_COLOR.getId(), + settings.CUSTOM_ICON_COLOR.getId(), settings.ICON_RES_NAME.getId(), settings.PARENT_APP_MODE.getId(), settings.ROUTING_PROFILE.getId(), diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java index 8b8b241b1b..f5189617dd 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java @@ -103,7 +103,7 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet { }) .create(); if (isProfileDependent()) { - preferenceBtn[0].setCompoundButtonColorId(getAppMode().getIconColorInfo().getColor(nightMode)); + preferenceBtn[0].setCompoundButtonColor(getAppMode().getProfileColor(nightMode)); } items.add(preferenceBtn[0]); @@ -133,8 +133,7 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet { Context themedCtx = UiUtilities.getThemedContext(app, nightMode); View buttonView = customView.findViewById(R.id.button_container); - int colorRes = mode.getIconColorInfo().getColor(nightMode); - int color = checked ? ContextCompat.getColor(themedCtx, colorRes) : AndroidUtils.getColorFromAttr(themedCtx, R.attr.divider_color_basic); + int color = checked ? mode.getProfileColor(nightMode) : AndroidUtils.getColorFromAttr(themedCtx, R.attr.divider_color_basic); int bgColor = UiUtilities.getColorWithAlpha(color, checked ? 0.1f : 0.5f); int selectedColor = UiUtilities.getColorWithAlpha(color, checked ? 0.3f : 0.5f); diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ElevationDateBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ElevationDateBottomSheet.java index 427bda7521..91d92ad241 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ElevationDateBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ElevationDateBottomSheet.java @@ -5,6 +5,7 @@ import android.os.Bundle; import android.view.View; import android.widget.TextView; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; @@ -65,6 +66,7 @@ public class ElevationDateBottomSheet extends MenuBottomSheetDialogFragment { private int checkedColor; private int uncheckedColor; private int disabledColor; + @ColorInt private int appModeColor; @Override @@ -101,7 +103,7 @@ public class ElevationDateBottomSheet extends MenuBottomSheetDialogFragment { on = getString(R.string.shared_string_enabled); off = getString(R.string.shared_string_disabled); - appModeColor = appMode.getIconColorInfo().getColor(nightMode); + appModeColor = appMode.getProfileColor(nightMode); activeColor = AndroidUtils.resolveAttribute(themedCtx, R.attr.active_color_basic); disabledColor = AndroidUtils.resolveAttribute(themedCtx, android.R.attr.textColorSecondary); checkedColor = (nightMode ? app.getResources().getColor(R.color.text_color_primary_dark) : app.getResources().getColor(R.color.text_color_primary_light)); @@ -123,7 +125,7 @@ public class ElevationDateBottomSheet extends MenuBottomSheetDialogFragment { private void createUseHeightButton(Context context) { boolean checked = useHeightPref.getModeValue(appMode); useHeightButton = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() - .setCompoundButtonColorId(appModeColor) + .setCompoundButtonColor(appModeColor) .setChecked(checked) .setTitle(checked ? on : off) .setTitleColorId(checked ? activeColor : disabledColor) diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/MultiSelectPreferencesBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/MultiSelectPreferencesBottomSheet.java index 71881876b3..90b88a264d 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/MultiSelectPreferencesBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/MultiSelectPreferencesBottomSheet.java @@ -89,7 +89,7 @@ public class MultiSelectPreferencesBottomSheet extends BasePreferenceBottomSheet .setTag(prefId) .create(); if (isProfileDependent()) { - item[0].setCompoundButtonColorId(getAppMode().getIconColorInfo().getColor(nightMode)); + item[0].setCompoundButtonColor(getAppMode().getProfileColor(nightMode)); } items.add(item[0]); } diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/RecalculateRouteInDeviationBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/RecalculateRouteInDeviationBottomSheet.java index 743e12ee38..7bde0e8034 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/RecalculateRouteInDeviationBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/RecalculateRouteInDeviationBottomSheet.java @@ -107,7 +107,7 @@ public class RecalculateRouteInDeviationBottomSheet extends BooleanPreferenceBot final BottomSheetItemWithCompoundButton[] preferenceBtn = new BottomSheetItemWithCompoundButton[1]; preferenceBtn[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() .setChecked(enabled) - .setCompoundButtonColorId(appModeColorId) + .setCompoundButtonColor(appModeColor) .setTitle(enabled ? on : off) .setTitleColorId(enabled ? activeColor : disabledColor) .setCustomView(getCustomButtonView(app, getAppMode(), enabled, nightMode)) diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ResetProfilePrefsBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ResetProfilePrefsBottomSheet.java index dd87247225..69e225b4c0 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ResetProfilePrefsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/ResetProfilePrefsBottomSheet.java @@ -45,10 +45,10 @@ public class ResetProfilePrefsBottomSheet extends BasePreferenceBottomSheet { BaseBottomSheetItem profileItem = new BottomSheetItemWithCompoundButton.Builder() .setChecked(true) - .setCompoundButtonColorId(profileColor) - .setButtonTintList(ColorStateList.valueOf(getResolvedColor(profileColor))) + .setCompoundButtonColor(colorNoAlpha) + .setButtonTintList(ColorStateList.valueOf(colorNoAlpha)) .setDescription(ProfileDataUtils.getAppModeDescription(ctx, mode)) - .setIcon(getIcon(mode.getIconRes(), profileColor)) + .setIcon(getPaintedIcon(mode.getIconRes(), colorNoAlpha)) .setTitle(mode.toHumanString()) .setBackground(new LayerDrawable(layers)) .setLayoutId(R.layout.preference_profile_item_with_radio_btn) diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/SingleSelectPreferenceBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/SingleSelectPreferenceBottomSheet.java index dc673207b2..2a214cdbe3 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/SingleSelectPreferenceBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/SingleSelectPreferenceBottomSheet.java @@ -6,6 +6,7 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; @@ -69,8 +70,11 @@ public class SingleSelectPreferenceBottomSheet extends BasePreferenceBottomSheet final BaseBottomSheetItem[] preferenceItem = new BottomSheetItemWithCompoundButton[1]; preferenceItem[0] = new BottomSheetItemWithCompoundButton.Builder() .setChecked(i == selectedEntryIndex) - .setButtonTintList(AndroidUtils.createCheckedColorStateList(ctx, R.color.icon_color_default_light, - isProfileDependent() ? getAppMode().getIconColorInfo().getColor(nightMode) : getActiveColorId())) + .setButtonTintList(AndroidUtils.createCheckedColorIntStateList( + ContextCompat.getColor(ctx,R.color.icon_color_default_light), + isProfileDependent() ? + getAppMode().getProfileColor(nightMode) : + ContextCompat.getColor(ctx, getActiveColorId()))) .setTitle(entries[i]) .setTag(i) .setLayoutId(R.layout.bottom_sheet_item_with_radio_btn_left) diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java index 63dab74fd4..a583940068 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java @@ -680,12 +680,9 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl @ColorInt protected int getActiveProfileColor() { - return ContextCompat.getColor(app, getActiveProfileColorRes()); - } - - @ColorRes - protected int getActiveProfileColorRes() { - return isProfileDependent() ? getSelectedAppMode().getIconColorInfo().getColor(isNightMode()) : R.color.icon_color_active_light; + return isProfileDependent() ? + getSelectedAppMode().getProfileColor(isNightMode()) : + ContextCompat.getColor(app, R.color.icon_color_active_light); } @ColorRes @@ -801,7 +798,7 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl protected Drawable getActiveIcon(@DrawableRes int id) { UiUtilities cache = getIconsCache(); - return cache != null ? cache.getIcon(id, getActiveProfileColorRes()) : null; + return cache != null ? cache.getPaintedIcon(id, getActiveProfileColor()) : null; } protected Drawable getIcon(@DrawableRes int id, @ColorRes int colorId) { @@ -829,7 +826,8 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl Drawable icon = AndroidUtils.createEnabledStateListDrawable(disabled, enabled); if (Build.VERSION.SDK_INT < 21) { - ColorStateList colorStateList = AndroidUtils.createEnabledColorStateList(app, R.color.icon_color_default_light, getActiveProfileColorRes()); + int defaultColor = ContextCompat.getColor(app, R.color.icon_color_default_light); + ColorStateList colorStateList = AndroidUtils.createEnabledColorIntStateList(defaultColor, getActiveProfileColor()); icon = DrawableCompat.wrap(icon); DrawableCompat.setTintList(icon, colorStateList); return icon; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java b/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java index 078197da4f..952ecea396 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java @@ -6,7 +6,9 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; +import alice.tuprolog.Int; import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; import net.osmand.AndroidUtils; @@ -121,7 +123,10 @@ public class DuplicatesSettingsAdapter extends RecyclerView.Adapter Date: Tue, 23 Feb 2021 22:20:41 +0500 Subject: [PATCH 11/29] Cosmetic changes --- .../settings/backend/ApplicationMode.java | 8 +-- .../fragments/DuplicatesSettingsAdapter.java | 11 ++-- .../fragments/ExportItemsBottomSheet.java | 16 ++--- .../fragments/ProfileAppearanceFragment.java | 65 +++++++++---------- 4 files changed, 49 insertions(+), 51 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java index 8cbcd4824b..3493a0768a 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java @@ -1,9 +1,5 @@ package net.osmand.plus.settings.backend; -import androidx.annotation.ColorInt; -import androidx.annotation.DrawableRes; -import androidx.core.content.ContextCompat; - import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.annotations.Expose; @@ -28,6 +24,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import androidx.annotation.ColorInt; +import androidx.annotation.DrawableRes; +import androidx.core.content.ContextCompat; + import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_ALTITUDE; import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_BATTERY; import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_BEARING; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java b/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java index 952ecea396..4b8e40f1a0 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/DuplicatesSettingsAdapter.java @@ -6,11 +6,6 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import alice.tuprolog.Int; -import androidx.annotation.NonNull; -import androidx.core.content.ContextCompat; -import androidx.recyclerview.widget.RecyclerView; - import net.osmand.AndroidUtils; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; @@ -35,12 +30,16 @@ import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean; import net.osmand.util.Algorithms; -import org.apache.commons.logging.Log; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; import java.io.File; import java.util.List; +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.RecyclerView; + import static net.osmand.plus.settings.backend.backup.FileSettingsItem.FileSubtype; public class DuplicatesSettingsAdapter extends RecyclerView.Adapter { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportItemsBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportItemsBottomSheet.java index 6fcd201de6..59c7327975 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportItemsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportItemsBottomSheet.java @@ -6,13 +6,6 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; -import androidx.core.widget.CompoundButtonCompat; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; - import net.osmand.AndroidUtils; import net.osmand.GPXUtilities.GPXTrackAnalysis; import net.osmand.IndexConstants; @@ -61,13 +54,20 @@ import net.osmand.plus.settings.fragments.ExportSettingsAdapter.OnItemSelectedLi import net.osmand.util.Algorithms; import net.osmand.view.ThreeStateCheckbox; -import org.apache.commons.logging.Log; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; import java.io.File; import java.util.ArrayList; import java.util.List; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import androidx.core.widget.CompoundButtonCompat; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; + import static net.osmand.view.ThreeStateCheckbox.State.CHECKED; import static net.osmand.view.ThreeStateCheckbox.State.MISC; import static net.osmand.view.ThreeStateCheckbox.State.UNCHECKED; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java index 624d90608c..49fe22be21 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java @@ -23,6 +23,38 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; +import net.osmand.AndroidUtils; +import net.osmand.IndexConstants; +import net.osmand.PlatformUtil; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.UiUtilities.DialogButtonType; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.profiles.LocationIcon; +import net.osmand.plus.profiles.NavigationIcon; +import net.osmand.plus.profiles.ProfileIconColors; +import net.osmand.plus.profiles.ProfileIcons; +import net.osmand.plus.profiles.SelectProfileBottomSheet; +import net.osmand.plus.profiles.SelectProfileBottomSheet.DialogMode; +import net.osmand.plus.profiles.SelectProfileBottomSheet.OnSelectProfileCallback; +import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.plus.routing.RouteProvider; +import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.plus.settings.backend.backup.ProfileSettingsItem; +import net.osmand.plus.settings.backend.backup.SettingsHelper; +import net.osmand.plus.track.ColorsCard; +import net.osmand.plus.track.CustomColorBottomSheet; +import net.osmand.plus.widgets.FlowLayout; +import net.osmand.plus.widgets.OsmandTextFieldBoxes; +import net.osmand.util.Algorithms; + +import org.apache.commons.logging.Log; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + import androidx.activity.OnBackPressedCallback; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; @@ -38,38 +70,6 @@ import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import androidx.recyclerview.widget.RecyclerView; -import net.osmand.AndroidUtils; -import net.osmand.IndexConstants; -import net.osmand.PlatformUtil; -import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.routepreparationmenu.cards.BaseCard; -import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.R; -import net.osmand.plus.settings.backend.backup.ProfileSettingsItem; -import net.osmand.plus.settings.backend.backup.SettingsHelper; -import net.osmand.plus.UiUtilities; -import net.osmand.plus.UiUtilities.DialogButtonType; -import net.osmand.plus.profiles.LocationIcon; -import net.osmand.plus.profiles.NavigationIcon; -import net.osmand.plus.profiles.ProfileIconColors; -import net.osmand.plus.profiles.ProfileIcons; -import net.osmand.plus.profiles.SelectProfileBottomSheet; -import net.osmand.plus.profiles.SelectProfileBottomSheet.DialogMode; -import net.osmand.plus.profiles.SelectProfileBottomSheet.OnSelectProfileCallback; -import net.osmand.plus.routing.RouteProvider; -import net.osmand.plus.track.ColorsCard; -import net.osmand.plus.track.CustomColorBottomSheet; -import net.osmand.plus.widgets.FlowLayout; -import net.osmand.plus.widgets.OsmandTextFieldBoxes; -import net.osmand.util.Algorithms; - -import org.apache.commons.logging.Log; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SETTINGS_ID; import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILES_LIST_UPDATED_ARG; import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILE_KEY_ARG; @@ -940,7 +940,6 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O return; } - if (cardOfColors.isBaseColor(color)) { changedProfile.customColor = null; changedProfile.color = changedProfile.getProfileColorByColorValue(color); From 0f81841c7980c3b91e1bd42af03a3b65b6174317 Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 24 Feb 2021 15:02:39 +0200 Subject: [PATCH 12/29] test adding altitude and timestamp to new favorite --- .../net/osmand/binary/RouteDataObject.java | 210 ++++++++++-------- .../src/net/osmand/data/FavouritePoint.java | 82 ++++++- .../osmand/plus/importfiles/ImportHelper.java | 18 +- .../plus/mapcontextmenu/MapContextMenu.java | 10 +- .../editors/FavoritePointEditor.java | 35 ++- .../editors/FavoritePointEditorFragment.java | 10 +- .../FavoritePointEditorFragmentNew.java | 12 +- .../quickaction/actions/FavoriteAction.java | 2 +- 8 files changed, 248 insertions(+), 131 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java index bc81ca667e..f444a56b04 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java @@ -4,6 +4,7 @@ import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule; +import net.osmand.data.LatLon; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import net.osmand.util.TransliterationHelper; @@ -37,7 +38,9 @@ public class RouteDataObject { public int[] nameIds; // mixed array [0, height, cumulative_distance height, cumulative_distance, height, ...] - length is length(points)*2 public float[] heightDistanceArray = null; + public float heightByCurrentLocation; private static final Log LOG = PlatformUtil.getLog(RouteDataObject.class); + public RouteDataObject(RouteRegion region) { this.region = region; } @@ -124,7 +127,7 @@ public class RouteDataObject { equals = this.pointTypes[i] == thatObj.pointTypes[i]; } else if (pointTypes[i].length != thatObj.pointTypes[i].length) { equals = false; - } else { + } else { for (int j = 0; j < this.pointTypes[i].length && equals; j++) { String thisTag = region.routeEncodingRules.get(pointTypes[i][j]).getTag(); String thisValue = region.routeEncodingRules.get(pointTypes[i][j]).getValue(); @@ -147,7 +150,7 @@ public class RouteDataObject { equals = this.pointNameTypes[i] == thatObj.pointNameTypes[i]; } else if (pointNameTypes[i].length != thatObj.pointNameTypes[i].length) { equals = false; - } else { + } else { for (int j = 0; j < this.pointNameTypes[i].length && equals; j++) { String thisTag = region.routeEncodingRules.get(pointNameTypes[i][j]).getTag(); String thisValue = pointNames[i][j]; @@ -165,53 +168,67 @@ public class RouteDataObject { } public float[] calculateHeightArray() { - if(heightDistanceArray != null) { + return calculateHeightArray(null); + } + + public float[] calculateHeightArray(LatLon currentLocation) { + if (heightDistanceArray != null) { return heightDistanceArray; } int startHeight = Algorithms.parseIntSilently(getValue("osmand_ele_start"), HEIGHT_UNDEFINED); int endHeight = Algorithms.parseIntSilently(getValue("osmand_ele_end"), startHeight); - if(startHeight == HEIGHT_UNDEFINED) { + if (startHeight == HEIGHT_UNDEFINED) { heightDistanceArray = new float[0]; return heightDistanceArray; } - heightDistanceArray = new float[2*getPointsLength()]; + heightDistanceArray = new float[2 * getPointsLength()]; double plon = 0; double plat = 0; - float prevHeight = startHeight; - for(int k = 0; k < getPointsLength(); k++) { + float prevHeight = heightByCurrentLocation = startHeight; + double prevDistance = 0; + for (int k = 0; k < getPointsLength(); k++) { double lon = MapUtils.get31LongitudeX(getPoint31XTile(k)); double lat = MapUtils.get31LatitudeY(getPoint31YTile(k)); - if(k > 0) { + if (k > 0) { double dd = MapUtils.getDistance(plat, plon, lat, lon); float height = HEIGHT_UNDEFINED; - if(k == getPointsLength() - 1) { + if (k == getPointsLength() - 1) { height = endHeight; } else { String asc = getValue(k, "osmand_ele_asc"); - if(asc != null && asc.length() > 0) { + if (asc != null && asc.length() > 0) { height = (prevHeight + Float.parseFloat(asc)); } else { String desc = getValue(k, "osmand_ele_desc"); - if(desc != null && desc.length() > 0) { + if (desc != null && desc.length() > 0) { height = (prevHeight - Float.parseFloat(desc)); } } } - heightDistanceArray[2*k] = (float) dd; - heightDistanceArray[2*k+1] = height; - if(height != HEIGHT_UNDEFINED) { + heightDistanceArray[2 * k] = (float) dd; + heightDistanceArray[2 * k + 1] = height; + + if (currentLocation != null) { + double distance = MapUtils.getDistance(currentLocation, lat, lon); + if (height != HEIGHT_UNDEFINED && distance < prevDistance) { + prevDistance = distance; + heightByCurrentLocation = height; + } + } + + if (height != HEIGHT_UNDEFINED) { // interpolate undefined double totalDistance = dd; int startUndefined = k; - while(startUndefined - 1 >= 0 && heightDistanceArray[2*(startUndefined - 1)+1] == HEIGHT_UNDEFINED) { - startUndefined --; - totalDistance += heightDistanceArray[2*(startUndefined)]; + while (startUndefined - 1 >= 0 && heightDistanceArray[2 * (startUndefined - 1) + 1] == HEIGHT_UNDEFINED) { + startUndefined--; + totalDistance += heightDistanceArray[2 * (startUndefined)]; } - if(totalDistance > 0) { + if (totalDistance > 0) { double angle = (height - prevHeight) / totalDistance; - for(int j = startUndefined; j < k; j++) { - heightDistanceArray[2*j+1] = (float) ((heightDistanceArray[2*j] * angle) + heightDistanceArray[2*j-1]); + for (int j = startUndefined; j < k; j++) { + heightDistanceArray[2 * j + 1] = (float) ((heightDistanceArray[2 * j] * angle) + heightDistanceArray[2 * j - 1]); } } prevHeight = height; @@ -223,6 +240,9 @@ public class RouteDataObject { } plat = lat; plon = lon; + if (currentLocation != null) { + prevDistance = MapUtils.getDistance(currentLocation, plat, plon); + } } return heightDistanceArray; } @@ -231,34 +251,34 @@ public class RouteDataObject { return id; } - public String getName(){ - if(names != null ) { + public String getName() { + if (names != null) { return names.get(region.nameTypeRule); } return null; } - public String getName(String lang){ + public String getName(String lang) { return getName(lang, false); } - public String getName(String lang, boolean transliterate){ - if(names != null ) { - if(Algorithms.isEmpty(lang)) { + public String getName(String lang, boolean transliterate) { + if (names != null) { + if (Algorithms.isEmpty(lang)) { return names.get(region.nameTypeRule); } int[] kt = names.keys(); - for(int i = 0 ; i < kt.length; i++) { + for (int i = 0; i < kt.length; i++) { int k = kt[i]; - if(region.routeEncodingRules.size() > k) { - if(("name:"+lang).equals(region.routeEncodingRules.get(k).getTag())) { + if (region.routeEncodingRules.size() > k) { + if (("name:" + lang).equals(region.routeEncodingRules.get(k).getTag())) { return names.get(k); } } } String nmDef = names.get(region.nameTypeRule); - if(transliterate && nmDef != null && nmDef.length() > 0) { + if (transliterate && nmDef != null && nmDef.length() > 0) { return TransliterationHelper.transliterate(nmDef); } return nmDef; @@ -279,20 +299,20 @@ public class RouteDataObject { // return getDestinationRef(direction); //} if (names != null) { - if(Algorithms.isEmpty(lang)) { + if (Algorithms.isEmpty(lang)) { return names.get(region.refTypeRule); } int[] kt = names.keys(); - for(int i = 0 ; i < kt.length; i++) { + for (int i = 0; i < kt.length; i++) { int k = kt[i]; - if(region.routeEncodingRules.size() > k) { - if(("ref:"+lang).equals(region.routeEncodingRules.get(k).getTag())) { + if (region.routeEncodingRules.size() > k) { + if (("ref:" + lang).equals(region.routeEncodingRules.get(k).getTag())) { return names.get(k); } } } String refDefault = names.get(region.refTypeRule); - if(transliterate && refDefault != null && refDefault.length() > 0) { + if (transliterate && refDefault != null && refDefault.length() > 0) { return TransliterationHelper.transliterate(refDefault); } return refDefault; @@ -307,13 +327,13 @@ public class RouteDataObject { String refTagDefault = "destination:ref"; String refDefault = null; - for(int i = 0 ; i < kt.length; i++) { + for (int i = 0; i < kt.length; i++) { int k = kt[i]; - if(region.routeEncodingRules.size() > k) { - if(refTag.equals(region.routeEncodingRules.get(k).getTag())) { + if (region.routeEncodingRules.size() > k) { + if (refTag.equals(region.routeEncodingRules.get(k).getTag())) { return names.get(k); } - if(refTagDefault.equals(region.routeEncodingRules.get(k).getTag())) { + if (refTagDefault.equals(region.routeEncodingRules.get(k).getTag())) { refDefault = names.get(k); } } @@ -326,12 +346,12 @@ public class RouteDataObject { return null; } - public String getDestinationName(String lang, boolean transliterate, boolean direction){ + public String getDestinationName(String lang, boolean transliterate, boolean direction) { //Issue #3289: Treat destination:ref like a destination, not like a ref String destRef = ((getDestinationRef(direction) == null) || getDestinationRef(direction).equals(getRef(lang, transliterate, direction))) ? "" : getDestinationRef(direction); String destRef1 = Algorithms.isEmpty(destRef) ? "" : destRef + ", "; - if(names != null) { + if (names != null) { int[] kt = names.keys(); // Issue #3181: Parse destination keys in this order: @@ -341,35 +361,35 @@ public class RouteDataObject { // destination String destinationTagLangFB = "destination:lang:XX"; - if(!Algorithms.isEmpty(lang)) { + if (!Algorithms.isEmpty(lang)) { destinationTagLangFB = (direction == true) ? "destination:lang:" + lang + ":forward" : "destination:lang:" + lang + ":backward"; } String destinationTagFB = (direction == true) ? "destination:forward" : "destination:backward"; String destinationTagLang = "destination:lang:XX"; - if(!Algorithms.isEmpty(lang)) { + if (!Algorithms.isEmpty(lang)) { destinationTagLang = "destination:lang:" + lang; } String destinationTagDefault = "destination"; String destinationDefault = null; - for(int i = 0 ; i < kt.length; i++) { + for (int i = 0; i < kt.length; i++) { int k = kt[i]; - if(region.routeEncodingRules.size() > k) { - if(!Algorithms.isEmpty(lang) && destinationTagLangFB.equals(region.routeEncodingRules.get(k).getTag())) { + if (region.routeEncodingRules.size() > k) { + if (!Algorithms.isEmpty(lang) && destinationTagLangFB.equals(region.routeEncodingRules.get(k).getTag())) { return destRef1 + ((transliterate) ? TransliterationHelper.transliterate(names.get(k)) : names.get(k)); } - if(destinationTagFB.equals(region.routeEncodingRules.get(k).getTag())) { + if (destinationTagFB.equals(region.routeEncodingRules.get(k).getTag())) { return destRef1 + ((transliterate) ? TransliterationHelper.transliterate(names.get(k)) : names.get(k)); } - if(!Algorithms.isEmpty(lang) && destinationTagLang.equals(region.routeEncodingRules.get(k).getTag())) { + if (!Algorithms.isEmpty(lang) && destinationTagLang.equals(region.routeEncodingRules.get(k).getTag())) { return destRef1 + ((transliterate) ? TransliterationHelper.transliterate(names.get(k)) : names.get(k)); } - if(destinationTagDefault.equals(region.routeEncodingRules.get(k).getTag())) { + if (destinationTagDefault.equals(region.routeEncodingRules.get(k).getTag())) { destinationDefault = names.get(k); } } } - if(destinationDefault != null) { + if (destinationDefault != null) { return destRef1 + ((transliterate) ? TransliterationHelper.transliterate(destinationDefault) : destinationDefault); } } @@ -400,14 +420,14 @@ public class RouteDataObject { RestrictionInfo ri = new RestrictionInfo(); ri.toWay = getRestrictionId(k); ri.type = getRestrictionType(k); - if(restrictionsVia != null && k < restrictionsVia.length) { + if (restrictionsVia != null && k < restrictionsVia.length) { ri.viaWay = restrictionsVia[k]; } return ri; } public long getRestrictionVia(int i) { - if(restrictionsVia != null && restrictionsVia.length > i) { + if (restrictionsVia != null && restrictionsVia.length > i) { return restrictionsVia[i]; } return 0; @@ -441,7 +461,7 @@ public class RouteDataObject { } if (insNames) { pointNames = new String[opointNames.length + 1][]; - pointNameTypes = new int[opointNameTypes.length +1][]; + pointNameTypes = new int[opointNameTypes.length + 1][]; } int i = 0; for (; i < pos; i++) { @@ -590,7 +610,7 @@ public class RouteDataObject { } public static float parseSpeed(String v, float def) { - if(v.equals("none")) { + if (v.equals("none")) { return RouteDataObject.NONE_MAX_SPEED; } else { int i = Algorithms.findFirstNumberEndIndex(v); @@ -614,20 +634,20 @@ public class RouteDataObject { f += Float.parseFloat(v.substring(0, i)); String pref = v.substring(i, v.length()).trim(); float add = 0; - for(int ik = 0; ik < pref.length(); ik++) { - if(Algorithms.isDigit(pref.charAt(ik)) || pref.charAt(ik) == '.' || pref.charAt(ik) == '-') { + for (int ik = 0; ik < pref.length(); ik++) { + if (Algorithms.isDigit(pref.charAt(ik)) || pref.charAt(ik) == '.' || pref.charAt(ik) == '-') { int first = Algorithms.findFirstNumberEndIndex(pref.substring(ik)); - if(first != -1) { + if (first != -1) { add = parseLength(pref.substring(ik), 0); pref = pref.substring(0, ik); } break; } } - if(pref.contains("km")) { + if (pref.contains("km")) { f *= 1000; } - if(pref.contains("\"") || pref.contains("in")) { + if (pref.contains("\"") || pref.contains("in")) { f *= 0.0254; } else if (pref.contains("\'") || pref.contains("ft") || pref.contains("feet")) { // foot to meters @@ -673,27 +693,27 @@ public class RouteDataObject { return false; } - public boolean roundabout(){ + public boolean roundabout() { int sz = types.length; - for(int i=0; i endPoint) { + if (startPoint > endPoint) { int k = endPoint; endPoint = startPoint; startPoint = k; } double d = 0; - for(int k = startPoint; k < endPoint && k < getPointsLength() -1; k++) { + for (int k = startPoint; k < endPoint && k < getPointsLength() - 1; k++) { int x = getPoint31XTile(k); int y = getPoint31YTile(k); int kx = getPoint31XTile(k + 1); @@ -974,16 +994,16 @@ public class RouteDataObject { // translate into meters total += simplifyDistance(x, y, px, py); } while (total < dist); - return -Math.atan2( x - px, y - py ); + return -Math.atan2(x - px, y - py); } private double simplifyDistance(int x, int y, int px, int py) { return Math.abs(px - x) * 0.011d + Math.abs(py - y) * 0.01863d; } - private static void assertTrueLength(String vl, float exp){ + private static void assertTrueLength(String vl, float exp) { float dest = parseLength(vl, 0); - if(exp != dest) { + if (exp != dest) { System.err.println("FAIL " + vl + " " + dest); } else { System.out.println("OK " + vl); @@ -992,24 +1012,24 @@ public class RouteDataObject { public static void main(String[] args) { assertTrueLength("10 km", 10000); - assertTrueLength("0.01 km", 10); - assertTrueLength("0.01 km 10 m", 20); - assertTrueLength("10 m", 10); - assertTrueLength("10m", 10); - assertTrueLength("3.4 m", 3.4f); - assertTrueLength("3.40 m", 3.4f); - assertTrueLength("10 m 10m", 20); - assertTrueLength("14'10\"", 4.5212f); - assertTrueLength("14.5'", 4.4196f); - assertTrueLength("14.5 ft", 4.4196f); - assertTrueLength("14'0\"", 4.2672f); - assertTrueLength("15ft", 4.572f); - assertTrueLength("15 ft 1 in", 4.5974f); - assertTrueLength("4.1 metres", 4.1f); - assertTrueLength("14'0''", 4.2672f); - assertTrueLength("14 feet", 4.2672f); - assertTrueLength("14 mile", 22530.76f); - assertTrueLength("14 cm", 0.14f); + assertTrueLength("0.01 km", 10); + assertTrueLength("0.01 km 10 m", 20); + assertTrueLength("10 m", 10); + assertTrueLength("10m", 10); + assertTrueLength("3.4 m", 3.4f); + assertTrueLength("3.40 m", 3.4f); + assertTrueLength("10 m 10m", 20); + assertTrueLength("14'10\"", 4.5212f); + assertTrueLength("14.5'", 4.4196f); + assertTrueLength("14.5 ft", 4.4196f); + assertTrueLength("14'0\"", 4.2672f); + assertTrueLength("15ft", 4.572f); + assertTrueLength("15 ft 1 in", 4.5974f); + assertTrueLength("4.1 metres", 4.1f); + assertTrueLength("14'0''", 4.2672f); + assertTrueLength("14 feet", 4.2672f); + assertTrueLength("14 mile", 22530.76f); + assertTrueLength("14 cm", 0.14f); // float badValue = -1; // assertTrueLength("none", badValue); @@ -1054,7 +1074,7 @@ public class RouteDataObject { public RestrictionInfo next; // optional to simulate linked list public int length() { - if(next == null) { + if (next == null) { return 1; } return next.length() + 1; @@ -1064,16 +1084,16 @@ public class RouteDataObject { public void setRestriction(int k, long to, int type, long viaWay) { long valto = (to << RouteDataObject.RESTRICTION_SHIFT) | ((long) type & RouteDataObject.RESTRICTION_MASK); restrictions[k] = valto; - if(viaWay != 0) { + if (viaWay != 0) { setRestrictionVia(k, viaWay); } } public void setRestrictionVia(int k, long viaWay) { - if(restrictionsVia != null) { + if (restrictionsVia != null) { long[] nrestrictionsVia = new long[Math.max(k + 1, restrictions.length)]; System.arraycopy(restrictions, 0, nrestrictionsVia, 0, restrictions.length); - restrictionsVia = nrestrictionsVia; + restrictionsVia = nrestrictionsVia; } else { restrictionsVia = new long[k + 1]; } diff --git a/OsmAnd/src/net/osmand/data/FavouritePoint.java b/OsmAnd/src/net/osmand/data/FavouritePoint.java index 7205b4a422..181c38d7f9 100644 --- a/OsmAnd/src/net/osmand/data/FavouritePoint.java +++ b/OsmAnd/src/net/osmand/data/FavouritePoint.java @@ -11,6 +11,9 @@ import androidx.annotation.Nullable; import androidx.annotation.StringRes; import net.osmand.GPXUtilities.WptPt; +import net.osmand.Location; +import net.osmand.ResultMatcher; +import net.osmand.binary.RouteDataObject; import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.OsmandApplication; import net.osmand.plus.settings.backend.BooleanPreference; @@ -42,6 +45,8 @@ public class FavouritePoint implements Serializable, LocationPoint { private boolean visible = true; private SpecialPointType specialPointType = null; private BackgroundType backgroundType = null; + private double altitude; + private long timestamp; public FavouritePoint() { } @@ -50,13 +55,26 @@ public class FavouritePoint implements Serializable, LocationPoint { this.latitude = latitude; this.longitude = longitude; this.category = category; - if(name == null) { + if (name == null) { name = ""; } this.name = name; initPersonalType(); } + public FavouritePoint(double latitude, double longitude, String name, String category, double altitude, long timestamp) { + this.latitude = latitude; + this.longitude = longitude; + this.category = category; + if (name == null) { + name = ""; + } + this.name = name; + this.altitude = altitude; + this.timestamp = timestamp; + initPersonalType(); + } + public FavouritePoint(FavouritePoint favouritePoint) { this.latitude = favouritePoint.latitude; this.longitude = favouritePoint.longitude; @@ -69,25 +87,48 @@ public class FavouritePoint implements Serializable, LocationPoint { this.address = favouritePoint.address; this.iconId = favouritePoint.iconId; this.backgroundType = favouritePoint.backgroundType; + this.altitude = favouritePoint.altitude; + this.timestamp = favouritePoint.timestamp; initPersonalType(); } private void initPersonalType() { - if(FavouritesDbHelper.FavoriteGroup.PERSONAL_CATEGORY.equals(category)) { - for(SpecialPointType p : SpecialPointType.values()) { - if(p.typeName.equals(this.name)) { + if (FavouritesDbHelper.FavoriteGroup.PERSONAL_CATEGORY.equals(category)) { + for (SpecialPointType p : SpecialPointType.values()) { + if (p.typeName.equals(this.name)) { this.specialPointType = p; } } } } + public void initAltitude(final OsmandApplication app, final Runnable callback) { + app.getLocationProvider().getRouteSegment(new Location("", latitude, longitude), null, false, new ResultMatcher() { + + @Override + public boolean publish(RouteDataObject routeDataObject) { + if (routeDataObject != null) { + routeDataObject.calculateHeightArray(new LatLon(latitude, longitude)); + altitude = routeDataObject.heightByCurrentLocation; + } else { + } + callback.run(); + return true; + } + + @Override + public boolean isCancelled() { + return false; + } + }); + } + public SpecialPointType getSpecialPointType() { return specialPointType; } public int getColor() { - return color; + return color; } @Nullable @@ -171,6 +212,22 @@ public class FavouritePoint implements Serializable, LocationPoint { this.longitude = longitude; } + public double getAltitude() { + return altitude; + } + + public void setAltitude(double altitude) { + this.altitude = altitude; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + public String getCategory() { return category; } @@ -200,7 +257,7 @@ public class FavouritePoint implements Serializable, LocationPoint { initPersonalType(); } - public String getDescription () { + public String getDescription() { return description; } @@ -256,7 +313,8 @@ public class FavouritePoint implements Serializable, LocationPoint { } else if (!originObjectName.equals(fp.originObjectName)) return false; - return (this.latitude == fp.latitude) && (this.longitude == fp.longitude); + return (this.latitude == fp.latitude) && (this.longitude == fp.longitude) && + (this.altitude == fp.altitude) && (this.timestamp == fp.timestamp); } @Override @@ -265,6 +323,8 @@ public class FavouritePoint implements Serializable, LocationPoint { int result = 1; result = prime * result + (int) Math.floor(latitude * 10000); result = prime * result + (int) Math.floor(longitude * 10000); + result = prime * result + (int) Math.floor(altitude * 10000); + result = prime * result + (int) Math.floor(timestamp * 10000); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((category == null) ? 0 : category.hashCode()); result = prime * result + ((description == null) ? 0 : description.hashCode()); @@ -289,7 +349,9 @@ public class FavouritePoint implements Serializable, LocationPoint { this.iconId = iconId; } - public String getCategory() { return FavouritesDbHelper.FavoriteGroup.PERSONAL_CATEGORY; } + public String getCategory() { + return FavouritesDbHelper.FavoriteGroup.PERSONAL_CATEGORY; + } public String getName() { return typeName; @@ -384,7 +446,7 @@ public class FavouritePoint implements Serializable, LocationPoint { name = ""; } FavouritePoint fp; - fp = new FavouritePoint(pt.lat, pt.lon, name, categoryName); + fp = new FavouritePoint(pt.lat, pt.lon, name, categoryName, pt.ele, pt.time); fp.setDescription(pt.desc); if (pt.comment != null) { fp.setOriginObjectName(pt.comment); @@ -405,6 +467,8 @@ public class FavouritePoint implements Serializable, LocationPoint { WptPt pt = new WptPt(); pt.lat = getLatitude(); pt.lon = getLongitude(); + pt.ele = getAltitude(); + pt.time = getTimestamp(); if (!isVisible()) { pt.getExtensionsToWrite().put(HIDDEN, "true"); } diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java index e65727b6c1..c4b78541de 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java @@ -212,7 +212,7 @@ public class ImportHelper { public static String getNameFromContentUri(OsmandApplication app, Uri contentUri) { try { String name; - Cursor returnCursor = app.getContentResolver().query(contentUri, new String[] {OpenableColumns.DISPLAY_NAME}, null, null, null); + Cursor returnCursor = app.getContentResolver().query(contentUri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null); if (returnCursor != null && returnCursor.moveToFirst()) { int columnIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); if (columnIndex != -1) { @@ -671,7 +671,7 @@ public class ImportHelper { } public static List asFavourites(OsmandApplication app, List wptPts, String fileName, boolean forceImportFavourites) { - List favourites = new ArrayList<>(); + final List favourites = new ArrayList<>(); for (WptPt p : wptPts) { if (Algorithms.isEmpty(p.name)) { p.name = app.getResources().getString(R.string.shared_string_waypoint); @@ -687,7 +687,7 @@ public class ImportHelper { } else { fpCat = p.category; } - FavouritePoint point = new FavouritePoint(p.lat, p.lon, p.name, fpCat); + final FavouritePoint point = new FavouritePoint(p.lat, p.lon, p.name, fpCat, p.ele, p.time); if (p.desc != null) { point.setDescription(p.desc); } @@ -698,7 +698,17 @@ public class ImportHelper { point.setIconIdFromName(app, iconName); } point.setBackgroundType(BackgroundType.getByTypeName(p.getBackgroundType(), DEFAULT_BACKGROUND_TYPE)); - favourites.add(point); + if (Double.isNaN(p.ele) || p.ele == 0) { + point.initAltitude(app, new Runnable() { + + @Override + public void run() { + favourites.add(point); + } + }); + } else { + favourites.add(point); + } } } return favourites; diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java index 3fe1e4452b..38bf3feb78 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java @@ -1036,6 +1036,8 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL title = ""; } String originObjectName = ""; + double altitude = 0; + long timestamp = System.currentTimeMillis(); Object object = getObject(); if (object != null) { if (object instanceof Amenity) { @@ -1043,10 +1045,13 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL } else if (object instanceof TransportStop) { originObjectName = ((TransportStop) object).toStringEn(); } + if (object instanceof WptPt) { + altitude = ((WptPt) object).ele; + } } FavoritePointEditor favoritePointEditor = getFavoritePointEditor(); if (favoritePointEditor != null) { - favoritePointEditor.add(getLatLon(), title, getStreetStr(), originObjectName); + favoritePointEditor.add(getLatLon(), title, getStreetStr(), originObjectName, altitude, timestamp); } } }); @@ -1074,7 +1079,8 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL for (OsmandMapLayer layer : mapActivity.getMapView().getLayers()) { layer.populateObjectContextMenu(latLon, getObject(), menuAdapter, mapActivity); } - mapActivity.getMapActions().addActionsToAdapter(configure ? 0 : latLon.getLatitude(), configure ? 0 : latLon.getLongitude(), menuAdapter, configure ? null : getObject(), configure); } + mapActivity.getMapActions().addActionsToAdapter(configure ? 0 : latLon.getLatitude(), configure ? 0 : latLon.getLongitude(), menuAdapter, configure ? null : getObject(), configure); + } return menuAdapter; } diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java index 513cd707d5..4e011ea21a 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java @@ -27,8 +27,8 @@ public class FavoritePointEditor extends PointEditor { return favorite; } - public void add(LatLon latLon, String title, String address, String originObjectName) { - MapActivity mapActivity = getMapActivity(); + public void add(LatLon latLon, String title, String address, String originObjectName, double altitude, long timestamp) { + final MapActivity mapActivity = getMapActivity(); if (latLon == null || mapActivity == null) { return; } @@ -37,15 +37,24 @@ public class FavoritePointEditor extends PointEditor { if (!Algorithms.isEmpty(lastCategory) && !app.getFavorites().groupExists(lastCategory)) { lastCategory = ""; } - favorite = new FavouritePoint(latLon.getLatitude(), latLon.getLongitude(), title, lastCategory); + favorite = new FavouritePoint(latLon.getLatitude(), latLon.getLongitude(), title, lastCategory, (float) altitude, timestamp); favorite.setDescription(""); favorite.setAddress(address.isEmpty() ? title : address); favorite.setOriginObjectName(originObjectName); - FavoritePointEditorFragmentNew.showInstance(mapActivity); + if (Double.isNaN(altitude) || altitude == 0) { + favorite.initAltitude(app, new Runnable() { + @Override + public void run() { + FavoritePointEditorFragmentNew.showInstance(mapActivity); + } + }); + } else { + FavoritePointEditorFragmentNew.showInstance(mapActivity); + } } - public void add(LatLon latLon, String title, String originObjectName, String categoryName, int categoryColor, boolean autoFill) { - MapActivity mapActivity = getMapActivity(); + public void add(LatLon latLon, String title, String originObjectName, String categoryName, int categoryColor, final boolean autoFill, double altitude, long timestamp) { + final MapActivity mapActivity = getMapActivity(); if (latLon == null || mapActivity == null) { return; } @@ -60,12 +69,20 @@ public class FavoritePointEditor extends PointEditor { categoryName = ""; } - favorite = new FavouritePoint(latLon.getLatitude(), latLon.getLongitude(), title, categoryName); + favorite = new FavouritePoint(latLon.getLatitude(), latLon.getLongitude(), title, categoryName, (float) altitude, timestamp); favorite.setDescription(""); favorite.setAddress(""); favorite.setOriginObjectName(originObjectName); - - FavoritePointEditorFragmentNew.showAutoFillInstance(mapActivity, autoFill); + if (Double.isNaN(altitude) || altitude == 0) { + favorite.initAltitude(app, new Runnable() { + @Override + public void run() { + FavoritePointEditorFragmentNew.showAutoFillInstance(mapActivity, autoFill); + } + }); + } else { + FavoritePointEditorFragmentNew.showAutoFillInstance(mapActivity, autoFill); + } } public void edit(FavouritePoint favorite) { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragment.java index fe05bf4296..e50b1fe724 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragment.java @@ -190,7 +190,7 @@ public class FavoritePointEditorFragment extends PointEditorFragment { final FavouritePoint favorite = getFavorite(); if (favorite != null) { final FavouritePoint point = new FavouritePoint(favorite.getLatitude(), favorite.getLongitude(), - getNameTextValue(), getCategoryTextValue()); + getNameTextValue(), getCategoryTextValue(), favorite.getAltitude(), favorite.getTimestamp()); point.setDescription(getDescriptionTextValue()); point.setAddress(getAddressTextValue()); AlertDialog.Builder builder = FavouritesDbHelper.checkDuplicates(point, helper, getMapActivity()); @@ -198,7 +198,7 @@ public class FavoritePointEditorFragment extends PointEditorFragment { if (favorite.getName().equals(point.getName()) && favorite.getCategory().equals(point.getCategory()) && Algorithms.stringsEqual(favorite.getDescription(), point.getDescription()) && - Algorithms.stringsEqual(favorite.getAddress(),point.getAddress())) { + Algorithms.stringsEqual(favorite.getAddress(), point.getAddress())) { if (needDismiss) { dismiss(false); } @@ -209,7 +209,7 @@ public class FavoritePointEditorFragment extends PointEditorFragment { builder.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - doSave(favorite, point.getName(), point.getCategory(), point.getDescription(),point.getAddress(), needDismiss); + doSave(favorite, point.getName(), point.getCategory(), point.getDescription(), point.getAddress(), needDismiss); } }); builder.create().show(); @@ -225,9 +225,9 @@ public class FavoritePointEditorFragment extends PointEditorFragment { FavoritePointEditor editor = getFavoritePointEditor(); if (editor != null && helper != null) { if (editor.isNew()) { - doAddFavorite(name, category, description,address); + doAddFavorite(name, category, description, address); } else { - helper.editFavouriteName(favorite, name, category, description,address); + helper.editFavouriteName(favorite, name, category, description, address); } } MapActivity mapActivity = getMapActivity(); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java index 3e4093d253..7f175589cd 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java @@ -242,7 +242,7 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew { final FavouritePoint favorite = getFavorite(); if (favorite != null) { final FavouritePoint point = new FavouritePoint(favorite.getLatitude(), favorite.getLongitude(), - getNameTextValue(), getCategoryTextValue()); + getNameTextValue(), getCategoryTextValue(), favorite.getAltitude(), favorite.getTimestamp()); point.setDescription(isDescriptionAvailable() ? getDescriptionTextValue() : null); point.setAddress(isAddressAvailable() ? getAddressTextValue() : null); point.setColor(color); @@ -258,7 +258,7 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew { final FavouritePoint favorite = getFavorite(); if (favorite != null) { final FavouritePoint point = new FavouritePoint(favorite.getLatitude(), favorite.getLongitude(), - getNameTextValue(), getCategoryTextValue()); + getNameTextValue(), getCategoryTextValue(), favorite.getAltitude(), favorite.getTimestamp()); point.setDescription(isDescriptionAvailable() ? getDescriptionTextValue() : null); point.setAddress(isAddressAvailable() ? getAddressTextValue() : null); point.setColor(color); @@ -302,7 +302,7 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew { } private void doSave(FavouritePoint favorite, String name, String category, String description, String address, - @ColorInt int color, BackgroundType backgroundType, @DrawableRes int iconId, boolean needDismiss) { + @ColorInt int color, BackgroundType backgroundType, @DrawableRes int iconId, boolean needDismiss) { FavouritesDbHelper helper = getHelper(); FavoritePointEditor editor = getFavoritePointEditor(); if (editor != null && helper != null) { @@ -329,8 +329,8 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew { } private void doEditFavorite(FavouritePoint favorite, String name, String category, String description, String address, - @ColorInt int color, BackgroundType backgroundType, @DrawableRes int iconId, - FavouritesDbHelper helper) { + @ColorInt int color, BackgroundType backgroundType, @DrawableRes int iconId, + FavouritesDbHelper helper) { OsmandApplication app = getMyApplication(); if (app != null) { app.getSettings().LAST_FAV_CATEGORY_ENTERED.set(category); @@ -342,7 +342,7 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew { } private void doAddFavorite(String name, String category, String description, String address, @ColorInt int color, - BackgroundType backgroundType, @DrawableRes int iconId) { + BackgroundType backgroundType, @DrawableRes int iconId) { OsmandApplication app = getMyApplication(); FavouritesDbHelper helper = getHelper(); FavouritePoint favorite = getFavorite(); diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java index fbe79b0681..faa72a16f6 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java @@ -119,7 +119,7 @@ public class FavoriteAction extends QuickAction { FavoritePointEditor favoritePointEditor = mapActivity.getContextMenu().getFavoritePointEditor(); if (favoritePointEditor != null) { favoritePointEditor.add(latLon, title, "", getParams().get(KEY_CATEGORY_NAME), - Integer.valueOf(getParams().get(KEY_CATEGORY_COLOR)), autoFill); + Integer.valueOf(getParams().get(KEY_CATEGORY_COLOR)), autoFill, 0, 0); } } From a702787f090151d64cb68d2a0549434175c97259 Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 25 Feb 2021 03:49:52 +0200 Subject: [PATCH 13/29] some fixes --- .../src/net/osmand/data/FavouritePoint.java | 12 +++++++--- .../plus/importfiles/FavoritesImportTask.java | 6 ++++- .../osmand/plus/importfiles/ImportHelper.java | 14 ++---------- .../editors/FavoritePointEditor.java | 22 ++++++++----------- .../quickaction/actions/FavoriteAction.java | 2 +- 5 files changed, 26 insertions(+), 30 deletions(-) diff --git a/OsmAnd/src/net/osmand/data/FavouritePoint.java b/OsmAnd/src/net/osmand/data/FavouritePoint.java index 181c38d7f9..f4ab5d77b1 100644 --- a/OsmAnd/src/net/osmand/data/FavouritePoint.java +++ b/OsmAnd/src/net/osmand/data/FavouritePoint.java @@ -59,6 +59,7 @@ public class FavouritePoint implements Serializable, LocationPoint { name = ""; } this.name = name; + timestamp = System.currentTimeMillis(); initPersonalType(); } @@ -71,7 +72,7 @@ public class FavouritePoint implements Serializable, LocationPoint { } this.name = name; this.altitude = altitude; - this.timestamp = timestamp; + this.timestamp = timestamp != 0 ? timestamp : System.currentTimeMillis(); initPersonalType(); } @@ -102,6 +103,10 @@ public class FavouritePoint implements Serializable, LocationPoint { } } + public void initAltitude(final OsmandApplication app) { + initAltitude(app, null); + } + public void initAltitude(final OsmandApplication app, final Runnable callback) { app.getLocationProvider().getRouteSegment(new Location("", latitude, longitude), null, false, new ResultMatcher() { @@ -110,9 +115,10 @@ public class FavouritePoint implements Serializable, LocationPoint { if (routeDataObject != null) { routeDataObject.calculateHeightArray(new LatLon(latitude, longitude)); altitude = routeDataObject.heightByCurrentLocation; - } else { } - callback.run(); + if (callback != null) { + callback.run(); + } return true; } diff --git a/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java index fd37d049eb..67f7881eb5 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java @@ -24,7 +24,7 @@ class FavoritesImportTask extends BaseLoadAsyncTask { private boolean forceImportFavourites; public FavoritesImportTask(@NonNull FragmentActivity activity, @NonNull GPXFile gpxFile, - @NonNull String fileName, boolean forceImportFavourites) { + @NonNull String fileName, boolean forceImportFavourites) { super(activity); this.gpxFile = gpxFile; this.fileName = fileName; @@ -39,6 +39,10 @@ class FavoritesImportTask extends BaseLoadAsyncTask { for (FavouritePoint favourite : favourites) { favoritesHelper.deleteFavourite(favourite, false); favoritesHelper.addFavourite(favourite, false); + double alt = favourite.getAltitude(); + if (Double.isNaN(alt) || alt == 0) { + favourite.initAltitude(app); + } } favoritesHelper.sortAll(); favoritesHelper.saveCurrentPointsIntoFile(); diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java index c4b78541de..f32089f9f6 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java @@ -687,7 +687,7 @@ public class ImportHelper { } else { fpCat = p.category; } - final FavouritePoint point = new FavouritePoint(p.lat, p.lon, p.name, fpCat, p.ele, p.time); + final FavouritePoint point = new FavouritePoint(p.lat, p.lon, p.name, fpCat, p.ele, 0); if (p.desc != null) { point.setDescription(p.desc); } @@ -698,17 +698,7 @@ public class ImportHelper { point.setIconIdFromName(app, iconName); } point.setBackgroundType(BackgroundType.getByTypeName(p.getBackgroundType(), DEFAULT_BACKGROUND_TYPE)); - if (Double.isNaN(p.ele) || p.ele == 0) { - point.initAltitude(app, new Runnable() { - - @Override - public void run() { - favourites.add(point); - } - }); - } else { - favourites.add(point); - } + favourites.add(point); } } return favourites; diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java index 4e011ea21a..5c0b6f8b59 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java @@ -37,7 +37,7 @@ public class FavoritePointEditor extends PointEditor { if (!Algorithms.isEmpty(lastCategory) && !app.getFavorites().groupExists(lastCategory)) { lastCategory = ""; } - favorite = new FavouritePoint(latLon.getLatitude(), latLon.getLongitude(), title, lastCategory, (float) altitude, timestamp); + favorite = new FavouritePoint(latLon.getLatitude(), latLon.getLongitude(), title, lastCategory, altitude, timestamp); favorite.setDescription(""); favorite.setAddress(address.isEmpty() ? title : address); favorite.setOriginObjectName(originObjectName); @@ -53,7 +53,7 @@ public class FavoritePointEditor extends PointEditor { } } - public void add(LatLon latLon, String title, String originObjectName, String categoryName, int categoryColor, final boolean autoFill, double altitude, long timestamp) { + public void add(LatLon latLon, String title, String originObjectName, String categoryName, int categoryColor, final boolean autoFill) { final MapActivity mapActivity = getMapActivity(); if (latLon == null || mapActivity == null) { return; @@ -69,20 +69,16 @@ public class FavoritePointEditor extends PointEditor { categoryName = ""; } - favorite = new FavouritePoint(latLon.getLatitude(), latLon.getLongitude(), title, categoryName, (float) altitude, timestamp); + favorite = new FavouritePoint(latLon.getLatitude(), latLon.getLongitude(), title, categoryName); favorite.setDescription(""); favorite.setAddress(""); favorite.setOriginObjectName(originObjectName); - if (Double.isNaN(altitude) || altitude == 0) { - favorite.initAltitude(app, new Runnable() { - @Override - public void run() { - FavoritePointEditorFragmentNew.showAutoFillInstance(mapActivity, autoFill); - } - }); - } else { - FavoritePointEditorFragmentNew.showAutoFillInstance(mapActivity, autoFill); - } + favorite.initAltitude(app, new Runnable() { + @Override + public void run() { + FavoritePointEditorFragmentNew.showAutoFillInstance(mapActivity, autoFill); + } + }); } public void edit(FavouritePoint favorite) { diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java index faa72a16f6..fbe79b0681 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/FavoriteAction.java @@ -119,7 +119,7 @@ public class FavoriteAction extends QuickAction { FavoritePointEditor favoritePointEditor = mapActivity.getContextMenu().getFavoritePointEditor(); if (favoritePointEditor != null) { favoritePointEditor.add(latLon, title, "", getParams().get(KEY_CATEGORY_NAME), - Integer.valueOf(getParams().get(KEY_CATEGORY_COLOR)), autoFill, 0, 0); + Integer.valueOf(getParams().get(KEY_CATEGORY_COLOR)), autoFill); } } From 066ee38de2c16e05099b856d0b914946f2fb1b1a Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 25 Feb 2021 05:04:43 +0200 Subject: [PATCH 14/29] fix use a more universal method for adding altitude --- .../net/osmand/plus/FavouritesDbHelper.java | 6 ++++++ .../plus/importfiles/FavoritesImportTask.java | 4 ---- .../editors/FavoritePointEditor.java | 18 ++---------------- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java index 992a0e42c6..2693d76a93 100644 --- a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java @@ -361,6 +361,9 @@ public class FavouritesDbHelper { } public boolean addFavourite(FavouritePoint p, boolean saveImmediately) { + if (p.getAltitude() == 0) { + p.initAltitude(context); + } if (p.getName().isEmpty() && flatGroups.containsKey(p.getCategory())) { return true; } @@ -543,6 +546,9 @@ public class FavouritesDbHelper { private boolean editFavourite(@NonNull FavouritePoint p, double lat, double lon, @Nullable String description) { cancelAddressRequest(p); + if (p.getLatitude() != lat && p.getLongitude() != lon) { + p.initAltitude(context); + } p.setLatitude(lat); p.setLongitude(lon); if (description != null) { diff --git a/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java index 67f7881eb5..b62de4923c 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java @@ -39,10 +39,6 @@ class FavoritesImportTask extends BaseLoadAsyncTask { for (FavouritePoint favourite : favourites) { favoritesHelper.deleteFavourite(favourite, false); favoritesHelper.addFavourite(favourite, false); - double alt = favourite.getAltitude(); - if (Double.isNaN(alt) || alt == 0) { - favourite.initAltitude(app); - } } favoritesHelper.sortAll(); favoritesHelper.saveCurrentPointsIntoFile(); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java index 5c0b6f8b59..26e83413be 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java @@ -41,16 +41,7 @@ public class FavoritePointEditor extends PointEditor { favorite.setDescription(""); favorite.setAddress(address.isEmpty() ? title : address); favorite.setOriginObjectName(originObjectName); - if (Double.isNaN(altitude) || altitude == 0) { - favorite.initAltitude(app, new Runnable() { - @Override - public void run() { - FavoritePointEditorFragmentNew.showInstance(mapActivity); - } - }); - } else { - FavoritePointEditorFragmentNew.showInstance(mapActivity); - } + FavoritePointEditorFragmentNew.showInstance(mapActivity); } public void add(LatLon latLon, String title, String originObjectName, String categoryName, int categoryColor, final boolean autoFill) { @@ -73,12 +64,7 @@ public class FavoritePointEditor extends PointEditor { favorite.setDescription(""); favorite.setAddress(""); favorite.setOriginObjectName(originObjectName); - favorite.initAltitude(app, new Runnable() { - @Override - public void run() { - FavoritePointEditorFragmentNew.showAutoFillInstance(mapActivity, autoFill); - } - }); + FavoritePointEditorFragmentNew.showAutoFillInstance(mapActivity, autoFill); } public void edit(FavouritePoint favorite) { From 0d4765142afc949b9a27e01525e82be347bc758a Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 25 Feb 2021 05:22:09 +0200 Subject: [PATCH 15/29] rollback some changes; small fixes; --- .../src/net/osmand/data/FavouritePoint.java | 41 ++++++++++--------- .../net/osmand/plus/FavouritesDbHelper.java | 6 +-- .../osmand/plus/importfiles/ImportHelper.java | 4 +- .../editors/FavoritePointEditor.java | 6 +-- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/OsmAnd/src/net/osmand/data/FavouritePoint.java b/OsmAnd/src/net/osmand/data/FavouritePoint.java index f4ab5d77b1..f87083363f 100644 --- a/OsmAnd/src/net/osmand/data/FavouritePoint.java +++ b/OsmAnd/src/net/osmand/data/FavouritePoint.java @@ -103,30 +103,33 @@ public class FavouritePoint implements Serializable, LocationPoint { } } - public void initAltitude(final OsmandApplication app) { + public void initAltitude(OsmandApplication app) { initAltitude(app, null); } - public void initAltitude(final OsmandApplication app, final Runnable callback) { - app.getLocationProvider().getRouteSegment(new Location("", latitude, longitude), null, false, new ResultMatcher() { + public void initAltitude(OsmandApplication app, final Runnable callback) { + Location location = new Location("", latitude, longitude); + app.getLocationProvider().getRouteSegment(location, null, false, + new ResultMatcher() { - @Override - public boolean publish(RouteDataObject routeDataObject) { - if (routeDataObject != null) { - routeDataObject.calculateHeightArray(new LatLon(latitude, longitude)); - altitude = routeDataObject.heightByCurrentLocation; - } - if (callback != null) { - callback.run(); - } - return true; - } + @Override + public boolean publish(RouteDataObject routeDataObject) { + if (routeDataObject != null) { + LatLon latLon = new LatLon(latitude, longitude); + routeDataObject.calculateHeightArray(latLon); + altitude = routeDataObject.heightByCurrentLocation; + } + if (callback != null) { + callback.run(); + } + return true; + } - @Override - public boolean isCancelled() { - return false; - } - }); + @Override + public boolean isCancelled() { + return false; + } + }); } public SpecialPointType getSpecialPointType() { diff --git a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java index 2693d76a93..9fffc074c2 100644 --- a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java @@ -361,7 +361,7 @@ public class FavouritesDbHelper { } public boolean addFavourite(FavouritePoint p, boolean saveImmediately) { - if (p.getAltitude() == 0) { + if (Double.isNaN(p.getAltitude()) || p.getAltitude() == 0) { p.initAltitude(context); } if (p.getName().isEmpty() && flatGroups.containsKey(p.getCategory())) { @@ -546,11 +546,9 @@ public class FavouritesDbHelper { private boolean editFavourite(@NonNull FavouritePoint p, double lat, double lon, @Nullable String description) { cancelAddressRequest(p); - if (p.getLatitude() != lat && p.getLongitude() != lon) { - p.initAltitude(context); - } p.setLatitude(lat); p.setLongitude(lon); + p.initAltitude(context); if (description != null) { p.setDescription(description); } diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java index f32089f9f6..3f5510bb4c 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java @@ -671,7 +671,7 @@ public class ImportHelper { } public static List asFavourites(OsmandApplication app, List wptPts, String fileName, boolean forceImportFavourites) { - final List favourites = new ArrayList<>(); + List favourites = new ArrayList<>(); for (WptPt p : wptPts) { if (Algorithms.isEmpty(p.name)) { p.name = app.getResources().getString(R.string.shared_string_waypoint); @@ -687,7 +687,7 @@ public class ImportHelper { } else { fpCat = p.category; } - final FavouritePoint point = new FavouritePoint(p.lat, p.lon, p.name, fpCat, p.ele, 0); + FavouritePoint point = new FavouritePoint(p.lat, p.lon, p.name, fpCat, p.ele, 0); if (p.desc != null) { point.setDescription(p.desc); } diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java index 26e83413be..2d2836234c 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditor.java @@ -28,7 +28,7 @@ public class FavoritePointEditor extends PointEditor { } public void add(LatLon latLon, String title, String address, String originObjectName, double altitude, long timestamp) { - final MapActivity mapActivity = getMapActivity(); + MapActivity mapActivity = getMapActivity(); if (latLon == null || mapActivity == null) { return; } @@ -44,8 +44,8 @@ public class FavoritePointEditor extends PointEditor { FavoritePointEditorFragmentNew.showInstance(mapActivity); } - public void add(LatLon latLon, String title, String originObjectName, String categoryName, int categoryColor, final boolean autoFill) { - final MapActivity mapActivity = getMapActivity(); + public void add(LatLon latLon, String title, String originObjectName, String categoryName, int categoryColor, boolean autoFill) { + MapActivity mapActivity = getMapActivity(); if (latLon == null || mapActivity == null) { return; } From 33c5c562d9f4237a252519ef9fa102c195727e30 Mon Sep 17 00:00:00 2001 From: cepprice Date: Thu, 25 Feb 2021 20:17:55 +0500 Subject: [PATCH 16/29] Invert setting value in preference bottom sheet --- .../bottomsheets/BooleanPreferenceBottomSheet.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java index 8b8b241b1b..b0536fe72b 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java @@ -66,7 +66,7 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet { ? getString(R.string.shared_string_disabled) : summaryOff.toString(); final int activeColor = AndroidUtils.resolveAttribute(themedCtx, R.attr.active_color_basic); final int disabledColor = AndroidUtils.resolveAttribute(themedCtx, android.R.attr.textColorSecondary); - boolean checked = pref.getModeValue(getAppMode()); + boolean checked = isPreferenceChecked(pref, app); final BottomSheetItemWithCompoundButton[] preferenceBtn = new BottomSheetItemWithCompoundButton[1]; preferenceBtn[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() @@ -77,7 +77,7 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet { .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - boolean newValue = !pref.getModeValue(getAppMode()); + boolean newValue = !isPreferenceChecked(pref, app); Fragment targetFragment = getTargetFragment(); if (targetFragment instanceof OnConfirmPreferenceChange) { ApplyQueryType applyQueryType = getApplyQueryType(); @@ -156,6 +156,13 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet { return (SwitchPreferenceEx) getPreference(); } + private boolean isPreferenceChecked(BooleanPreference preference, OsmandApplication app) { + boolean checked = preference.getModeValue(getAppMode()); + boolean shouldInvertSetting = app.getSettings().DISABLE_COMPLEX_ROUTING.getId() + .equals(preference.getId()); + return checked != shouldInvertSetting; + } + public static void showInstance(@NonNull FragmentManager fm, String prefId, Fragment target, boolean usedOnMap, @Nullable ApplicationMode appMode, ApplyQueryType applyQueryType, boolean profileDependent) { From 399ea02fdfc3aab8bbb0119de8a32d9e6f091805 Mon Sep 17 00:00:00 2001 From: ivanPyrohivskyi Date: Thu, 25 Feb 2021 17:32:25 +0200 Subject: [PATCH 17/29] Gradient colorization for route --- .../java/net/osmand/router/RouteColorize.java | 380 ++++++++++++++++++ 1 file changed, 380 insertions(+) create mode 100644 OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java new file mode 100644 index 0000000000..9074403176 --- /dev/null +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -0,0 +1,380 @@ +package net.osmand.router; + +import net.osmand.GPXUtilities; +import net.osmand.osm.edit.Node; +import net.osmand.osm.edit.OsmMapUtils; +import net.osmand.util.MapUtils; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; + +public class RouteColorize { + + public int zoom; + public double[] latitudes; + public double[] longitudes; + public double[] values; + public double minValue; + public double maxValue; + public double[][] palette; + + private List dataList; + private static final String ANSI_RESET = "\u001B[0m"; + private static final String ANSI_RED = "\u001B[31m"; + private static final String ANSI_GREEN = "\u001B[32m"; + public static final String ANSI_YELLOW = "\u001B[33m"; + + public enum ValueType { + ELEVATION, + SPEED, + SLOPE, + NONE + } + + private ValueType valueType; + + public static int SLOPE_RANGE = 150; + + + /** + * @param minValue can be NaN + * @param maxValue can be NaN + * @param palette array {{[color][value]},...}, color in sRGB format + */ + public RouteColorize(int zoom, double[] latitudes, double[] longitudes, double[] values, double minValue, double maxValue, double[][] palette) { + this.zoom = zoom; + this.latitudes = latitudes; + this.longitudes = longitudes; + this.values = values; + this.minValue = minValue; + this.maxValue = maxValue; + this.palette = palette; + + if (Double.isNaN(minValue) || Double.isNaN(maxValue)) { + calculateMinMaxValue(); + } + checkPalette(); + sortPalette(); + } + + /** + * @param palette array {{[color][value]},...}, color in sRGB format + * @param type ELEVATION, SPEED, SLOPE + */ + public RouteColorize(int zoom, double[][] palette, List wptPtList, ValueType type) { + this.zoom = zoom; + this.palette = palette; + + latitudes = new double[wptPtList.size()]; + longitudes = new double[wptPtList.size()]; + values = new double[wptPtList.size()]; + double[] elevations = new double[wptPtList.size()]; + for (int i = 0; i < wptPtList.size(); i++) { + latitudes[i] = wptPtList.get(i).lat; + longitudes[i] = wptPtList.get(i).lon; + if (type == ValueType.ELEVATION) { + values[i] = wptPtList.get(i).ele; + } else if (type == ValueType.SPEED) { + values[i] = wptPtList.get(i).speed; + } else if (type == ValueType.SLOPE) { + elevations[i] = wptPtList.get(i).ele; + } + } + + if (type == ValueType.SLOPE) { + values = calculateSlopesByElevations(latitudes, longitudes, elevations, SLOPE_RANGE); + } + + calculateMinMaxValue(); + valueType = type; + checkPalette(); + sortPalette(); + } + + /** + * Calculate slopes from elevations needs for right colorizing + * + * @param slopeRange - in what range calculate the derivative, usually we used 150 meters + * @return slopes array, in the begin and the end present NaN values! + */ + public static double[] calculateSlopesByElevations(double[] latitudes, double[] longitudes, double[] elevations, double slopeRange) { + + double[] newElevations = elevations; + for (int i = 2; i < elevations.length - 2; i++) { + newElevations[i] = elevations[i - 2] + + elevations[i - 1] + + elevations[i] + + elevations[i + 1] + + elevations[i + 2]; + newElevations[i] /= 5; + } + elevations = newElevations; + + double[] slopes = new double[elevations.length]; + if (latitudes.length != longitudes.length || latitudes.length != elevations.length) { + System.out.println(ANSI_RED + "Sizes of arrays latitudes, longitudes and values are not match" + ANSI_RESET); + return slopes; + } + + double[] distances = new double[elevations.length]; + double totalDistance = 0.0d; + distances[0] = totalDistance; + for (int i = 0; i < elevations.length - 1; i++) { + totalDistance += MapUtils.getDistance(latitudes[i], longitudes[i], latitudes[i + 1], longitudes[i + 1]); + distances[i + 1] = totalDistance; + } + + for (int i = 0; i < elevations.length; i++) { + if (distances[i] < slopeRange / 2 || distances[i] > totalDistance - slopeRange / 2) { + slopes[i] = Double.NaN; + } else { + double[] arg = findDerivativeArguments(distances, elevations, i, slopeRange); + slopes[i] = (arg[1] - arg[0]) / (arg[3] - arg[2]); + } + } + return slopes; + } + + public List getResult(boolean simplify) { + List result = new ArrayList<>(); + if (simplify) { + result = simplify(); + } else { + for (int i = 0; i < latitudes.length; i++) { + result.add(new Data(i, latitudes[i], longitudes[i], values[i])); + } + } + for (Data data : result) { + data.color = getColorByValue(data.val); + } + return result; + } + + public Color getColorByValue(double value) { + if (Double.isNaN(value)) { + return getDefaultColor(); + } + for (int i = 0; i < palette.length - 1; i++) { + if (value == palette[i][1]) + return new Color((int) palette[i][0]); + if (value > palette[i][1] && value < palette[i + 1][1]) { + Color minPaletteColor = new Color((int) palette[i][0]); + Color maxPaletteColor = new Color((int) palette[i + 1][0]); + double minPaletteValue = palette[i][1]; + double maxPaletteValue = palette[i + 1][1]; + double percent = (value - minPaletteValue) / (maxPaletteValue - minPaletteValue); + double resultRed = minPaletteColor.getRed() + percent * (maxPaletteColor.getRed() - minPaletteColor.getRed()); + double resultGreen = minPaletteColor.getGreen() + percent * (maxPaletteColor.getGreen() - minPaletteColor.getGreen()); + double resultBlue = minPaletteColor.getBlue() + percent * (maxPaletteColor.getBlue() - minPaletteColor.getBlue()); + double resultAlpha = minPaletteColor.getAlpha() + percent * (maxPaletteColor.getAlpha() - minPaletteColor.getAlpha()); + return new Color((int) resultRed, (int) resultGreen, (int) resultBlue, (int) resultAlpha); + } + } + return getDefaultColor(); + } + + private Color getDefaultColor() { + if (valueType != null && valueType == ValueType.SLOPE) { + return new Color(255, 222, 2, 227); + } + return new Color(0, 0, 0, 0); + } + + private List simplify() { + if (dataList == null) { + dataList = new ArrayList<>(); + for (int i = 0; i < latitudes.length; i++) { + dataList.add(new Data(i, latitudes[i], longitudes[i], values[i])); + } + } + List nodes = new ArrayList<>(); + List result = new ArrayList<>(); + for (Data data : dataList) { + nodes.add(new net.osmand.osm.edit.Node(data.lat, data.lon, data.id)); + } + OsmMapUtils.simplifyDouglasPeucker(nodes, zoom + 5, 1, result, true); + + List simplified = new ArrayList<>(); + + for (int i = 1; i < result.size() - 1; i++) { + int prevId = (int) result.get(i - 1).getId(); + int currentId = (int) result.get(i).getId(); + List sublist = dataList.subList(prevId, currentId); + simplified.addAll(getExtremums(sublist)); + } + return simplified; + } + + private List getExtremums(List subDataList) { + if (subDataList.size() <= 2) + return subDataList; + + List result = new ArrayList<>(); + double min; + double max; + min = max = subDataList.get(0).val; + for (Data pt : subDataList) { + if (min > pt.val) + min = pt.val; + if (max < pt.val) + max = pt.val; + } + + double diff = max - min; + + result.add(subDataList.get(0)); + for (int i = 1; i < subDataList.size() - 1; i++) { + double prev = subDataList.get(i - 1).val; + double current = subDataList.get(i).val; + double next = subDataList.get(i + 1).val; + Data currentData = subDataList.get(i); + + if ((current > prev && current > next) || (current < prev && current < next) + || (current < prev && current == next) || (current == prev && current < next) + || (current > prev && current == next) || (current == prev && current > next)) { + Data prevInResult; + if (result.size() > 0) { + prevInResult = result.get(0); + if (prevInResult.val / diff > 0.05d) {// check differences in 5% + result.add(currentData); + } + } else + result.add(currentData); + } + } + result.add(subDataList.get(subDataList.size() - 1)); + return result; + } + + private void checkPalette() { + if (palette.length < 2 || palette[0].length < 2 || palette[1].length < 2) { + System.out.println(ANSI_YELLOW + "Fill palette in {{[color][value]},...} format. Will use default palette" + ANSI_RESET); + palette = new double[3][2]; + Color red = new Color(255, 1, 1, 255); + Color yellow = new Color(255, 222, 2, 227); + Color green = new Color(46, 185, 0, 191); + + double[][] defaultPalette = { + { green.getRGB(), minValue}, + { yellow.getRGB(), valueType == ValueType.SLOPE ? 0 : (minValue + maxValue) / 2}, + { red.getRGB(), maxValue} + }; + palette = defaultPalette; + } + double min; + double max = min = palette[0][1]; + int minIndex = 0; + int maxIndex = 0; + for (int i = 0; i < palette.length; i++) { + double[] p = palette[i]; + if (p[1] > max) { + max = p[1]; + maxIndex = i; + } + if (p[1] < min) { + min = p[1]; + minIndex = i; + } + } + if (minValue < min) { + palette[minIndex][1] = minValue; + } + if (maxValue > max) { + palette[maxIndex][1] = maxValue; + } + } + + private void sortPalette() { + java.util.Arrays.sort(palette, new java.util.Comparator() { + public int compare(double[] a, double[] b) { + return Double.compare(a[1], b[1]); + } + }); + } + + /** + * @return double[minElevation, maxElevation, minDist, maxDist] + */ + private static double[] findDerivativeArguments(double[] distances, double[] elevations, int index, double slopeRange) { + double[] result = new double[4]; + double minDist = distances[index] - slopeRange / 2; + double maxDist = distances[index] + slopeRange / 2; + result[0] = Double.NaN; + result[1] = Double.NaN; + result[2] = minDist; + result[3] = maxDist; + int closestMaxIndex = -1; + int closestMinIndex = -1; + for (int i = index; i < distances.length; i++) { + if (distances[i] == maxDist) { + result[1] = elevations[i]; + break; + } + if (distances[i] > maxDist) { + closestMaxIndex = i; + break; + } + } + for (int i = index; i >= 0; i--) { + if (distances[i] == minDist) { + result[0] = elevations[i]; + break; + } + if (distances[i] < minDist) { + closestMinIndex = i; + break; + } + } + if (closestMaxIndex > 0) { + double diff = distances[closestMaxIndex] - distances[closestMaxIndex - 1]; + double coef = (maxDist - distances[closestMaxIndex - 1]) / diff; + if (coef > 1 || coef < 0) { + System.out.println(ANSI_RED + "Coefficient fo max must be 0..1 , coef=" + coef + ANSI_RESET); + } + result[1] = (1 - coef) * elevations[closestMaxIndex - 1] + coef * elevations[closestMaxIndex]; + } + if (closestMinIndex >= 0) { + double diff = distances[closestMinIndex + 1] - distances[closestMinIndex]; + double coef = (minDist - distances[closestMinIndex]) / diff; + if (coef > 1 || coef < 0) { + System.out.println(ANSI_RED + "Coefficient for min must be 0..1 , coef=" + coef + ANSI_RESET); + } + result[0] = (1 - coef) * elevations[closestMinIndex] + coef * elevations[closestMinIndex + 1]; + } + if (Double.isNaN(result[0]) || Double.isNaN(result[1])) { + System.out.println(ANSI_RED + "Elevations wasn't calculated" + ANSI_RESET); + } + return result; + } + + private void calculateMinMaxValue() { + if (values.length == 0) + return; + minValue = maxValue = Double.NaN; + for (double value : values) { + if ((Double.isNaN(maxValue) || Double.isNaN(minValue)) && !Double.isNaN(value)) + maxValue = minValue = value; + if (minValue > value) + minValue = value; + if (maxValue < value) + maxValue = value; + } + } + + public class Data { + int id; + public double lat; + public double lon; + public double val; + public Color color; + + Data(int id, double lat, double lon, double val) { + this.id = id; + this.lat = lat; + this.lon = lon; + this.val = val; + } + } + +} From 1c0e5411b1870bed7dfe120141dd32f0592e99d6 Mon Sep 17 00:00:00 2001 From: cepprice Date: Thu, 25 Feb 2021 20:47:46 +0500 Subject: [PATCH 18/29] Show settings only when plugin enabled --- OsmAnd/src/net/osmand/plus/OsmandPlugin.java | 4 +++ .../fragments/RouteParametersFragment.java | 30 ++++++++++++------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java index 90342ff256..d3543a6df1 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java +++ b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java @@ -690,6 +690,10 @@ public abstract class OsmandPlugin { return null; } + public static boolean isPluginEnabled(Class clz) { + return getEnabledPlugin(clz) != null; + } + public static List getCustomDownloadRegions() { List l = new ArrayList<>(); for (OsmandPlugin plugin : getEnabledPlugins()) { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java index a344647573..4ec93b68ef 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteParametersFragment.java @@ -28,9 +28,10 @@ import net.osmand.AndroidUtils; import net.osmand.StateChangedListener; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; -import net.osmand.plus.Version; +import net.osmand.plus.development.OsmandDevelopmentPlugin; import net.osmand.plus.routing.RouteProvider; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.settings.backend.ApplicationMode; @@ -326,17 +327,10 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP setupRouteRecalcHeader(screen); setupSelectRouteRecalcDistance(screen); setupReverseDirectionRecalculation(screen); - addDivider(screen); - setupDevelopmentCategoryHeader(screen); - if (am.isDerivedRoutingFrom(ApplicationMode.PUBLIC_TRANSPORT)) { - setupOsmLiveForPublicTransportPref(); - setupNativePublicTransport(); + + if (OsmandPlugin.isPluginEnabled(OsmandDevelopmentPlugin.class)) { + setupDevelopmentCategoryPreferences(screen, am); } - if (am.isDerivedRoutingFrom(ApplicationMode.CAR)) { - setupOsmLiveForRoutingPref(); - setupDisableComplexRoutingPref(); - } - setupFastRecalculationPref(); } private void setupOtherBooleanParameterSummary(ApplicationMode am, RoutingParameter p, SwitchPreferenceEx switchPreferenceEx) { @@ -380,6 +374,20 @@ public class RouteParametersFragment extends BaseSettingsFragment implements OnP screen.addPreference(routingCategory); } + private void setupDevelopmentCategoryPreferences(PreferenceScreen screen, ApplicationMode am) { + addDivider(screen); + setupDevelopmentCategoryHeader(screen); + if (am.isDerivedRoutingFrom(ApplicationMode.PUBLIC_TRANSPORT)) { + setupOsmLiveForPublicTransportPref(); + setupNativePublicTransport(); + } + if (am.isDerivedRoutingFrom(ApplicationMode.CAR)) { + setupOsmLiveForRoutingPref(); + setupDisableComplexRoutingPref(); + } + setupFastRecalculationPref(); + } + private void setupDevelopmentCategoryHeader(PreferenceScreen screen) { PreferenceCategory developmentCategory = new PreferenceCategory(requireContext()); developmentCategory.setLayoutResource(R.layout.preference_category_with_descr); From 92c6ed4501c5dab25a1b6d90babb2eb5efa3bf42 Mon Sep 17 00:00:00 2001 From: ivanPyrohivskyi Date: Fri, 26 Feb 2021 18:29:07 +0200 Subject: [PATCH 19/29] Fixes --- .../java/net/osmand/router/RouteColorize.java | 150 +++++++++++------- 1 file changed, 93 insertions(+), 57 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java index 9074403176..383d57b7cd 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -20,10 +20,12 @@ public class RouteColorize { public double[][] palette; private List dataList; - private static final String ANSI_RESET = "\u001B[0m"; - private static final String ANSI_RED = "\u001B[31m"; - private static final String ANSI_GREEN = "\u001B[32m"; - public static final String ANSI_YELLOW = "\u001B[33m"; + + public static final int DARK_GREY = -10724260; + public static final int LIGHT_GREY = -3618616; + public static final int RED = -65279; + public static final int GREEN = -1087457024; + public static final int YELLOW = -469770750; public enum ValueType { ELEVATION, @@ -32,6 +34,13 @@ public class RouteColorize { NONE } + private final int VALUE_INDEX = 0; + private final int DECIMAL_COLOR_INDEX = 1;//sRGB decimal format + private final int RED_COLOR_INDEX = 1;//RGB + private final int GREEN_COLOR_INDEX = 2;//RGB + private final int BLUE_COLOR_INDEX = 3;//RGB + private final int ALPHA_COLOR_INDEX = 4;//RGBA + private ValueType valueType; public static int SLOPE_RANGE = 150; @@ -40,7 +49,7 @@ public class RouteColorize { /** * @param minValue can be NaN * @param maxValue can be NaN - * @param palette array {{[color][value]},...}, color in sRGB format + * @param palette array {{value,color},...} - color in sRGB (decimal) format OR {{value,RED,GREEN,BLUE,ALPHA},...} - color in RGBA format */ public RouteColorize(int zoom, double[] latitudes, double[] longitudes, double[] values, double minValue, double maxValue, double[][] palette) { this.zoom = zoom; @@ -59,31 +68,38 @@ public class RouteColorize { } /** - * @param palette array {{[color][value]},...}, color in sRGB format - * @param type ELEVATION, SPEED, SLOPE + * @param type ELEVATION, SPEED, SLOPE */ - public RouteColorize(int zoom, double[][] palette, List wptPtList, ValueType type) { - this.zoom = zoom; - this.palette = palette; + public RouteColorize(int zoom, GPXUtilities.GPXFile gpxFile, ValueType type) { - latitudes = new double[wptPtList.size()]; - longitudes = new double[wptPtList.size()]; - values = new double[wptPtList.size()]; - double[] elevations = new double[wptPtList.size()]; - for (int i = 0; i < wptPtList.size(); i++) { - latitudes[i] = wptPtList.get(i).lat; - longitudes[i] = wptPtList.get(i).lon; - if (type == ValueType.ELEVATION) { - values[i] = wptPtList.get(i).ele; - } else if (type == ValueType.SPEED) { - values[i] = wptPtList.get(i).speed; - } else if (type == ValueType.SLOPE) { - elevations[i] = wptPtList.get(i).ele; + if (!gpxFile.hasTrkPt()) + return; + + List latList = new ArrayList<>(); + List lonList = new ArrayList<>(); + List valList = new ArrayList<>(); + for (GPXUtilities.Track t : gpxFile.tracks) { + for (GPXUtilities.TrkSegment ts : t.segments) { + for (GPXUtilities.WptPt p : ts.points) { + latList.add(p.lat); + lonList.add(p.lon); + if (type == ValueType.SPEED) { + valList.add(p.speed); + } else { + valList.add(p.ele); + } + } } } + this.zoom = zoom; + latitudes = listToArray(latList); + longitudes = listToArray(lonList); + if (type == ValueType.SLOPE) { - values = calculateSlopesByElevations(latitudes, longitudes, elevations, SLOPE_RANGE); + values = calculateSlopesByElevations(latitudes, longitudes, listToArray(valList), SLOPE_RANGE); + } else { + values = listToArray(valList); } calculateMinMaxValue(); @@ -98,7 +114,7 @@ public class RouteColorize { * @param slopeRange - in what range calculate the derivative, usually we used 150 meters * @return slopes array, in the begin and the end present NaN values! */ - public static double[] calculateSlopesByElevations(double[] latitudes, double[] longitudes, double[] elevations, double slopeRange) { + public double[] calculateSlopesByElevations(double[] latitudes, double[] longitudes, double[] elevations, double slopeRange) { double[] newElevations = elevations; for (int i = 2; i < elevations.length - 2; i++) { @@ -113,7 +129,7 @@ public class RouteColorize { double[] slopes = new double[elevations.length]; if (latitudes.length != longitudes.length || latitudes.length != elevations.length) { - System.out.println(ANSI_RED + "Sizes of arrays latitudes, longitudes and values are not match" + ANSI_RESET); + //System.out.println("Sizes of arrays latitudes, longitudes and values are not match"); return slopes; } @@ -153,16 +169,16 @@ public class RouteColorize { public Color getColorByValue(double value) { if (Double.isNaN(value)) { - return getDefaultColor(); + value = (minValue + maxValue) / 2; } for (int i = 0; i < palette.length - 1; i++) { - if (value == palette[i][1]) - return new Color((int) palette[i][0]); - if (value > palette[i][1] && value < palette[i + 1][1]) { - Color minPaletteColor = new Color((int) palette[i][0]); - Color maxPaletteColor = new Color((int) palette[i + 1][0]); - double minPaletteValue = palette[i][1]; - double maxPaletteValue = palette[i + 1][1]; + if (value == palette[i][VALUE_INDEX]) + return new Color((int) palette[i][DECIMAL_COLOR_INDEX]); + if (value >= palette[i][VALUE_INDEX] && value <= palette[i + 1][VALUE_INDEX]) { + Color minPaletteColor = new Color((int) palette[i][DECIMAL_COLOR_INDEX]); + Color maxPaletteColor = new Color((int) palette[i + 1][DECIMAL_COLOR_INDEX]); + double minPaletteValue = palette[i][VALUE_INDEX]; + double maxPaletteValue = palette[i + 1][VALUE_INDEX]; double percent = (value - minPaletteValue) / (maxPaletteValue - minPaletteValue); double resultRed = minPaletteColor.getRed() + percent * (maxPaletteColor.getRed() - minPaletteColor.getRed()); double resultGreen = minPaletteColor.getGreen() + percent * (maxPaletteColor.getGreen() - minPaletteColor.getGreen()); @@ -174,10 +190,13 @@ public class RouteColorize { return getDefaultColor(); } + public void setPalette(double[][] palette) { + this.palette = palette; + checkPalette(); + sortPalette(); + } + private Color getDefaultColor() { - if (valueType != null && valueType == ValueType.SLOPE) { - return new Color(255, 222, 2, 227); - } return new Color(0, 0, 0, 0); } @@ -185,6 +204,7 @@ public class RouteColorize { if (dataList == null) { dataList = new ArrayList<>(); for (int i = 0; i < latitudes.length; i++) { + //System.out.println(latitudes[i] + " " + longitudes[i] + " " + values[i]); dataList.add(new Data(i, latitudes[i], longitudes[i], values[i])); } } @@ -248,47 +268,55 @@ public class RouteColorize { } private void checkPalette() { - if (palette.length < 2 || palette[0].length < 2 || palette[1].length < 2) { - System.out.println(ANSI_YELLOW + "Fill palette in {{[color][value]},...} format. Will use default palette" + ANSI_RESET); + if (palette == null || palette.length < 2 || palette[0].length < 2 || palette[1].length < 2) { + //System.out.println("Fill palette in {{[color][value]},...} format. Will use default palette"); palette = new double[3][2]; - Color red = new Color(255, 1, 1, 255); - Color yellow = new Color(255, 222, 2, 227); - Color green = new Color(46, 185, 0, 191); double[][] defaultPalette = { - { green.getRGB(), minValue}, - { yellow.getRGB(), valueType == ValueType.SLOPE ? 0 : (minValue + maxValue) / 2}, - { red.getRGB(), maxValue} + {minValue, GREEN}, + {valueType == ValueType.SLOPE ? 0 : (minValue + maxValue) / 2, YELLOW}, + {maxValue, RED} }; palette = defaultPalette; } double min; - double max = min = palette[0][1]; + double max = min = palette[0][VALUE_INDEX]; int minIndex = 0; int maxIndex = 0; + double[][] sRGBPalette = new double[palette.length][2]; for (int i = 0; i < palette.length; i++) { double[] p = palette[i]; - if (p[1] > max) { - max = p[1]; + if (p.length == 2) { + sRGBPalette[i] = p; + } else if (p.length == 4) { + Color color = new Color((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], (int) p[BLUE_COLOR_INDEX]); + sRGBPalette[i] = new double[]{p[VALUE_INDEX], color.getRGB()}; + } else if (p.length >= 5) { + Color color = new Color((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], (int) p[BLUE_COLOR_INDEX], (int) p[ALPHA_COLOR_INDEX]); + sRGBPalette[i] = new double[]{p[VALUE_INDEX], color.getRGB()}; + } + if (p[VALUE_INDEX] > max) { + max = p[VALUE_INDEX]; maxIndex = i; } - if (p[1] < min) { - min = p[1]; + if (p[VALUE_INDEX] < min) { + min = p[VALUE_INDEX]; minIndex = i; } } + palette = sRGBPalette; if (minValue < min) { - palette[minIndex][1] = minValue; + palette[minIndex][VALUE_INDEX] = minValue; } if (maxValue > max) { - palette[maxIndex][1] = maxValue; + palette[maxIndex][VALUE_INDEX] = maxValue; } } private void sortPalette() { java.util.Arrays.sort(palette, new java.util.Comparator() { public int compare(double[] a, double[] b) { - return Double.compare(a[1], b[1]); + return Double.compare(a[VALUE_INDEX], b[VALUE_INDEX]); } }); } @@ -296,7 +324,7 @@ public class RouteColorize { /** * @return double[minElevation, maxElevation, minDist, maxDist] */ - private static double[] findDerivativeArguments(double[] distances, double[] elevations, int index, double slopeRange) { + private double[] findDerivativeArguments(double[] distances, double[] elevations, int index, double slopeRange) { double[] result = new double[4]; double minDist = distances[index] - slopeRange / 2; double maxDist = distances[index] + slopeRange / 2; @@ -330,7 +358,7 @@ public class RouteColorize { double diff = distances[closestMaxIndex] - distances[closestMaxIndex - 1]; double coef = (maxDist - distances[closestMaxIndex - 1]) / diff; if (coef > 1 || coef < 0) { - System.out.println(ANSI_RED + "Coefficient fo max must be 0..1 , coef=" + coef + ANSI_RESET); + //System.out.println("Coefficient fo max must be 0..1 , coef=" + coef); } result[1] = (1 - coef) * elevations[closestMaxIndex - 1] + coef * elevations[closestMaxIndex]; } @@ -338,12 +366,12 @@ public class RouteColorize { double diff = distances[closestMinIndex + 1] - distances[closestMinIndex]; double coef = (minDist - distances[closestMinIndex]) / diff; if (coef > 1 || coef < 0) { - System.out.println(ANSI_RED + "Coefficient for min must be 0..1 , coef=" + coef + ANSI_RESET); + //System.out.println("Coefficient for min must be 0..1 , coef=" + coef); } result[0] = (1 - coef) * elevations[closestMinIndex] + coef * elevations[closestMinIndex + 1]; } if (Double.isNaN(result[0]) || Double.isNaN(result[1])) { - System.out.println(ANSI_RED + "Elevations wasn't calculated" + ANSI_RESET); + //System.out.println("Elevations wasn't calculated"); } return result; } @@ -362,6 +390,14 @@ public class RouteColorize { } } + private double[] listToArray(List doubleList) { + double[] result = new double[doubleList.size()]; + for (int i = 0; i < doubleList.size(); i++) { + result[i] = doubleList.get(i); + } + return result; + } + public class Data { int id; public double lat; From 27aab34bf989d6dee21d16fb169ab086ecc94c97 Mon Sep 17 00:00:00 2001 From: ivanPyrohivskyi Date: Fri, 26 Feb 2021 19:09:54 +0200 Subject: [PATCH 20/29] Added rgbaToDecimal converter --- .../java/net/osmand/router/RouteColorize.java | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java index 383d57b7cd..18b5f72f2f 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -1,9 +1,12 @@ package net.osmand.router; import net.osmand.GPXUtilities; +import net.osmand.PlatformUtil; +import net.osmand.binary.BinaryMapAddressReaderAdapter; import net.osmand.osm.edit.Node; import net.osmand.osm.edit.OsmMapUtils; import net.osmand.util.MapUtils; +import org.apache.commons.logging.Log; import java.awt.Color; import java.util.ArrayList; @@ -21,11 +24,13 @@ public class RouteColorize { private List dataList; - public static final int DARK_GREY = -10724260; - public static final int LIGHT_GREY = -3618616; - public static final int RED = -65279; - public static final int GREEN = -1087457024; - public static final int YELLOW = -469770750; + + + public static final int DARK_GREY = rgbaToDecimal(92, 92, 92, 255); + public static final int LIGHT_GREY = rgbaToDecimal(200, 200, 200, 255); + public static final int RED = rgbaToDecimal(255,1,1,255); + public static final int GREEN = rgbaToDecimal(46,185,0,191); + public static final int YELLOW = rgbaToDecimal(255,222,2,227); public enum ValueType { ELEVATION, @@ -45,6 +50,7 @@ public class RouteColorize { public static int SLOPE_RANGE = 150; + private static final Log LOG = PlatformUtil.getLog(RouteColorize.class); /** * @param minValue can be NaN @@ -72,8 +78,10 @@ public class RouteColorize { */ public RouteColorize(int zoom, GPXUtilities.GPXFile gpxFile, ValueType type) { - if (!gpxFile.hasTrkPt()) + if (!gpxFile.hasTrkPt()) { + LOG.warn("GPX file is not consist of track points"); return; + } List latList = new ArrayList<>(); List lonList = new ArrayList<>(); @@ -129,7 +137,7 @@ public class RouteColorize { double[] slopes = new double[elevations.length]; if (latitudes.length != longitudes.length || latitudes.length != elevations.length) { - //System.out.println("Sizes of arrays latitudes, longitudes and values are not match"); + LOG.warn("Sizes of arrays latitudes, longitudes and values are not match"); return slopes; } @@ -269,7 +277,7 @@ public class RouteColorize { private void checkPalette() { if (palette == null || palette.length < 2 || palette[0].length < 2 || palette[1].length < 2) { - //System.out.println("Fill palette in {{[color][value]},...} format. Will use default palette"); + LOG.info("Will use default palette"); palette = new double[3][2]; double[][] defaultPalette = { @@ -358,7 +366,7 @@ public class RouteColorize { double diff = distances[closestMaxIndex] - distances[closestMaxIndex - 1]; double coef = (maxDist - distances[closestMaxIndex - 1]) / diff; if (coef > 1 || coef < 0) { - //System.out.println("Coefficient fo max must be 0..1 , coef=" + coef); + LOG.warn("Coefficient fo max must be 0..1 , coef=" + coef); } result[1] = (1 - coef) * elevations[closestMaxIndex - 1] + coef * elevations[closestMaxIndex]; } @@ -366,12 +374,12 @@ public class RouteColorize { double diff = distances[closestMinIndex + 1] - distances[closestMinIndex]; double coef = (minDist - distances[closestMinIndex]) / diff; if (coef > 1 || coef < 0) { - //System.out.println("Coefficient for min must be 0..1 , coef=" + coef); + LOG.warn("Coefficient for min must be 0..1 , coef=" + coef); } result[0] = (1 - coef) * elevations[closestMinIndex] + coef * elevations[closestMinIndex + 1]; } if (Double.isNaN(result[0]) || Double.isNaN(result[1])) { - //System.out.println("Elevations wasn't calculated"); + LOG.warn("Elevations wasn't calculated"); } return result; } @@ -398,6 +406,14 @@ public class RouteColorize { return result; } + private static int rgbaToDecimal(int r, int g, int b, int a) { + int value = ((a & 0xFF) << 24) | + ((r & 0xFF) << 16) | + ((g & 0xFF) << 8) | + ((b & 0xFF) << 0); + return value; + } + public class Data { int id; public double lat; From 11f1ba5bc2901fbbce29209957ce38b9263d4a7b Mon Sep 17 00:00:00 2001 From: ivanPyrohivskyi Date: Fri, 26 Feb 2021 19:51:36 +0200 Subject: [PATCH 21/29] Removed java.awt.* --- .../java/net/osmand/router/RouteColorize.java | 100 ++++++++++-------- 1 file changed, 58 insertions(+), 42 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java index 18b5f72f2f..6730965d1f 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -2,13 +2,11 @@ package net.osmand.router; import net.osmand.GPXUtilities; import net.osmand.PlatformUtil; -import net.osmand.binary.BinaryMapAddressReaderAdapter; import net.osmand.osm.edit.Node; import net.osmand.osm.edit.OsmMapUtils; import net.osmand.util.MapUtils; import org.apache.commons.logging.Log; -import java.awt.Color; import java.util.ArrayList; import java.util.List; @@ -22,9 +20,7 @@ public class RouteColorize { public double maxValue; public double[][] palette; - private List dataList; - - + private List dataList; public static final int DARK_GREY = rgbaToDecimal(92, 92, 92, 255); public static final int LIGHT_GREY = rgbaToDecimal(200, 200, 200, 255); @@ -48,7 +44,8 @@ public class RouteColorize { private ValueType valueType; - public static int SLOPE_RANGE = 150; + public static int SLOPE_RANGE = 150;//150 meters + private static final double MIN_DIFFERENCE_SLOPE = 0.05d;//5% private static final Log LOG = PlatformUtil.getLog(RouteColorize.class); @@ -160,39 +157,39 @@ public class RouteColorize { return slopes; } - public List getResult(boolean simplify) { - List result = new ArrayList<>(); + public List getResult(boolean simplify) { + List result = new ArrayList<>(); if (simplify) { result = simplify(); } else { for (int i = 0; i < latitudes.length; i++) { - result.add(new Data(i, latitudes[i], longitudes[i], values[i])); + result.add(new RouteColorizationPoint(i, latitudes[i], longitudes[i], values[i])); } } - for (Data data : result) { + for (RouteColorizationPoint data : result) { data.color = getColorByValue(data.val); } return result; } - public Color getColorByValue(double value) { + public int getColorByValue(double value) { if (Double.isNaN(value)) { value = (minValue + maxValue) / 2; } for (int i = 0; i < palette.length - 1; i++) { if (value == palette[i][VALUE_INDEX]) - return new Color((int) palette[i][DECIMAL_COLOR_INDEX]); + return (int) palette[i][DECIMAL_COLOR_INDEX]; if (value >= palette[i][VALUE_INDEX] && value <= palette[i + 1][VALUE_INDEX]) { - Color minPaletteColor = new Color((int) palette[i][DECIMAL_COLOR_INDEX]); - Color maxPaletteColor = new Color((int) palette[i + 1][DECIMAL_COLOR_INDEX]); + int minPaletteColor = (int) palette[i][DECIMAL_COLOR_INDEX]; + int maxPaletteColor = (int) palette[i + 1][DECIMAL_COLOR_INDEX]; double minPaletteValue = palette[i][VALUE_INDEX]; double maxPaletteValue = palette[i + 1][VALUE_INDEX]; double percent = (value - minPaletteValue) / (maxPaletteValue - minPaletteValue); - double resultRed = minPaletteColor.getRed() + percent * (maxPaletteColor.getRed() - minPaletteColor.getRed()); - double resultGreen = minPaletteColor.getGreen() + percent * (maxPaletteColor.getGreen() - minPaletteColor.getGreen()); - double resultBlue = minPaletteColor.getBlue() + percent * (maxPaletteColor.getBlue() - minPaletteColor.getBlue()); - double resultAlpha = minPaletteColor.getAlpha() + percent * (maxPaletteColor.getAlpha() - minPaletteColor.getAlpha()); - return new Color((int) resultRed, (int) resultGreen, (int) resultBlue, (int) resultAlpha); + double resultRed = getRed(minPaletteColor) + percent * (getRed(maxPaletteColor) - getRed(minPaletteColor)); + double resultGreen = getGreen(minPaletteColor) + percent * (getGreen(maxPaletteColor) - getGreen(minPaletteColor)); + double resultBlue = getBlue(minPaletteColor) + percent * (getBlue(maxPaletteColor) - getBlue(minPaletteColor)); + double resultAlpha = getAlpha(minPaletteColor) + percent * (getAlpha(maxPaletteColor) - getAlpha(minPaletteColor)); + return rgbaToDecimal((int) resultRed, (int) resultGreen, (int) resultBlue, (int) resultAlpha); } } return getDefaultColor(); @@ -204,49 +201,52 @@ public class RouteColorize { sortPalette(); } - private Color getDefaultColor() { - return new Color(0, 0, 0, 0); + private int getDefaultColor() { + return rgbaToDecimal(0, 0, 0, 0); } - private List simplify() { + private List simplify() { if (dataList == null) { dataList = new ArrayList<>(); for (int i = 0; i < latitudes.length; i++) { //System.out.println(latitudes[i] + " " + longitudes[i] + " " + values[i]); - dataList.add(new Data(i, latitudes[i], longitudes[i], values[i])); + dataList.add(new RouteColorizationPoint(i, latitudes[i], longitudes[i], values[i])); } } List nodes = new ArrayList<>(); List result = new ArrayList<>(); - for (Data data : dataList) { + for (RouteColorizationPoint data : dataList) { nodes.add(new net.osmand.osm.edit.Node(data.lat, data.lon, data.id)); } OsmMapUtils.simplifyDouglasPeucker(nodes, zoom + 5, 1, result, true); - List simplified = new ArrayList<>(); + List simplified = new ArrayList<>(); for (int i = 1; i < result.size() - 1; i++) { int prevId = (int) result.get(i - 1).getId(); int currentId = (int) result.get(i).getId(); - List sublist = dataList.subList(prevId, currentId); + List sublist = dataList.subList(prevId, currentId); simplified.addAll(getExtremums(sublist)); } return simplified; } - private List getExtremums(List subDataList) { - if (subDataList.size() <= 2) + private List getExtremums(List subDataList) { + if (subDataList.size() <= 2) { return subDataList; + } - List result = new ArrayList<>(); + List result = new ArrayList<>(); double min; double max; min = max = subDataList.get(0).val; - for (Data pt : subDataList) { - if (min > pt.val) + for (RouteColorizationPoint pt : subDataList) { + if (min > pt.val) { min = pt.val; - if (max < pt.val) + } + if (max < pt.val) { max = pt.val; + } } double diff = max - min; @@ -256,15 +256,15 @@ public class RouteColorize { double prev = subDataList.get(i - 1).val; double current = subDataList.get(i).val; double next = subDataList.get(i + 1).val; - Data currentData = subDataList.get(i); + RouteColorizationPoint currentData = subDataList.get(i); if ((current > prev && current > next) || (current < prev && current < next) || (current < prev && current == next) || (current == prev && current < next) || (current > prev && current == next) || (current == prev && current > next)) { - Data prevInResult; + RouteColorizationPoint prevInResult; if (result.size() > 0) { prevInResult = result.get(0); - if (prevInResult.val / diff > 0.05d) {// check differences in 5% + if (prevInResult.val / diff > MIN_DIFFERENCE_SLOPE) { result.add(currentData); } } else @@ -297,11 +297,11 @@ public class RouteColorize { if (p.length == 2) { sRGBPalette[i] = p; } else if (p.length == 4) { - Color color = new Color((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], (int) p[BLUE_COLOR_INDEX]); - sRGBPalette[i] = new double[]{p[VALUE_INDEX], color.getRGB()}; + int color = rgbaToDecimal((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], (int) p[BLUE_COLOR_INDEX], 255); + sRGBPalette[i] = new double[]{p[VALUE_INDEX], color}; } else if (p.length >= 5) { - Color color = new Color((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], (int) p[BLUE_COLOR_INDEX], (int) p[ALPHA_COLOR_INDEX]); - sRGBPalette[i] = new double[]{p[VALUE_INDEX], color.getRGB()}; + int color = rgbaToDecimal((int) p[RED_COLOR_INDEX], (int) p[GREEN_COLOR_INDEX], (int) p[BLUE_COLOR_INDEX], (int) p[ALPHA_COLOR_INDEX]); + sRGBPalette[i] = new double[]{p[VALUE_INDEX], color}; } if (p[VALUE_INDEX] > max) { max = p[VALUE_INDEX]; @@ -414,14 +414,30 @@ public class RouteColorize { return value; } - public class Data { + private int getRed(int value) { + return (value >> 16) & 0xFF; + } + + private int getGreen(int value) { + return (value >> 8) & 0xFF; + } + + private int getBlue(int value) { + return (value >> 0) & 0xFF; + } + + private int getAlpha(int value) { + return (value >> 24) & 0xff; + } + + public static class RouteColorizationPoint { int id; public double lat; public double lon; public double val; - public Color color; + public int color; - Data(int id, double lat, double lon, double val) { + RouteColorizationPoint(int id, double lat, double lon, double val) { this.id = id; this.lat = lat; this.lon = lon; From 793bda10244a7455e1dc8145fa48f101b06cbf9c Mon Sep 17 00:00:00 2001 From: cepprice Date: Sun, 28 Feb 2021 23:35:21 +0500 Subject: [PATCH 22/29] Simplify code --- .../bottomsheets/BooleanPreferenceBottomSheet.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java index b0536fe72b..5eb3dd226c 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java @@ -66,7 +66,7 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet { ? getString(R.string.shared_string_disabled) : summaryOff.toString(); final int activeColor = AndroidUtils.resolveAttribute(themedCtx, R.attr.active_color_basic); final int disabledColor = AndroidUtils.resolveAttribute(themedCtx, android.R.attr.textColorSecondary); - boolean checked = isPreferenceChecked(pref, app); + boolean checked = switchPreference.isChecked(); final BottomSheetItemWithCompoundButton[] preferenceBtn = new BottomSheetItemWithCompoundButton[1]; preferenceBtn[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() @@ -77,7 +77,7 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet { .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - boolean newValue = !isPreferenceChecked(pref, app); + boolean newValue = !switchPreference.isChecked(); Fragment targetFragment = getTargetFragment(); if (targetFragment instanceof OnConfirmPreferenceChange) { ApplyQueryType applyQueryType = getApplyQueryType(); @@ -156,13 +156,6 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet { return (SwitchPreferenceEx) getPreference(); } - private boolean isPreferenceChecked(BooleanPreference preference, OsmandApplication app) { - boolean checked = preference.getModeValue(getAppMode()); - boolean shouldInvertSetting = app.getSettings().DISABLE_COMPLEX_ROUTING.getId() - .equals(preference.getId()); - return checked != shouldInvertSetting; - } - public static void showInstance(@NonNull FragmentManager fm, String prefId, Fragment target, boolean usedOnMap, @Nullable ApplicationMode appMode, ApplyQueryType applyQueryType, boolean profileDependent) { From 718b5a648b2cfe79a01d95957955461c095b75e9 Mon Sep 17 00:00:00 2001 From: cepprice Date: Sun, 28 Feb 2021 23:42:57 +0500 Subject: [PATCH 23/29] Fix IndexOutOfBoundsException --- OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index 86f9654b73..22d24ba792 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -1005,6 +1005,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement } } }); + notifyDataSetChanged(); } public Set getSelectedGpx() { From a2afc8c0a241ff090e6926f937353b6fb6b611f0 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 1 Mar 2021 11:21:08 +0200 Subject: [PATCH 24/29] Added icons: ic_action_update, ic_action_file_report --- OsmAnd/res/drawable/ic_action_file_report.xml | 30 +++++++++++++++++++ OsmAnd/res/drawable/ic_action_update.xml | 12 ++++++++ 2 files changed, 42 insertions(+) create mode 100644 OsmAnd/res/drawable/ic_action_file_report.xml create mode 100644 OsmAnd/res/drawable/ic_action_update.xml diff --git a/OsmAnd/res/drawable/ic_action_file_report.xml b/OsmAnd/res/drawable/ic_action_file_report.xml new file mode 100644 index 0000000000..d2da33d3ca --- /dev/null +++ b/OsmAnd/res/drawable/ic_action_file_report.xml @@ -0,0 +1,30 @@ + + + + + + + diff --git a/OsmAnd/res/drawable/ic_action_update.xml b/OsmAnd/res/drawable/ic_action_update.xml new file mode 100644 index 0000000000..eb6037c6ba --- /dev/null +++ b/OsmAnd/res/drawable/ic_action_update.xml @@ -0,0 +1,12 @@ + + + + From fa353ad87ce7e38954ef8854a91036db70061ccb Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 1 Mar 2021 13:24:30 +0200 Subject: [PATCH 25/29] small fixes --- .../src/main/java/net/osmand/util/Algorithms.java | 15 +++++---------- .../plus/onlinerouting/engine/GpxEngine.java | 2 +- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java index 8954e2d61b..36c0034a26 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java @@ -565,16 +565,11 @@ public class Algorithms { } } - public static ByteArrayInputStream createByteArrayIS(InputStream inputStream) throws IOException { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - int i = 0; - while ((i = inputStream.read()) != -1) { - outputStream.write(i); - } - inputStream.close(); - - byte[] byteArray = outputStream.toByteArray(); - return new ByteArrayInputStream(byteArray); + public static ByteArrayInputStream createByteArrayIS(InputStream in) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + streamCopy(in, out); + in.close(); + return new ByteArrayInputStream(out.toByteArray()); } @SuppressWarnings("ResultOfMethodCallIgnored") diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java index eac4771ba3..736d09611a 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java @@ -95,7 +95,7 @@ public class GpxEngine extends OnlineRoutingEngine { } private GPXFile parseGpx(@NonNull String content) { - InputStream gpxStream = null; + InputStream gpxStream; try { gpxStream = new ByteArrayInputStream(content.getBytes("UTF-8")); return GPXUtilities.loadGPXFile(gpxStream); From 9f0bda924d97c337b39bcbd2f598034fb5a59543 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 1 Mar 2021 14:57:58 +0200 Subject: [PATCH 26/29] Fix possible IllegalStateException --- OsmAnd/src/net/osmand/plus/OsmandPlugin.java | 2 +- OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java index 90342ff256..9775fdd415 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java +++ b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java @@ -468,7 +468,7 @@ public abstract class OsmandPlugin { FragmentManager fm = mapActivity.getSupportFragmentManager(); Fragment fragment = fm.findFragmentByTag(fragmentData.tag); if (fragment != null) { - fm.beginTransaction().remove(fragment).commit(); + fm.beginTransaction().remove(fragment).commitAllowingStateLoss(); } } } diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java index 4afb671275..fc4bb84f0e 100644 --- a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java +++ b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java @@ -1004,7 +1004,7 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo new TransactionBuilder(mapActivity.getSupportFragmentManager(), settings, mapActivity); builder.addFragmentsData(fragmentsData) .addFragmentsData(OsmandPlugin.getPluginsCardsList()) - .getFragmentTransaction().commit(); + .getFragmentTransaction().commitAllowingStateLoss(); } private void removeFragment(String tag) { From 2bc49ea8f89b79ca1d75295cf1d9685c7e35a251 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 1 Mar 2021 16:00:08 +0200 Subject: [PATCH 27/29] Try to fix some npe or IllegalStateException --- OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java | 8 ++++++-- .../src/net/osmand/plus/importfiles/ImportHelper.java | 11 ++++++++--- .../editors/FavoritePointEditorFragmentNew.java | 9 +++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index 3687602716..e82907a9e4 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -417,8 +417,12 @@ public class OsmandAidlApi { } private void registerReceiver(BroadcastReceiver rec, MapActivity ma, String filter) { - receivers.put(filter, rec); - ma.registerReceiver(rec, new IntentFilter(filter)); + try { + receivers.put(filter, rec); + ma.registerReceiver(rec, new IntentFilter(filter)); + } catch (IllegalStateException e) { + LOG.error(e); + } } private void registerRemoveMapWidgetReceiver(MapActivity mapActivity) { diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java index 9279a85ce5..8d9392d09e 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java @@ -6,6 +6,7 @@ import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; +import android.os.AsyncTask.Status; import android.os.Build; import android.os.Bundle; import android.provider.OpenableColumns; @@ -25,6 +26,8 @@ import net.osmand.PlatformUtil; import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint.BackgroundType; import net.osmand.plus.AppInitializer; +import net.osmand.plus.AppInitializer.AppInitializeListener; +import net.osmand.plus.AppInitializer.InitEvents; import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -704,14 +707,16 @@ public class ImportHelper { @SuppressWarnings("unchecked") private

void executeImportTask(final AsyncTask importTask, final P... requests) { if (app.isApplicationInitializing()) { - app.getAppInitializer().addListener(new AppInitializer.AppInitializeListener() { + app.getAppInitializer().addListener(new AppInitializeListener() { @Override - public void onProgress(AppInitializer init, AppInitializer.InitEvents event) { + public void onProgress(AppInitializer init, InitEvents event) { } @Override public void onFinish(AppInitializer init) { - importTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, requests); + if (importTask.getStatus() == Status.PENDING) { + importTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, requests); + } } }); } else { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java index 3e4093d253..d1d60d0d21 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/FavoritePointEditorFragmentNew.java @@ -75,6 +75,9 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew { FavouritesDbHelper helper = getHelper(); if (editor != null && helper != null) { FavouritePoint favorite = editor.getFavorite(); + if (favorite == null && savedInstanceState != null) { + favorite = (FavouritePoint) savedInstanceState.getSerializable(FavoriteDialogs.KEY_FAVORITE); + } this.favorite = favorite; this.group = helper.getGroup(favorite); this.color = favorite.getColor(); @@ -109,6 +112,12 @@ public class FavoritePointEditorFragmentNew extends PointEditorFragmentNew { return view; } + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putSerializable(FavoriteDialogs.KEY_FAVORITE, getFavorite()); + } + private void replacePressed() { Bundle args = new Bundle(); args.putSerializable(FavoriteDialogs.KEY_FAVORITE, getFavorite()); From 4b93539c255e9c9f9b9e5de12c36f0541d3cade3 Mon Sep 17 00:00:00 2001 From: cepprice Date: Mon, 1 Mar 2021 12:28:55 +0500 Subject: [PATCH 28/29] Clean up and refactoring --- OsmAnd/res/layout/preference_colors_card.xml | 12 +++++ OsmAnd/res/xml/profile_appearance.xml | 2 +- OsmAnd/src/net/osmand/aidl/ConnectedApp.java | 6 +-- .../net/osmand/plus/ContextMenuAdapter.java | 39 +++++----------- .../src/net/osmand/plus/ContextMenuItem.java | 45 +++++++------------ .../plus/activities/MapActivityActions.java | 8 ++-- .../plus/activities/MapActivityLayers.java | 2 +- .../audionotes/AudioVideoNotesPlugin.java | 4 +- .../osmand/plus/dialogs/ConfigureMapMenu.java | 19 ++++---- .../plus/dialogs/DetailsBottomSheet.java | 2 +- .../plus/dialogs/MapLayerMenuListener.java | 14 +++--- .../download/ui/LocalIndexesFragment.java | 6 +-- .../plus/mapillary/MapillaryPlugin.java | 4 +- .../osmand/plus/osmedit/OsmEditingPlugin.java | 10 ++--- .../net/osmand/plus/osmedit/OsmNotesMenu.java | 2 +- .../actions/ShowHidePoiAction.java | 1 - .../rastermaps/OsmandRasterMapsPlugin.java | 9 ++-- .../AvoidRoadsBottomSheetDialogFragment.java | 7 --- .../settings/backend/ApplicationMode.java | 12 +---- .../fragments/BaseSettingsFragment.java | 4 +- .../fragments/ProfileAppearanceFragment.java | 12 ++--- .../plus/srtmplugin/ContourLinesMenu.java | 4 +- .../osmand/plus/srtmplugin/SRTMPlugin.java | 9 ++-- .../views/mapwidgets/MapWidgetRegistry.java | 9 ++-- .../plus/wikipedia/WikipediaPlugin.java | 4 +- .../plus/wikipedia/WikipediaPoiMenu.java | 2 +- 26 files changed, 106 insertions(+), 142 deletions(-) create mode 100644 OsmAnd/res/layout/preference_colors_card.xml diff --git a/OsmAnd/res/layout/preference_colors_card.xml b/OsmAnd/res/layout/preference_colors_card.xml new file mode 100644 index 0000000000..97ad948f70 --- /dev/null +++ b/OsmAnd/res/layout/preference_colors_card.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/OsmAnd/res/xml/profile_appearance.xml b/OsmAnd/res/xml/profile_appearance.xml index 53a1fa2a1c..87ec511b69 100644 --- a/OsmAnd/res/xml/profile_appearance.xml +++ b/OsmAnd/res/xml/profile_appearance.xml @@ -26,7 +26,7 @@ diff --git a/OsmAnd/src/net/osmand/aidl/ConnectedApp.java b/OsmAnd/src/net/osmand/aidl/ConnectedApp.java index bbfa4f89b8..b8a467d991 100644 --- a/OsmAnd/src/net/osmand/aidl/ConnectedApp.java +++ b/OsmAnd/src/net/osmand/aidl/ConnectedApp.java @@ -133,7 +133,7 @@ public class ConnectedApp implements Comparable { CompoundButton btn = view.findViewById(R.id.toggle_item); if (btn != null && btn.getVisibility() == View.VISIBLE) { btn.setChecked(!btn.isChecked()); - menuAdapter.getItem(position).setColorRes(btn.isChecked() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + menuAdapter.getItem(position).setColor(app, btn.isChecked() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); return false; } @@ -146,7 +146,7 @@ public class ConnectedApp implements Comparable { if (layersPref.set(isChecked)) { ContextMenuItem item = adapter.getItem(position); if (item != null) { - item.setColorRes(isChecked ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + item.setColor(app, isChecked ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setSelected(isChecked); adapter.notifyDataSetChanged(); } @@ -162,7 +162,7 @@ public class ConnectedApp implements Comparable { .setListener(listener) .setSelected(layersEnabled) .setIcon(R.drawable.ic_extension_dark) - .setColor(layersEnabled ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, layersEnabled ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .createItem()); } diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java index 12eec8af31..5fdea403d3 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java @@ -277,14 +277,7 @@ public class ContextMenuAdapter { } if (layoutId == R.layout.main_menu_drawer_btn_switch_profile || layoutId == R.layout.main_menu_drawer_btn_configure_profile) { - int colorNoAlpha; - if (item.getColor() != null) { - colorNoAlpha = item.getColor(); - } else { - int colorResId = item.getColorRes(); - colorNoAlpha = ContextCompat.getColor(app, colorResId); - } - + int colorNoAlpha = item.getColor(); TextView title = convertView.findViewById(R.id.title); title.setText(item.getTitle()); @@ -310,21 +303,13 @@ public class ContextMenuAdapter { return convertView; } if (layoutId == R.layout.profile_list_item) { - int tag = item.getTag(); - - int colorNoAlpha; - if (item.getColor() != null) { - colorNoAlpha = item.getColor(); - } else { - int colorResId = item.getColorRes(); - colorNoAlpha = ContextCompat.getColor(app, colorResId); - } + int colorNoAlpha = item.getColor(); TextView title = convertView.findViewById(R.id.title); TextView desc = convertView.findViewById(R.id.description); ImageView icon = convertView.findViewById(R.id.icon); title.setText(item.getTitle()); - + convertView.findViewById(R.id.divider_up).setVisibility(View.INVISIBLE); convertView.findViewById(R.id.divider_bottom).setVisibility(View.INVISIBLE); convertView.findViewById(R.id.menu_image).setVisibility(View.GONE); @@ -428,20 +413,18 @@ public class ContextMenuAdapter { } } else { if (item.getIcon() != ContextMenuItem.INVALID_ID) { - int colorRes = item.getColorRes(); + Integer color = item.getColor(); Drawable drawable; - if (profileDependent) { + if (color == null) { + int colorRes = lightTheme ? R.color.icon_color_default_light : R.color.icon_color_default_dark; + colorRes = item.shouldSkipPainting() ? 0 : colorRes; + drawable = mIconsCache.getIcon(item.getIcon(), colorRes); + } else if (profileDependent) { drawable = mIconsCache.getPaintedIcon(item.getIcon(), currentModeColor); } else { - if (colorRes == ContextMenuItem.INVALID_ID) { - if (!item.shouldSkipPainting()) { - colorRes = lightTheme ? R.color.icon_color_default_light : R.color.icon_color_default_dark; - } else { - colorRes = 0; - } - } - drawable = mIconsCache.getIcon(item.getIcon(), colorRes); + drawable = mIconsCache.getPaintedIcon(item.getIcon(), color); } + ((AppCompatImageView) convertView.findViewById(R.id.icon)).setImageDrawable(drawable); convertView.findViewById(R.id.icon).setVisibility(View.VISIBLE); } else if (convertView.findViewById(R.id.icon) != null) { diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuItem.java b/OsmAnd/src/net/osmand/plus/ContextMenuItem.java index a4b846613d..1ab526cbeb 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuItem.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuItem.java @@ -19,8 +19,6 @@ public class ContextMenuItem { private String title; @DrawableRes private int mIcon; - @ColorRes - private int colorRes; @ColorInt private Integer color; @DrawableRes @@ -50,7 +48,6 @@ public class ContextMenuItem { private ContextMenuItem(@StringRes int titleId, String title, @DrawableRes int icon, - @ColorRes int colorRes, @ColorInt Integer color, @DrawableRes int secondaryIcon, Boolean selected, @@ -75,7 +72,6 @@ public class ContextMenuItem { this.titleId = titleId; this.title = title; this.mIcon = icon; - this.colorRes = colorRes; this.color = color; this.secondaryIcon = secondaryIcon; this.selected = selected; @@ -113,28 +109,17 @@ public class ContextMenuItem { return mIcon; } - @ColorRes - public int getColorRes() { - return colorRes; - } - @ColorInt - Integer getColor() { + public Integer getColor() { return color; } - @ColorRes - public int getThemedColorRes(Context context) { - if (skipPaintingWithoutColor || getColorRes() != INVALID_ID) { - return getColorRes(); - } else { - return UiUtilities.getDefaultColorRes(context); - } - } - @ColorInt public int getThemedColor(Context context) { - return ContextCompat.getColor(context, getThemedColorRes(context)); + if (skipPaintingWithoutColor || color != null) { + return color; + } + return ContextCompat.getColor(context, UiUtilities.getDefaultColorRes(context)); } @DrawableRes @@ -221,8 +206,10 @@ public class ContextMenuItem { this.secondaryIcon = secondaryIcon; } - public void setColorRes(int colorRes) { - this.colorRes = colorRes; + public void setColor(Context context, @ColorRes int colorRes) { + if (colorRes != INVALID_ID) { + this.color = ContextCompat.getColor(context, colorRes); + } } public void setSelected(boolean selected) { @@ -277,8 +264,6 @@ public class ContextMenuItem { private String mTitle; @DrawableRes private int mIcon = INVALID_ID; - @ColorRes - private int mColorRes = INVALID_ID; @ColorInt private Integer mColor = null; @DrawableRes @@ -318,13 +303,15 @@ public class ContextMenuItem { return this; } - public ItemBuilder setColor(@ColorRes int colorRes) { - mColorRes = colorRes; + public ItemBuilder setColor(@ColorInt Integer color) { + mColor = color; return this; } - public ItemBuilder setColorInt(@ColorInt int color) { - mColor = color; + public ItemBuilder setColor(Context context, @ColorRes int colorRes) { + if (colorRes != INVALID_ID) { + mColor = ContextCompat.getColor(context, colorRes); + } return this; } @@ -438,7 +425,7 @@ public class ContextMenuItem { } public ContextMenuItem createItem() { - ContextMenuItem item = new ContextMenuItem(mTitleId, mTitle, mIcon, mColorRes, mColor, mSecondaryIcon, + ContextMenuItem item = new ContextMenuItem(mTitleId, mTitle, mIcon, mColor, mSecondaryIcon, mSelected, mProgress, mLayout, mLoading, mIsCategory, mIsClickable, mSkipPaintingWithoutColor, mOrder, mDescription, mOnUpdateCallback, mItemClickListener, mIntegerListener, mProgressListener, mItemDeleteAction, mHideDivider, mHideCompoundButton, mMinHeight, mTag, mId); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index acc557ed09..a0835dbf01 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -749,7 +749,7 @@ public class MapActivityActions implements DialogProvider { optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.profile_list_item) .setIcon(appMode.getIconRes()) - .setColorInt(appMode.getProfileColor(nightMode)) + .setColor(appMode.getProfileColor(nightMode)) .setTag(tag) .setTitle(appMode.toHumanString()) .setDescription(modeDescription) @@ -766,7 +766,7 @@ public class MapActivityActions implements DialogProvider { int activeColorPrimaryResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.profile_list_item) - .setColor(activeColorPrimaryResId) + .setColor(app, activeColorPrimaryResId) .setTag(PROFILES_CONTROL_BUTTON_TAG) .setTitle(getString(R.string.shared_string_manage)) .setListener(new ItemClickListener() { @@ -1059,7 +1059,7 @@ public class MapActivityActions implements DialogProvider { .setId(DRAWER_SWITCH_PROFILE_ID) .setIcon(currentMode.getIconRes()) .setSecondaryIcon(icArrowResId) - .setColorInt(currentMode.getProfileColor(nightMode)) + .setColor(currentMode.getProfileColor(nightMode)) .setTitle(currentMode.toHumanString()) .setDescription(modeDescription) .setListener(new ItemClickListener() { @@ -1073,7 +1073,7 @@ public class MapActivityActions implements DialogProvider { .createItem()); optionsMenuHelper.addItem(new ItemBuilder().setLayout(R.layout.main_menu_drawer_btn_configure_profile) .setId(DRAWER_CONFIGURE_PROFILE_ID) - .setColorInt(currentMode.getProfileColor(nightMode)) + .setColor(currentMode.getProfileColor(nightMode)) .setTitle(getString(R.string.configure_profile)) .setListener(new ItemClickListener() { @Override diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java index ce2f1f95bf..49a4bc545f 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java @@ -432,7 +432,7 @@ public class MapActivityLayers { } else { builder.setIcon(R.drawable.mx_user_defined); } - builder.setColor(ContextMenuItem.INVALID_ID); + builder.setColor(activity, ContextMenuItem.INVALID_ID); builder.setSkipPaintingWithoutColor(true); adapter.addItem(builder.createItem()); } diff --git a/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java b/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java index b7f15624b4..6d425ef65e 100644 --- a/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java +++ b/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java @@ -678,7 +678,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin { public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { if (itemId == R.string.layer_recordings) { SHOW_RECORDINGS.set(!SHOW_RECORDINGS.get()); - adapter.getItem(pos).setColorRes(SHOW_RECORDINGS.get() ? + adapter.getItem(pos).setColor(app, SHOW_RECORDINGS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); updateLayers(mapView, mapActivity); @@ -690,7 +690,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin { .setId(RECORDING_LAYER) .setSelected(SHOW_RECORDINGS.get()) .setIcon(R.drawable.ic_action_micro_dark) - .setColor(SHOW_RECORDINGS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(mapActivity, SHOW_RECORDINGS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setItemDeleteAction(makeDeleteAction(SHOW_RECORDINGS)) .setListener(listener).createItem()); } diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java index 1ae5e49e43..5a69f5b2cd 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/ConfigureMapMenu.java @@ -184,7 +184,7 @@ public class ConfigureMapMenu { .setId(FAVORITES_ID) .setTitleId(R.string.shared_string_favorites, activity) .setSelected(settings.SHOW_FAVORITES.get()) - .setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setIcon(R.drawable.ic_action_favorite) .setItemDeleteAction(makeDeleteAction(settings.SHOW_FAVORITES)) .setListener(l) @@ -196,7 +196,7 @@ public class ConfigureMapMenu { .setTitleId(R.string.layer_poi, activity) .setSelected(selected) .setDescription(app.getPoiFilters().getSelectedPoiFiltersName(wiki)) - .setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setIcon(R.drawable.ic_action_info_dark) .setSecondaryIcon(R.drawable.ic_action_additional_option) .setListener(l).createItem()); @@ -205,7 +205,7 @@ public class ConfigureMapMenu { .setId(POI_OVERLAY_LABELS_ID) .setTitleId(R.string.layer_amenity_label, activity) .setSelected(settings.SHOW_POI_LABEL.get()) - .setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setIcon(R.drawable.ic_action_text_dark) .setItemDeleteAction(makeDeleteAction(settings.SHOW_POI_LABEL)) .setListener(l).createItem()); @@ -217,7 +217,7 @@ public class ConfigureMapMenu { .setIcon(R.drawable.ic_action_transport_bus) .setSecondaryIcon(R.drawable.ic_action_additional_option) .setSelected(selected) - .setColor(selected ? selectedProfileColor : ContextMenuItem.INVALID_ID) + .setColor(selected ? selectedProfileColor : null) .setListener(l).createItem()); selected = app.getSelectedGpxHelper().isShowingAnyGpxFiles(); @@ -226,7 +226,7 @@ public class ConfigureMapMenu { .setTitleId(R.string.layer_gpx_layer, activity) .setSelected(app.getSelectedGpxHelper().isShowingAnyGpxFiles()) .setDescription(app.getSelectedGpxHelper().getGpxDescription()) - .setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setIcon(R.drawable.ic_action_polygom_dark) .setSecondaryIcon(R.drawable.ic_action_additional_option) .setListener(l).createItem()); @@ -236,7 +236,7 @@ public class ConfigureMapMenu { .setId(MAP_MARKERS_ID) .setTitleId(R.string.map_markers, activity) .setSelected(selected) - .setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setIcon(R.drawable.ic_action_flag) .setItemDeleteAction(makeDeleteAction(settings.SHOW_MAP_MARKERS)) .setListener(l).createItem()); @@ -704,7 +704,6 @@ public class ConfigureMapMenu { for (int i = 0; i < prefs.size(); i++) { prefs.get(i).set(false); } - adapter.getItem(pos).setColorRes(ContextMenuItem.INVALID_ID); a.notifyDataSetInvalidated(); activity.refreshMapComplete(); activity.getMapLayers().updateLayers(activity.getMapView()); @@ -738,7 +737,7 @@ public class ConfigureMapMenu { } } } - builder.setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + builder.setColor(activity, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); if (useDescription) { final String descr = getDescription(prefs, includedPrefs); builder.setDescription(descr); @@ -839,7 +838,7 @@ public class ConfigureMapMenu { selected |= prefs.get(i).get(); } adapter.getItem(pos).setSelected(selected); - adapter.getItem(pos).setColorRes(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + adapter.getItem(pos).setColor(activity, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); a.notifyDataSetInvalidated(); } }); @@ -874,7 +873,7 @@ public class ConfigureMapMenu { } else { adapter.getItem(pos).setSelected(selected); } - adapter.getItem(pos).setColorRes(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + adapter.getItem(pos).setColor(activity, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); } a.notifyDataSetInvalidated(); activity.refreshMapComplete(); diff --git a/OsmAnd/src/net/osmand/plus/dialogs/DetailsBottomSheet.java b/OsmAnd/src/net/osmand/plus/dialogs/DetailsBottomSheet.java index b80acfedb0..fbfc5e6fc6 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/DetailsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/DetailsBottomSheet.java @@ -217,7 +217,7 @@ public class DetailsBottomSheet extends BasePreferenceBottomSheet { } if (adapter != null) { adapter.getItem(position).setSelected(checked); - adapter.getItem(position).setColorRes(checked ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + adapter.getItem(position).setColor(app, checked ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.getItem(position).setDescription(getString( R.string.ltr_or_rtl_combine_via_slash, String.valueOf(selected), diff --git a/OsmAnd/src/net/osmand/plus/dialogs/MapLayerMenuListener.java b/OsmAnd/src/net/osmand/plus/dialogs/MapLayerMenuListener.java index 29a64bcee4..d3f6fc053d 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/MapLayerMenuListener.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/MapLayerMenuListener.java @@ -77,7 +77,7 @@ final class MapLayerMenuListener extends OnRowItemClick { public boolean processResult(Boolean result) { if (item != null) { item.setSelected(result); - item.setColorRes(result ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + item.setColor(mapActivity, result ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); } return true; @@ -86,7 +86,7 @@ final class MapLayerMenuListener extends OnRowItemClick { boolean selected = TransportLinesMenu.isShowLines(mapActivity.getMyApplication()); if (!selected && item != null) { item.setSelected(true); - item.setColorRes(R.color.osmand_orange); + item.setColor(mapActivity, R.color.osmand_orange); adapter.notifyDataSetChanged(); } return false; @@ -94,7 +94,7 @@ final class MapLayerMenuListener extends OnRowItemClick { CompoundButton btn = (CompoundButton) view.findViewById(R.id.toggle_item); if (btn != null && btn.getVisibility() == View.VISIBLE) { btn.setChecked(!btn.isChecked()); - menuAdapter.getItem(pos).setColorRes(btn.isChecked() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + menuAdapter.getItem(pos).setColor(mapActivity, btn.isChecked() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); return false; } else { @@ -110,7 +110,7 @@ final class MapLayerMenuListener extends OnRowItemClick { final PoiFiltersHelper poiFiltersHelper = mapActivity.getMyApplication().getPoiFilters(); final ContextMenuItem item = menuAdapter.getItem(pos); if (item.getSelected() != null) { - item.setColorRes(isChecked ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + item.setColor(mapActivity, isChecked ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); } if (itemId == R.string.layer_poi) { PoiUIFilter wiki = poiFiltersHelper.getTopWikiPoiFilter(); @@ -139,7 +139,7 @@ final class MapLayerMenuListener extends OnRowItemClick { @Override public boolean processResult(Boolean result) { item.setSelected(result); - item.setColorRes(result ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + item.setColor(mapActivity, result ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); return true; } @@ -171,7 +171,7 @@ final class MapLayerMenuListener extends OnRowItemClick { boolean selected = app.getSelectedGpxHelper().isShowingAnyGpxFiles(); item.setSelected(selected); item.setDescription(app.getSelectedGpxHelper().getGpxDescription()); - item.setColorRes(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + item.setColor(mapActivity, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); } }); @@ -189,7 +189,7 @@ final class MapLayerMenuListener extends OnRowItemClick { boolean selected = pf.isShowingAnyPoi(wiki); item.setSelected(selected); item.setDescription(pf.getSelectedPoiFiltersName(wiki)); - item.setColorRes(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + item.setColor(mapActivity, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); } }; diff --git a/OsmAnd/src/net/osmand/plus/download/ui/LocalIndexesFragment.java b/OsmAnd/src/net/osmand/plus/download/ui/LocalIndexesFragment.java index 3081c0680b..3b259ab241 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/LocalIndexesFragment.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/LocalIndexesFragment.java @@ -516,13 +516,13 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement .setTitleId(R.string.shared_string_refresh, getContext()) .setIcon(R.drawable.ic_action_refresh_dark) .setListener(listener) - .setColor(iconColorResId) + .setColor(getContext(), iconColorResId) .createItem()); optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder() .setTitleId(R.string.shared_string_delete, getContext()) .setIcon(R.drawable.ic_action_delete_dark) .setListener(listener) - .setColor(iconColorResId) + .setColor(getContext(), iconColorResId) .createItem()); optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder() .setTitleId(R.string.local_index_mi_backup, getContext()) @@ -554,7 +554,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); } if (contextMenuItem.getIcon() != -1) { - Drawable icMenuItem = getMyApplication().getUIUtilities().getIcon(contextMenuItem.getIcon(), contextMenuItem.getColorRes()); + Drawable icMenuItem = getMyApplication().getUIUtilities().getPaintedIcon(contextMenuItem.getIcon(), contextMenuItem.getColor()); item.setIcon(icMenuItem); } diff --git a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryPlugin.java b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryPlugin.java index bc2b0dbc95..4be50700cc 100644 --- a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryPlugin.java +++ b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryPlugin.java @@ -185,7 +185,7 @@ public class MapillaryPlugin extends OsmandPlugin { ContextMenuItem item = adapter.getItem(pos); if (item != null) { item.setSelected(settings.SHOW_MAPILLARY.get()); - item.setColorRes(settings.SHOW_MAPILLARY.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + item.setColor(app, settings.SHOW_MAPILLARY.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); } } @@ -201,7 +201,7 @@ public class MapillaryPlugin extends OsmandPlugin { .setTitleId(R.string.street_level_imagery, mapActivity) .setDescription("Mapillary") .setSelected(settings.SHOW_MAPILLARY.get()) - .setColor(settings.SHOW_MAPILLARY.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, settings.SHOW_MAPILLARY.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setIcon(R.drawable.ic_action_mapillary) .setSecondaryIcon(R.drawable.ic_action_additional_option) .setItemDeleteAction(makeDeleteAction(settings.SHOW_MAPILLARY)) diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java index 4f25b58761..731129e915 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditingPlugin.java @@ -324,7 +324,7 @@ public class OsmEditingPlugin extends OsmandPlugin { .setTitleId(R.string.layer_osm_bugs, mapActivity) .setSelected(settings.SHOW_OSM_BUGS.get()) .setIcon(R.drawable.ic_action_osm_note) - .setColor(settings.SHOW_OSM_BUGS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, settings.SHOW_OSM_BUGS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setSecondaryIcon(R.drawable.ic_action_additional_option) .setListener(new ContextMenuAdapter.OnRowItemClick() { @@ -343,7 +343,7 @@ public class OsmEditingPlugin extends OsmandPlugin { if (itemId == R.string.layer_osm_bugs) { OsmandPreference showOsmBugs = settings.SHOW_OSM_BUGS; showOsmBugs.set(isChecked); - adapter.getItem(pos).setColorRes(showOsmBugs.get() ? + adapter.getItem(pos).setColor(app, showOsmBugs.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); updateLayers(mapActivity.getMapView(), mapActivity); @@ -359,14 +359,14 @@ public class OsmEditingPlugin extends OsmandPlugin { .setTitleId(R.string.layer_osm_edits, mapActivity) .setSelected(settings.SHOW_OSM_EDITS.get()) .setIcon(R.drawable.ic_action_openstreetmap_logo) - .setColor(settings.SHOW_OSM_EDITS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, settings.SHOW_OSM_EDITS.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setListener(new ContextMenuAdapter.OnRowItemClick() { @Override public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { if (itemId == R.string.layer_osm_edits) { OsmandPreference showOsmEdits = settings.SHOW_OSM_EDITS; showOsmEdits.set(isChecked); - adapter.getItem(pos).setColorRes(showOsmEdits.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + adapter.getItem(pos).setColor(app, showOsmEdits.get() ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); updateLayers(mapActivity.getMapView(), mapActivity); } @@ -404,7 +404,7 @@ public class OsmEditingPlugin extends OsmandPlugin { final AvailableGPXFragment f = ((AvailableGPXFragment) fragment); optionsMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.local_index_mi_upload_gpx, activity) .setIcon(R.drawable.ic_action_export) - .setColor(R.color.color_white) + .setColor(app, R.color.color_white) .setListener(new ItemClickListener() { @Override diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java index 0279955801..f521eba6b1 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmNotesMenu.java @@ -110,7 +110,7 @@ public class OsmNotesMenu { .setTitleId(osmNotesStringId, mapActivity) .setDescription(mapActivity.getString(R.string.switch_osm_notes_visibility_desc)) .setIcon(R.drawable.ic_action_osm_note) - .setColor(toggleIconColorId) + .setColor(app, toggleIconColorId) .setListener(l) .setSelected(showOsmBugs) .createItem()); diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/ShowHidePoiAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/ShowHidePoiAction.java index 4c2d452e64..51b9b300ed 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/ShowHidePoiAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/ShowHidePoiAction.java @@ -353,7 +353,6 @@ public class ShowHidePoiAction extends QuickAction { builder.setIcon(R.drawable.mx_user_defined); } - builder.setColor(ContextMenuItem.INVALID_ID); builder.setSkipPaintingWithoutColor(true); adapter.addItem(builder.createItem()); } diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java b/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java index e902e66791..b04e0d5891 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java @@ -13,7 +13,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; -import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; @@ -323,7 +322,7 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin { : mapActivity.getString(R.string.shared_string_none); item.setDescription(overlayMapDescr); item.setSelected(hasOverlayDescription); - item.setColorRes(hasOverlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + item.setColor(app, hasOverlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); } } @@ -348,7 +347,7 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin { item.setDescription(underlayMapDescr); item.setSelected(hasUnderlayDescription); - item.setColorRes(hasUnderlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + item.setColor(app, hasUnderlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); @@ -381,7 +380,7 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin { .setId(OVERLAY_MAP) .setDescription(overlayMapDescr) .setSelected(hasOverlayDescription) - .setColor(hasOverlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, hasOverlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setIcon(R.drawable.ic_layer_top) .setSecondaryIcon(R.drawable.ic_action_additional_option) .setListener(listener) @@ -397,7 +396,7 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin { .setId(UNDERLAY_MAP) .setDescription(underlayMapDescr) .setSelected(hasUnderlayDescription) - .setColor(hasUnderlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, hasUnderlayDescription ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setIcon(R.drawable.ic_layer_bottom) .setSecondaryIcon(R.drawable.ic_action_additional_option) .setListener(listener) diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/AvoidRoadsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/AvoidRoadsBottomSheetDialogFragment.java index 447e011c2d..41147171c5 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/AvoidRoadsBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/AvoidRoadsBottomSheetDialogFragment.java @@ -65,8 +65,6 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr private List compoundButtons = new ArrayList<>(); private boolean hideImpassableRoads; - @ColorRes - private int compoundButtonColorId = INVALID_ID; @ColorInt private Integer compoundButtonColor = null; private ApplicationMode appMode; @@ -239,7 +237,6 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr final BottomSheetItemWithCompoundButton[] item = new BottomSheetItemWithCompoundButton[1]; item[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder() - .setCompoundButtonColorId(compoundButtonColorId) .setCompoundButtonColor(compoundButtonColor) .setChecked(selected) .setTitle(parameterName) @@ -258,10 +255,6 @@ public class AvoidRoadsBottomSheetDialogFragment extends MenuBottomSheetDialogFr } } - public void setCompoundButtonColorId(@ColorRes int compoundButtonColorId) { - this.compoundButtonColorId = compoundButtonColorId; - } - public void setCompoundButtonColor(@ColorInt int compoundButtonColor) { this.compoundButtonColor = compoundButtonColor; } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java index 3493a0768a..f2e5992f25 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java @@ -500,11 +500,11 @@ public class ApplicationMode { public Integer getCustomIconColor() { String customColor = app.getSettings().CUSTOM_ICON_COLOR.getModeValue(this); - return customColor == null ? null : Integer.valueOf(customColor); + return customColor == null ? null : Algorithms.parseColor(customColor); } public void setCustomIconColor(Integer customIconColor) { - String valueToSave = customIconColor == null ? null : String.valueOf(customIconColor); + String valueToSave = customIconColor == null ? null : Algorithms.colorToString(customIconColor); app.getSettings().CUSTOM_ICON_COLOR.setModeValue(this, valueToSave); } @@ -605,7 +605,6 @@ public class ApplicationMode { mode.setRoutingProfile(builder.routingProfile); mode.setRouteService(builder.routeService); mode.setIconColor(builder.iconColor); - mode.setCustomIconColors(builder.customIconColors); mode.setCustomIconColor(builder.customIconColor); mode.setLocationIcon(builder.locationIcon); mode.setNavigationIcon(builder.navigationIcon); @@ -726,7 +725,6 @@ public class ApplicationMode { private String routingProfile; private String iconResName; private ProfileIconColors iconColor; - private List customIconColors; private Integer customIconColor; private LocationIcon locationIcon; private NavigationIcon navigationIcon; @@ -751,7 +749,6 @@ public class ApplicationMode { applicationMode.setRouteService(routeService); applicationMode.setRoutingProfile(routingProfile); applicationMode.setIconResName(iconResName); - applicationMode.setCustomIconColors(customIconColors); applicationMode.setCustomIconColor(customIconColor); applicationMode.setIconColor(iconColor); applicationMode.setLocationIcon(locationIcon); @@ -801,11 +798,6 @@ public class ApplicationMode { return this; } - public ApplicationModeBuilder setCustomIconColors(List customIconColors) { - this.customIconColors = customIconColors; - return this; - } - public ApplicationModeBuilder setCustomIconColor(Integer customIconColor) { this.customIconColor = customIconColor; return this; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java index a583940068..e6d39cade8 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java @@ -682,7 +682,7 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl protected int getActiveProfileColor() { return isProfileDependent() ? getSelectedAppMode().getProfileColor(isNightMode()) : - ContextCompat.getColor(app, R.color.icon_color_active_light); + ContextCompat.getColor(app, nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light); } @ColorRes @@ -826,7 +826,7 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl Drawable icon = AndroidUtils.createEnabledStateListDrawable(disabled, enabled); if (Build.VERSION.SDK_INT < 21) { - int defaultColor = ContextCompat.getColor(app, R.color.icon_color_default_light); + int defaultColor = ContextCompat.getColor(app, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light); ColorStateList colorStateList = AndroidUtils.createEnabledColorIntStateList(defaultColor, getActiveProfileColor()); icon = DrawableCompat.wrap(icon); DrawableCompat.setTintList(icon, colorStateList); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java index 49fe22be21..32136b8c09 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java @@ -38,12 +38,13 @@ import net.osmand.plus.profiles.SelectProfileBottomSheet; import net.osmand.plus.profiles.SelectProfileBottomSheet.DialogMode; import net.osmand.plus.profiles.SelectProfileBottomSheet.OnSelectProfileCallback; import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener; import net.osmand.plus.routing.RouteProvider; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.backup.ProfileSettingsItem; import net.osmand.plus.settings.backend.backup.SettingsHelper; import net.osmand.plus.track.ColorsCard; -import net.osmand.plus.track.CustomColorBottomSheet; +import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener; import net.osmand.plus.widgets.FlowLayout; import net.osmand.plus.widgets.OsmandTextFieldBoxes; import net.osmand.util.Algorithms; @@ -74,7 +75,7 @@ import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SETTINGS_ID import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILES_LIST_UPDATED_ARG; import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILE_KEY_ARG; -public class ProfileAppearanceFragment extends BaseSettingsFragment implements OnSelectProfileCallback, BaseCard.CardListener, CustomColorBottomSheet.ColorPickerListener { +public class ProfileAppearanceFragment extends BaseSettingsFragment implements OnSelectProfileCallback, CardListener, ColorPickerListener { private static final Log LOG = PlatformUtil.getLog(ProfileAppearanceFragment.class); @@ -475,7 +476,9 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O if (mapActivity == null) { return; } - ViewGroup parentView = (ViewGroup) holder.itemView; + FlowLayout colorsCardContainer = (FlowLayout) holder.findViewById(R.id.color_items); + colorsCardContainer.removeAllViews(); + int selectedColor = changedProfile.getActualColor(); List colors = new ArrayList<>(); for (ProfileIconColors color : ProfileIconColors.values()) { @@ -483,8 +486,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O } colorsCard = new ColorsCard(mapActivity, selectedColor, this, colors, app.getSettings().CUSTOM_ICON_COLORS, getSelectedAppMode()); colorsCard.setListener(this); - parentView.removeAllViews(); - parentView.addView(colorsCard.build(app)); + colorsCardContainer.addView(colorsCard.build(app)); updateColorName(); } diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/ContourLinesMenu.java b/OsmAnd/src/net/osmand/plus/srtmplugin/ContourLinesMenu.java index 86abdee880..0b4f6d831c 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/ContourLinesMenu.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/ContourLinesMenu.java @@ -184,7 +184,7 @@ public class ContourLinesMenu { contextMenuAdapter.addItem(new ContextMenuItem.ItemBuilder() .setTitleId(toggleActionStringId, mapActivity) .setIcon(toggleIconId) - .setColor(toggleIconColorId) + .setColor(app, toggleIconColorId) .setListener(l) .setSelected(selected).createItem()); if (selected) { @@ -225,7 +225,7 @@ public class ContourLinesMenu { .setTitleId(R.string.srtm_plugin_name, mapActivity) .setLayout(R.layout.list_item_icon_and_right_btn) .setIcon(R.drawable.ic_plugin_srtm) - .setColor(R.color.osmand_orange) + .setColor(app, R.color.osmand_orange) .setDescription(app.getString(R.string.shared_string_plugin)) .setListener(l).createItem()); } else { diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java index c44d0a8c5b..bf070b158a 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java @@ -10,7 +10,6 @@ import android.widget.ArrayAdapter; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; -import androidx.core.content.ContextCompat; import net.osmand.AndroidUtils; import net.osmand.data.LatLon; @@ -303,7 +302,7 @@ public class SRTMPlugin extends OsmandPlugin { if (item != null) { item.setDescription(app.getString(R.string.display_zoom_level, getPrefDescription(app, contourLinesProp, pref))); - item.setColorRes(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + item.setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setSelected(selected); adapter.notifyDataSetChanged(); } @@ -322,7 +321,7 @@ public class SRTMPlugin extends OsmandPlugin { } ContextMenuItem item = adapter.getItem(position); if (item != null) { - item.setColorRes(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + item.setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setSelected(selected); adapter.notifyDataSetChanged(); } @@ -346,7 +345,7 @@ public class SRTMPlugin extends OsmandPlugin { .setSelected(contourLinesSelected) .setIcon(R.drawable.ic_plugin_srtm) .setDescription(app.getString(R.string.display_zoom_level, descr)) - .setColor(contourLinesSelected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, contourLinesSelected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setItemDeleteAction(makeDeleteAction(settings.CONTOUR_LINES_ZOOM)) .setSecondaryIcon(R.drawable.ic_action_additional_option) .setListener(listener).createItem()); @@ -360,7 +359,7 @@ public class SRTMPlugin extends OsmandPlugin { ? R.string.shared_string_hillshade : R.string.download_slope_maps)) .setSelected(terrainEnabled) - .setColor(terrainEnabled ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, terrainEnabled ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setIcon(R.drawable.ic_action_hillshade_dark) .setSecondaryIcon(R.drawable.ic_action_additional_option) .setItemDeleteAction(makeDeleteAction(settings.TERRAIN, settings.TERRAIN_MODE)) diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapWidgetRegistry.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapWidgetRegistry.java index 39cab96543..47546a3c01 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapWidgetRegistry.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapWidgetRegistry.java @@ -9,7 +9,6 @@ import android.widget.LinearLayout; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.StringRes; -import androidx.core.content.ContextCompat; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.ContextMenuAdapter; @@ -461,7 +460,7 @@ public class MapWidgetRegistry { .setTitleId(R.string.configure_screen_quick_action, mapActivity) .setIcon(R.drawable.ic_quick_action) .setSelected(selected) - .setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setSecondaryIcon( R.drawable.ic_action_additional_option) .setListener(new ContextMenuAdapter.OnRowItemClick() { @Override @@ -497,7 +496,7 @@ public class MapWidgetRegistry { } ContextMenuItem item = adapter.getItem(position); item.setSelected(visible); - item.setColorRes(visible ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + item.setColor(app, visible ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); adapter.notifyDataSetChanged(); } @@ -519,7 +518,7 @@ public class MapWidgetRegistry { ContextMenuItem.ItemBuilder itemBuilder = new ContextMenuItem.ItemBuilder() .setIcon(r.getDrawableMenu()) .setSelected(selected) - .setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setSecondaryIcon(r.widget != null ? R.drawable.ic_action_additional_option : ContextMenuItem.INVALID_ID) .setDescription(r.visibleCollapsed(mode) ? desc : null) .setListener(new ContextMenuAdapter.OnRowItemClick() { @@ -638,7 +637,7 @@ public class MapWidgetRegistry { } ContextMenuItem item = adapter.getItem(position); item.setSelected(visible); - item.setColorRes(visible ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); + item.setColor(app, visible ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setDescription(visible && collapsed ? desc : null); adapter.notifyDataSetChanged(); } diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPlugin.java b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPlugin.java index 1b97f6df1c..f08f02966e 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPlugin.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPlugin.java @@ -141,7 +141,7 @@ public class WikipediaPlugin extends OsmandPlugin { ContextMenuItem item = adapter.getItem(pos); if (item != null) { item.setSelected(selected); - item.setColorRes(selected ? + item.setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); item.setDescription(selected ? getLanguagesSummary() : null); adapter.notifyDataSetChanged(); @@ -160,7 +160,7 @@ public class WikipediaPlugin extends OsmandPlugin { .setTitleId(R.string.shared_string_wikipedia, mapActivity) .setDescription(selected ? getLanguagesSummary() : null) .setSelected(selected) - .setColor(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) + .setColor(app, selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) .setIcon(R.drawable.ic_plugin_wikipedia) .setSecondaryIcon(R.drawable.ic_action_additional_option) .setListener(listener).createItem()); diff --git a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPoiMenu.java b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPoiMenu.java index 28c2639a35..a2cb6b5b71 100644 --- a/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPoiMenu.java +++ b/OsmAnd/src/net/osmand/plus/wikipedia/WikipediaPoiMenu.java @@ -74,7 +74,7 @@ public class WikipediaPoiMenu { .setTitleId(toggleActionStringId, mapActivity) .setDescription(summary) .setIcon(toggleIconId) - .setColor(toggleIconColorId) + .setColor(app, toggleIconColorId) .setListener(l) .setSelected(enabled).createItem()); From c092551bda8cc212bc0a921e9798be964c5fc5b0 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 2 Mar 2021 00:13:49 +0200 Subject: [PATCH 29/29] Small fix --- .../plus/settings/backend/ApplicationMode.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java index 319cab0eca..f707f82f88 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/ApplicationMode.java @@ -1,5 +1,9 @@ package net.osmand.plus.settings.backend; +import androidx.annotation.ColorInt; +import androidx.annotation.DrawableRes; +import androidx.core.content.ContextCompat; + import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.annotations.Expose; @@ -26,10 +30,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import androidx.annotation.ColorInt; -import androidx.annotation.DrawableRes; -import androidx.core.content.ContextCompat; - import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_ALTITUDE; import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_BATTERY; import static net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WIDGET_BEARING; @@ -505,8 +505,12 @@ public class ApplicationMode { } public Integer getCustomIconColor() { - String customColor = app.getSettings().CUSTOM_ICON_COLOR.getModeValue(this); - return customColor == null ? null : Algorithms.parseColor(customColor); + try { + String customColor = app.getSettings().CUSTOM_ICON_COLOR.getModeValue(this); + return Algorithms.isEmpty(customColor) ? null : Algorithms.parseColor(customColor); + } catch (IllegalArgumentException e) { + return null; + } } public void setCustomIconColor(Integer customIconColor) {