Implement Online routing backend p.2
This commit is contained in:
parent
055b4c0f5a
commit
8395078329
28 changed files with 1107 additions and 642 deletions
|
@ -27,6 +27,8 @@
|
|||
android:layout_weight="1"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/content_padding_small"
|
||||
android:paddingBottom="@dimen/content_padding_small"
|
||||
android:orientation="vertical">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
|
@ -34,7 +36,6 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
app:typeface="@string/font_roboto_regular"
|
||||
|
|
|
@ -129,6 +129,19 @@
|
|||
tools:visibility="visible"
|
||||
android:visibility="gone" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/error_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:paddingTop="@dimen/content_padding_half"
|
||||
android:textColor="@color/color_invalid"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_regular"
|
||||
tools:text="Error text"
|
||||
tools:visibility="visible"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
|
|
|
@ -11,7 +11,21 @@
|
|||
Thx - Hardy
|
||||
|
||||
-->
|
||||
|
||||
<string name="message_name_is_already_exists">The name is already exists</string>
|
||||
<string name="message_server_error">Server error: %1$s</string>
|
||||
<string name="routing_engine_vehicle_type_mtb">MTB</string>
|
||||
<string name="routing_engine_vehicle_type_racingbike">Racing bike</string>
|
||||
<string name="routing_engine_vehicle_type_scooter">Scooter</string>
|
||||
<string name="routing_engine_vehicle_type_truck">Truck</string>
|
||||
<string name="routing_engine_vehicle_type_small_truck">Small truck</string>
|
||||
<string name="routing_engine_vehicle_type_hgv">HGV</string>
|
||||
<string name="routing_engine_vehicle_type_cycling_regular">Regular cycling</string>
|
||||
<string name="routing_engine_vehicle_type_cycling_road">Road cycling</string>
|
||||
<string name="routing_engine_vehicle_type_cycling_mountain">Mountain cycling</string>
|
||||
<string name="routing_engine_vehicle_type_cycling_electric">Electric cycling</string>
|
||||
<string name="routing_engine_vehicle_type_walking">Walking</string>
|
||||
<string name="routing_engine_vehicle_type_hiking">Hiking</string>
|
||||
<string name="routing_engine_vehicle_type_wheelchair">Wheelchair</string>
|
||||
<string name="shared_string_empty">Empty</string>
|
||||
<string name="select_folder_descr">Select folder or add new one</string>
|
||||
<string name="select_folder">Select folder</string>
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package net.osmand.plus.onlinerouting;
|
||||
|
||||
public enum EngineParameter {
|
||||
KEY,
|
||||
VEHICLE_KEY,
|
||||
CUSTOM_NAME,
|
||||
NAME_INDEX,
|
||||
CUSTOM_URL,
|
||||
API_KEY
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package net.osmand.plus.onlinerouting;
|
||||
|
||||
public enum EngineType {
|
||||
|
||||
GRAPHHOPPER("Graphhopper", "https://graphhopper.com/api/1/route"),
|
||||
OSRM("OSRM", "https://router.project-osrm.org/route/v1/"),
|
||||
ORS("Openroute Service", "https://api.openrouteservice.org/v2/directions/");
|
||||
|
||||
private String title;
|
||||
private String standardUrl;
|
||||
|
||||
EngineType(String title, String standardUrl) {
|
||||
this.title = title;
|
||||
this.standardUrl = standardUrl;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getStandardUrl() {
|
||||
return standardUrl;
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
package net.osmand.plus.onlinerouting;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class OnlineRoutingEngine {
|
||||
|
||||
public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_";
|
||||
|
||||
public enum EngineParameter {
|
||||
CUSTOM_NAME,
|
||||
CUSTOM_URL,
|
||||
API_KEY
|
||||
}
|
||||
|
||||
private String stringKey;
|
||||
private EngineType type;
|
||||
private String vehicleKey;
|
||||
private Map<String, String> params = new HashMap<>();
|
||||
|
||||
public OnlineRoutingEngine(@NonNull String stringKey,
|
||||
@NonNull EngineType type,
|
||||
@NonNull String vehicleKey,
|
||||
@Nullable Map<String, String> params) {
|
||||
this(stringKey, type, vehicleKey);
|
||||
if (!Algorithms.isEmpty(params)) {
|
||||
this.params.putAll(params);
|
||||
}
|
||||
}
|
||||
|
||||
public OnlineRoutingEngine(@NonNull String stringKey,
|
||||
@NonNull EngineType type,
|
||||
@NonNull String vehicleKey) {
|
||||
this.stringKey = stringKey;
|
||||
this.type = type;
|
||||
this.vehicleKey = vehicleKey;
|
||||
}
|
||||
|
||||
public String getStringKey() {
|
||||
return stringKey;
|
||||
}
|
||||
|
||||
public EngineType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
String customUrl = getParameter(EngineParameter.CUSTOM_URL);
|
||||
if (Algorithms.isEmpty(customUrl)) {
|
||||
return type.getStandardUrl();
|
||||
}
|
||||
return customUrl;
|
||||
}
|
||||
|
||||
public String getVehicleKey() {
|
||||
return vehicleKey;
|
||||
}
|
||||
|
||||
public Map<String, String> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public String getParameter(EngineParameter paramKey) {
|
||||
return params.get(paramKey.name());
|
||||
}
|
||||
|
||||
public void putParameter(EngineParameter paramKey, String paramValue) {
|
||||
params.put(paramKey.name(), paramValue);
|
||||
}
|
||||
|
||||
public String getName(@NonNull Context ctx) {
|
||||
String customName = getParameter(EngineParameter.CUSTOM_NAME);
|
||||
if (customName != null) {
|
||||
return customName;
|
||||
} else {
|
||||
return getStandardName(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
private String getStandardName(@NonNull Context ctx) {
|
||||
return getStandardName(ctx, type, vehicleKey);
|
||||
}
|
||||
|
||||
public static String getStandardName(@NonNull Context ctx,
|
||||
@NonNull EngineType type,
|
||||
@NonNull String vehicleKey) {
|
||||
String vehicleTitle = VehicleType.toHumanString(ctx, vehicleKey);
|
||||
String pattern = ctx.getString(R.string.ltr_or_rtl_combine_via_dash);
|
||||
return String.format(pattern, type.getTitle(), vehicleTitle);
|
||||
}
|
||||
|
||||
public static OnlineRoutingEngine createNewEngine(@NonNull EngineType type,
|
||||
@NonNull String vehicleKey,
|
||||
@Nullable Map<String, String> params) {
|
||||
return new OnlineRoutingEngine(generateKey(), type, vehicleKey, params);
|
||||
}
|
||||
|
||||
private static String generateKey() {
|
||||
return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
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.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<String, String> params) {
|
||||
switch (type) {
|
||||
case GRAPHHOPPER:
|
||||
return new GraphhopperEngine(params);
|
||||
case OSRM:
|
||||
return new OsrmEngine(params);
|
||||
case ORS:
|
||||
return new OrsEngine(params);
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Online routing type {" + type.name() + "} not supported");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package net.osmand.plus.onlinerouting;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
@ -10,10 +11,10 @@ import net.osmand.data.LatLon;
|
|||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.Version;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter;
|
||||
import net.osmand.plus.onlinerouting.engine.EngineType;
|
||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.GeoPolylineParserUtil;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.json.JSONArray;
|
||||
|
@ -24,7 +25,7 @@ import java.io.BufferedReader;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URLConnection;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -35,14 +36,18 @@ public class OnlineRoutingHelper {
|
|||
|
||||
private static final Log LOG = PlatformUtil.getLog(OnlineRoutingHelper.class);
|
||||
|
||||
private static final String ITEMS = "items";
|
||||
private static final String TYPE = "type";
|
||||
private static final String PARAMS = "params";
|
||||
|
||||
private OsmandApplication app;
|
||||
private OsmandSettings settings;
|
||||
private Map<String, OnlineRoutingEngine> cachedEngines;
|
||||
|
||||
public OnlineRoutingHelper(OsmandApplication app) {
|
||||
public OnlineRoutingHelper(@NonNull OsmandApplication app) {
|
||||
this.app = app;
|
||||
this.settings = app.getSettings();
|
||||
loadFromSettings();
|
||||
this.cachedEngines = loadSavedEngines();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -50,104 +55,42 @@ public class OnlineRoutingHelper {
|
|||
return new ArrayList<>(cachedEngines.values());
|
||||
}
|
||||
|
||||
public OnlineRoutingEngine getEngineByKey(String stringKey) {
|
||||
@NonNull
|
||||
public List<OnlineRoutingEngine> getEnginesExceptMentioned(@Nullable String ... excludeKeys) {
|
||||
List<OnlineRoutingEngine> engines = getEngines();
|
||||
if (excludeKeys != null) {
|
||||
for (String key : excludeKeys) {
|
||||
OnlineRoutingEngine engine = getEngineByKey(key);
|
||||
engines.remove(engine);
|
||||
}
|
||||
}
|
||||
return engines;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OnlineRoutingEngine getEngineByKey(@Nullable String stringKey) {
|
||||
return cachedEngines.get(stringKey);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<LatLon> calculateRouteOnline(@NonNull OnlineRoutingEngine engine,
|
||||
@NonNull List<LatLon> path) throws IOException, JSONException {
|
||||
String fullUrl = createFullUrl(engine, path);
|
||||
String content = makeRequest(fullUrl);
|
||||
return parseResponse(engine, content);
|
||||
String url = engine.getFullUrl(path);
|
||||
String content = makeRequest(url);
|
||||
return engine.parseServerResponse(content);
|
||||
}
|
||||
|
||||
public String createFullUrl(OnlineRoutingEngine engine, List<LatLon> path) {
|
||||
StringBuilder sb = new StringBuilder(engine.getBaseUrl());
|
||||
String vehicle = engine.getVehicleKey();
|
||||
String apiKey = engine.getParameter(EngineParameter.API_KEY);
|
||||
switch (engine.getType()) {
|
||||
|
||||
case GRAPHHOPPER:
|
||||
sb.append("?");
|
||||
for (LatLon point : path) {
|
||||
sb.append("point=")
|
||||
.append(point.getLatitude())
|
||||
.append(',')
|
||||
.append(point.getLongitude())
|
||||
.append('&');
|
||||
}
|
||||
sb.append("vehicle=").append(vehicle);
|
||||
|
||||
if (!Algorithms.isEmpty(apiKey)) {
|
||||
sb.append('&').append("key=").append(apiKey);
|
||||
}
|
||||
break;
|
||||
|
||||
case OSRM:
|
||||
sb.append(vehicle).append('/');
|
||||
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(';');
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ORS:
|
||||
if (path.size() > 1) {
|
||||
sb.append("driving-car").append('?'); // todo only for testing
|
||||
if (!Algorithms.isEmpty(apiKey)) {
|
||||
sb.append("api_key=").append(apiKey);
|
||||
}
|
||||
LatLon start = path.get(0);
|
||||
LatLon end = path.get(path.size() - 1);
|
||||
sb.append('&').append("start=")
|
||||
.append(start.getLatitude()).append(',').append(start.getLongitude());
|
||||
sb.append('&').append("end=")
|
||||
.append(end.getLatitude()).append(',').append(end.getLongitude());
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private List<LatLon> parseResponse(OnlineRoutingEngine engine, String content) throws JSONException {
|
||||
JSONObject obj = new JSONObject(content);
|
||||
|
||||
switch (engine.getType()) {
|
||||
|
||||
case GRAPHHOPPER:
|
||||
return GeoPolylineParserUtil.parse(
|
||||
obj.getJSONArray("paths").getJSONObject(0).getString("points"),
|
||||
GeoPolylineParserUtil.PRECISION_5);
|
||||
|
||||
case OSRM:
|
||||
return GeoPolylineParserUtil.parse(
|
||||
obj.getJSONArray("routes").getJSONObject(0).getString("geometry"),
|
||||
GeoPolylineParserUtil.PRECISION_5);
|
||||
|
||||
case ORS:
|
||||
JSONArray array = obj.getJSONArray("features").getJSONObject(0)
|
||||
.getJSONObject("geometry").getJSONArray("coordinates");
|
||||
List<LatLon> track = new ArrayList<>();
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
JSONArray point = array.getJSONArray(i);
|
||||
double lat = Double.parseDouble(point.getString(0));
|
||||
double lon = Double.parseDouble(point.getString(1));
|
||||
track.add(new LatLon(lat, lon));
|
||||
}
|
||||
return track;
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private String makeRequest(String url) throws IOException {
|
||||
URLConnection connection = NetworkUtils.getHttpURLConnection(url);
|
||||
@NonNull
|
||||
public String makeRequest(@NonNull String url) throws IOException {
|
||||
HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url);
|
||||
connection.setRequestProperty("User-Agent", Version.getFullVersion(app));
|
||||
StringBuilder content = new StringBuilder();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
BufferedReader reader;
|
||||
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
} else {
|
||||
reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
|
||||
}
|
||||
String s;
|
||||
while ((s = reader.readLine()) != null) {
|
||||
content.append(s);
|
||||
|
@ -160,32 +103,49 @@ public class OnlineRoutingHelper {
|
|||
}
|
||||
|
||||
public void saveEngine(@NonNull OnlineRoutingEngine engine) {
|
||||
String stringKey = engine.getStringKey();
|
||||
cachedEngines.put(stringKey, engine);
|
||||
saveToSettings();
|
||||
}
|
||||
|
||||
public void deleteEngine(@NonNull String stringKey) {
|
||||
OnlineRoutingEngine engine = getEngineByKey(stringKey);
|
||||
if (engine != null) {
|
||||
deleteEngine(engine);
|
||||
}
|
||||
deleteInaccessibleParameters(engine);
|
||||
String key = createEngineKeyIfNeeded(engine);
|
||||
cachedEngines.put(key, engine);
|
||||
saveCacheToSettings();
|
||||
}
|
||||
|
||||
public void deleteEngine(@NonNull OnlineRoutingEngine engine) {
|
||||
String stringKey = engine.getStringKey();
|
||||
if (cachedEngines.containsKey(stringKey)) {
|
||||
deleteEngine(stringKey);
|
||||
}
|
||||
|
||||
public void deleteEngine(@Nullable String stringKey) {
|
||||
if (stringKey != null) {
|
||||
cachedEngines.remove(stringKey);
|
||||
saveToSettings();
|
||||
saveCacheToSettings();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadFromSettings() {
|
||||
private void deleteInaccessibleParameters(@NonNull OnlineRoutingEngine engine) {
|
||||
for (EngineParameter key : EngineParameter.values()) {
|
||||
if (!engine.isParameterAllowed(key)) {
|
||||
engine.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String createEngineKeyIfNeeded(@NonNull OnlineRoutingEngine engine) {
|
||||
String key = engine.get(EngineParameter.KEY);
|
||||
if (Algorithms.isEmpty(key)) {
|
||||
key = OnlineRoutingEngine.generateKey();
|
||||
engine.put(EngineParameter.KEY, key);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Map<String, OnlineRoutingEngine> loadSavedEngines() {
|
||||
Map<String, OnlineRoutingEngine> cachedEngines = new LinkedHashMap<>();
|
||||
for (OnlineRoutingEngine engine : readFromSettings()) {
|
||||
cachedEngines.put(engine.getStringKey(), engine);
|
||||
}
|
||||
this.cachedEngines = cachedEngines;
|
||||
return cachedEngines;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -203,7 +163,7 @@ public class OnlineRoutingHelper {
|
|||
return engines;
|
||||
}
|
||||
|
||||
private void saveToSettings() {
|
||||
private void saveCacheToSettings() {
|
||||
if (!Algorithms.isEmpty(cachedEngines)) {
|
||||
try {
|
||||
JSONObject json = new JSONObject();
|
||||
|
@ -217,38 +177,44 @@ public class OnlineRoutingHelper {
|
|||
}
|
||||
}
|
||||
|
||||
public static void readFromJson(JSONObject json, List<OnlineRoutingEngine> engines) throws JSONException {
|
||||
public static void readFromJson(@NonNull JSONObject json,
|
||||
@NonNull List<OnlineRoutingEngine> engines) throws JSONException {
|
||||
if (!json.has("items")) {
|
||||
return;
|
||||
}
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<HashMap<String, String>>() {
|
||||
Type typeToken = new TypeToken<HashMap<String, String>>() {
|
||||
}.getType();
|
||||
JSONArray itemsJson = json.getJSONArray("items");
|
||||
JSONArray itemsJson = json.getJSONArray(ITEMS);
|
||||
for (int i = 0; i < itemsJson.length(); i++) {
|
||||
JSONObject object = itemsJson.getJSONObject(i);
|
||||
String key = object.getString("key");
|
||||
String vehicleKey = object.getString("vehicle");
|
||||
EngineType engineType = EngineType.valueOf(object.getString("type"));
|
||||
String paramsString = object.getString("params");
|
||||
HashMap<String, String> params = gson.fromJson(paramsString, type);
|
||||
engines.add(new OnlineRoutingEngine(key, engineType, vehicleKey, params));
|
||||
if (object.has(TYPE) && object.has(PARAMS)) {
|
||||
EngineType type = EngineType.getTypeByName(object.getString(TYPE));
|
||||
String paramsString = object.getString(PARAMS);
|
||||
HashMap<String, String> params = gson.fromJson(paramsString, typeToken);
|
||||
OnlineRoutingEngine engine = OnlineRoutingFactory.createEngine(type, params);
|
||||
if (!Algorithms.isEmpty(engine.getStringKey())) {
|
||||
engines.add(engine);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeToJson(JSONObject json, List<OnlineRoutingEngine> engines) throws JSONException {
|
||||
public static void writeToJson(@NonNull JSONObject json,
|
||||
@NonNull List<OnlineRoutingEngine> engines) throws JSONException {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<HashMap<String, String>>() {
|
||||
}.getType();
|
||||
for (OnlineRoutingEngine engine : engines) {
|
||||
if (Algorithms.isEmpty(engine.getStringKey())) {
|
||||
continue;
|
||||
}
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("key", engine.getStringKey());
|
||||
jsonObject.put("type", engine.getType().name());
|
||||
jsonObject.put("vehicle", engine.getVehicleKey());
|
||||
jsonObject.put("params", gson.toJson(engine.getParams(), type));
|
||||
jsonObject.put(TYPE, engine.getType().name());
|
||||
jsonObject.put(PARAMS, gson.toJson(engine.getParams(), type));
|
||||
jsonArray.put(jsonObject);
|
||||
}
|
||||
json.put("items", jsonArray);
|
||||
json.put(ITEMS, jsonArray);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,48 +3,26 @@ package net.osmand.plus.onlinerouting;
|
|||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.util.Algorithms;
|
||||
public class VehicleType {
|
||||
private final String key;
|
||||
@StringRes
|
||||
private final int titleId;
|
||||
|
||||
public enum VehicleType {
|
||||
CAR("car", R.string.routing_engine_vehicle_type_car),
|
||||
BIKE("bike", R.string.routing_engine_vehicle_type_bike),
|
||||
FOOT("foot", R.string.routing_engine_vehicle_type_foot),
|
||||
DRIVING("driving", R.string.routing_engine_vehicle_type_driving),
|
||||
CUSTOM("", R.string.shared_string_custom);
|
||||
|
||||
VehicleType(String key, int titleId) {
|
||||
public VehicleType(@NonNull String key,
|
||||
@StringRes int titleId) {
|
||||
this.key = key;
|
||||
this.titleId = titleId;
|
||||
}
|
||||
|
||||
private String key;
|
||||
private int titleId;
|
||||
|
||||
@NonNull
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getTitle(Context ctx) {
|
||||
@NonNull
|
||||
public String getTitle(@NonNull Context ctx) {
|
||||
return ctx.getString(titleId);
|
||||
}
|
||||
|
||||
public static String toHumanString(@NonNull Context ctx,
|
||||
@NonNull String key) {
|
||||
VehicleType vehicleType = getVehicleByKey(key);
|
||||
if (vehicleType == CUSTOM) {
|
||||
return Algorithms.capitalizeFirstLetter(key);
|
||||
}
|
||||
return vehicleType.getTitle(ctx);
|
||||
}
|
||||
|
||||
public static VehicleType getVehicleByKey(String key) {
|
||||
for (VehicleType v : values()) {
|
||||
if (Algorithms.objectEquals(v.getKey(), key)) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
return CUSTOM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
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");
|
||||
|
||||
private final String title;
|
||||
|
||||
EngineType(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static EngineType getTypeByName(@Nullable String name) {
|
||||
if (!Algorithms.isEmpty(name)) {
|
||||
for (EngineType type : values()) {
|
||||
if (type.name().equals(name)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
return values()[0];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package net.osmand.plus.onlinerouting.engine;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.onlinerouting.EngineParameter;
|
||||
import net.osmand.plus.onlinerouting.VehicleType;
|
||||
import net.osmand.util.GeoPolylineParserUtil;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GraphhopperEngine extends OnlineRoutingEngine {
|
||||
|
||||
public GraphhopperEngine(@Nullable Map<String, String> params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull EngineType getType() {
|
||||
return EngineType.GRAPHHOPPER;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getStandardUrl() {
|
||||
return "https://graphhopper.com/api/1/route";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collectAllowedParameters() {
|
||||
allowParameters(EngineParameter.API_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collectAllowedVehicles(@NonNull List<VehicleType> vehicles) {
|
||||
vehicles.add(new VehicleType("car", R.string.routing_engine_vehicle_type_car));
|
||||
vehicles.add(new VehicleType("bike", R.string.routing_engine_vehicle_type_bike));
|
||||
vehicles.add(new VehicleType("foot", R.string.routing_engine_vehicle_type_foot));
|
||||
vehicles.add(new VehicleType("hike", R.string.routing_engine_vehicle_type_hiking));
|
||||
vehicles.add(new VehicleType("mtb", R.string.routing_engine_vehicle_type_mtb));
|
||||
vehicles.add(new VehicleType("racingbike", R.string.routing_engine_vehicle_type_racingbike));
|
||||
vehicles.add(new VehicleType("scooter", R.string.routing_engine_vehicle_type_scooter));
|
||||
vehicles.add(new VehicleType("truck", R.string.routing_engine_vehicle_type_truck));
|
||||
vehicles.add(new VehicleType("small_truck", R.string.routing_engine_vehicle_type_small_truck));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeFullUrl(@NonNull StringBuilder sb,
|
||||
@NonNull List<LatLon> path) {
|
||||
sb.append("?");
|
||||
for (LatLon point : path) {
|
||||
sb.append("point=")
|
||||
.append(point.getLatitude())
|
||||
.append(',')
|
||||
.append(point.getLongitude())
|
||||
.append('&');
|
||||
}
|
||||
String vehicle = get(EngineParameter.VEHICLE_KEY);
|
||||
if (vehicle != null) {
|
||||
sb.append("vehicle=").append(vehicle);
|
||||
}
|
||||
String apiKey = get(EngineParameter.API_KEY);
|
||||
if (apiKey != null) {
|
||||
sb.append('&').append("key=").append(apiKey);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<LatLon> parseServerResponse(@NonNull String content) throws JSONException {
|
||||
JSONObject obj = new JSONObject(content);
|
||||
return GeoPolylineParserUtil.parse(
|
||||
obj.getJSONArray("paths").getJSONObject(0).getString("points"),
|
||||
GeoPolylineParserUtil.PRECISION_5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean parseServerMessage(@NonNull StringBuilder sb,
|
||||
@NonNull String content) throws JSONException {
|
||||
JSONObject obj = new JSONObject(content);
|
||||
if (obj.has("message")) {
|
||||
String message = obj.getString("message");
|
||||
sb.append(message);
|
||||
}
|
||||
return obj.has("paths");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,197 @@
|
|||
package net.osmand.plus.onlinerouting.engine;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.data.LatLon;
|
||||
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.util.Algorithms;
|
||||
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class OnlineRoutingEngine implements Cloneable {
|
||||
|
||||
public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_";
|
||||
public static final VehicleType CUSTOM_VEHICLE = new VehicleType("", R.string.shared_string_custom);
|
||||
|
||||
private final Map<String, String> params = new HashMap<>();
|
||||
private final List<VehicleType> allowedVehicles = new ArrayList<>();
|
||||
private final Set<EngineParameter> allowedParameters = new HashSet<>();
|
||||
|
||||
public OnlineRoutingEngine(@Nullable Map<String, String> params) {
|
||||
if (!Algorithms.isEmpty(params)) {
|
||||
this.params.putAll(params);
|
||||
}
|
||||
collectAllowedVehiclesInternal();
|
||||
collectAllowedParametersInternal();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public abstract EngineType getType();
|
||||
|
||||
@Nullable
|
||||
public String getStringKey() {
|
||||
return get(EngineParameter.KEY);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getName(@NonNull Context ctx) {
|
||||
String customName = get(EngineParameter.CUSTOM_NAME);
|
||||
if (customName != null) {
|
||||
return customName;
|
||||
} else {
|
||||
return getStandardName(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String getStandardName(@NonNull Context ctx) {
|
||||
String base = getBaseName(ctx);
|
||||
String index = get(EngineParameter.NAME_INDEX);
|
||||
return !Algorithms.isEmpty(index) ? base + " " + index : base;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getBaseName(@NonNull Context ctx) {
|
||||
String vehicleTitle = getSelectedVehicleName(ctx);
|
||||
if (Algorithms.isEmpty(vehicleTitle)) {
|
||||
return getType().getTitle();
|
||||
} else {
|
||||
String pattern = ctx.getString(R.string.ltr_or_rtl_combine_via_dash);
|
||||
return String.format(pattern, getType().getTitle(), vehicleTitle);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getBaseUrl() {
|
||||
String customUrl = get(EngineParameter.CUSTOM_URL);
|
||||
if (Algorithms.isEmpty(customUrl)) {
|
||||
return getStandardUrl();
|
||||
}
|
||||
return customUrl;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getFullUrl(@NonNull List<LatLon> path) {
|
||||
StringBuilder sb = new StringBuilder(getBaseUrl());
|
||||
makeFullUrl(sb, path);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
protected abstract void makeFullUrl(@NonNull StringBuilder sb,
|
||||
@NonNull List<LatLon> path);
|
||||
|
||||
@NonNull
|
||||
public abstract List<LatLon> parseServerResponse(@NonNull String content) throws JSONException;
|
||||
|
||||
@NonNull
|
||||
public abstract String getStandardUrl();
|
||||
|
||||
@NonNull
|
||||
public Map<String, String> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String get(@NonNull EngineParameter key) {
|
||||
return params.get(key.name());
|
||||
}
|
||||
|
||||
public void put(@NonNull EngineParameter key, @NonNull String value) {
|
||||
params.put(key.name(), value);
|
||||
}
|
||||
|
||||
public void remove(@NonNull EngineParameter key) {
|
||||
params.remove(key.name());
|
||||
}
|
||||
|
||||
private void collectAllowedVehiclesInternal() {
|
||||
allowedVehicles.clear();
|
||||
collectAllowedVehicles(allowedVehicles);
|
||||
allowedVehicles.add(CUSTOM_VEHICLE);
|
||||
}
|
||||
|
||||
protected abstract void collectAllowedVehicles(@NonNull List<VehicleType> vehicles);
|
||||
|
||||
@NonNull
|
||||
public List<VehicleType> getAllowedVehicles() {
|
||||
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();
|
||||
|
||||
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);
|
||||
VehicleType vt = getVehicleTypeByKey(key);
|
||||
if (!vt.equals(CUSTOM_VEHICLE)) {
|
||||
return vt.getTitle(ctx);
|
||||
}
|
||||
return key != null ? Algorithms.capitalizeFirstLetter(key) : null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public VehicleType getSelectedVehicleType() {
|
||||
String key = get(EngineParameter.VEHICLE_KEY);
|
||||
return getVehicleTypeByKey(key);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public VehicleType getVehicleTypeByKey(@Nullable String vehicleKey) {
|
||||
if (!isEmpty(vehicleKey)) {
|
||||
for (VehicleType vt : allowedVehicles) {
|
||||
if (Algorithms.objectEquals(vt.getKey(), vehicleKey)) {
|
||||
return vt;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CUSTOM_VEHICLE;
|
||||
}
|
||||
|
||||
public abstract boolean parseServerMessage(@NonNull StringBuilder sb,
|
||||
@NonNull String content) throws JSONException;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Object clone() {
|
||||
return OnlineRoutingFactory.createEngine(getType(), getParams());
|
||||
}
|
||||
|
||||
protected boolean isEmpty(@Nullable String s) {
|
||||
return Algorithms.isEmpty(s);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String generateKey() {
|
||||
return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis();
|
||||
}
|
||||
}
|
102
OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java
Normal file
102
OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java
Normal file
|
@ -0,0 +1,102 @@
|
|||
package net.osmand.plus.onlinerouting.engine;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.data.LatLon;
|
||||
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;
|
||||
|
||||
public class OrsEngine extends OnlineRoutingEngine {
|
||||
|
||||
public OrsEngine(@Nullable Map<String, String> params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull EngineType getType() {
|
||||
return EngineType.ORS;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getStandardUrl() {
|
||||
return "https://api.openrouteservice.org/v2/directions/";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collectAllowedParameters() {
|
||||
allowParameters(EngineParameter.API_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collectAllowedVehicles(@NonNull List<VehicleType> vehicles) {
|
||||
vehicles.add(new VehicleType("driving-car", R.string.routing_engine_vehicle_type_car));
|
||||
vehicles.add(new VehicleType("driving-hgv", R.string.routing_engine_vehicle_type_hgv));
|
||||
vehicles.add(new VehicleType("cycling-regular", R.string.routing_engine_vehicle_type_cycling_regular));
|
||||
vehicles.add(new VehicleType("cycling-road", R.string.routing_engine_vehicle_type_cycling_road));
|
||||
vehicles.add(new VehicleType("cycling-mountain", R.string.routing_engine_vehicle_type_cycling_mountain));
|
||||
vehicles.add(new VehicleType("cycling-electric", R.string.routing_engine_vehicle_type_cycling_electric));
|
||||
vehicles.add(new VehicleType("foot-walking", R.string.routing_engine_vehicle_type_walking));
|
||||
vehicles.add(new VehicleType("foot-hiking", R.string.routing_engine_vehicle_type_hiking));
|
||||
vehicles.add(new VehicleType("wheelchair", R.string.routing_engine_vehicle_type_wheelchair));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeFullUrl(@NonNull StringBuilder sb,
|
||||
@NonNull List<LatLon> path) {
|
||||
if (path.size() > 1) {
|
||||
String vehicleKey = get(EngineParameter.VEHICLE_KEY);
|
||||
if (!isEmpty(vehicleKey)) {
|
||||
sb.append(vehicleKey);
|
||||
}
|
||||
sb.append('?');
|
||||
String apiKey = get(EngineParameter.API_KEY);
|
||||
if (!isEmpty(apiKey)) {
|
||||
sb.append("api_key=").append(apiKey);
|
||||
}
|
||||
LatLon start = path.get(0);
|
||||
LatLon end = path.get(path.size() - 1);
|
||||
sb.append('&').append("start=")
|
||||
.append(start.getLatitude()).append(',').append(start.getLongitude());
|
||||
sb.append('&').append("end=")
|
||||
.append(end.getLatitude()).append(',').append(end.getLongitude());
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<LatLon> parseServerResponse(@NonNull String content) throws JSONException {
|
||||
JSONObject obj = new JSONObject(content);
|
||||
JSONArray array = obj.getJSONArray("features").getJSONObject(0)
|
||||
.getJSONObject("geometry").getJSONArray("coordinates");
|
||||
List<LatLon> track = new ArrayList<>();
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
JSONArray point = array.getJSONArray(i);
|
||||
double lat = Double.parseDouble(point.getString(0));
|
||||
double lon = Double.parseDouble(point.getString(1));
|
||||
track.add(new LatLon(lat, lon));
|
||||
}
|
||||
return track;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean parseServerMessage(@NonNull StringBuilder sb,
|
||||
@NonNull String content) throws JSONException {
|
||||
JSONObject obj = new JSONObject(content);
|
||||
if (obj.has("error")) {
|
||||
String message = obj.getString("error");
|
||||
sb.append(message);
|
||||
}
|
||||
return obj.has("features");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package net.osmand.plus.onlinerouting.engine;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.onlinerouting.EngineParameter;
|
||||
import net.osmand.plus.onlinerouting.VehicleType;
|
||||
import net.osmand.util.GeoPolylineParserUtil;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class OsrmEngine extends OnlineRoutingEngine {
|
||||
|
||||
public OsrmEngine(@Nullable Map<String, String> params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull EngineType getType() {
|
||||
return EngineType.OSRM;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getStandardUrl() {
|
||||
return "https://router.project-osrm.org/route/v1/";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collectAllowedParameters() { }
|
||||
|
||||
@Override
|
||||
protected void collectAllowedVehicles(@NonNull List<VehicleType> vehicles) {
|
||||
vehicles.add(new VehicleType("car", R.string.routing_engine_vehicle_type_car));
|
||||
vehicles.add(new VehicleType("bike", R.string.routing_engine_vehicle_type_bike));
|
||||
vehicles.add(new VehicleType("foot", R.string.routing_engine_vehicle_type_foot));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeFullUrl(@NonNull StringBuilder sb,
|
||||
@NonNull List<LatLon> path) {
|
||||
String vehicleKey = get(EngineParameter.VEHICLE_KEY);
|
||||
if (!isEmpty(vehicleKey)) {
|
||||
sb.append(vehicleKey).append('/');
|
||||
}
|
||||
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(';');
|
||||
}
|
||||
}
|
||||
sb.append('?');
|
||||
sb.append("overview=full");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<LatLon> parseServerResponse(@NonNull String content) throws JSONException {
|
||||
JSONObject obj = new JSONObject(content);
|
||||
return GeoPolylineParserUtil.parse(
|
||||
obj.getJSONArray("routes").getJSONObject(0).getString("geometry"),
|
||||
GeoPolylineParserUtil.PRECISION_5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean parseServerMessage(@NonNull StringBuilder sb,
|
||||
@NonNull String content) throws JSONException {
|
||||
JSONObject obj = new JSONObject(content);
|
||||
if (obj.has("message")) {
|
||||
String message = obj.getString("message");
|
||||
sb.append(message);
|
||||
}
|
||||
return obj.has("routes");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package net.osmand.plus.onlinerouting.ui;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import net.osmand.data.LatLon;
|
||||
|
||||
public enum ExampleLocation {
|
||||
|
||||
AMSTERDAM("Amsterdam",
|
||||
new LatLon(52.379189, 4.899431),
|
||||
new LatLon(52.308056, 4.764167)),
|
||||
|
||||
BERLIN("Berlin",
|
||||
new LatLon(52.520008, 13.404954),
|
||||
new LatLon(52.3666652, 13.501997992)),
|
||||
|
||||
NEW_YORK("New York",
|
||||
new LatLon(43.000000, -75.000000),
|
||||
new LatLon(40.641766, -73.780968)),
|
||||
|
||||
PARIS("Paris",
|
||||
new LatLon(48.864716, 2.349014),
|
||||
new LatLon(48.948437, 2.434931));
|
||||
|
||||
ExampleLocation(@NonNull String name,
|
||||
@NonNull LatLon cityCenterLatLon,
|
||||
@NonNull LatLon cityAirportLatLon) {
|
||||
this.name = name;
|
||||
this.cityCenterLatLon = cityCenterLatLon;
|
||||
this.cityAirportLatLon = cityAirportLatLon;
|
||||
}
|
||||
|
||||
private String name;
|
||||
private LatLon cityCenterLatLon;
|
||||
private LatLon cityAirportLatLon;
|
||||
|
||||
@NonNull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public LatLon getCityCenterLatLon() {
|
||||
return cityCenterLatLon;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public LatLon getCityAirportLatLon() {
|
||||
return cityAirportLatLon;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package net.osmand.plus.onlinerouting;
|
||||
package net.osmand.plus.onlinerouting.ui;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
|
@ -9,6 +9,7 @@ import android.widget.EditText;
|
|||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
|
@ -39,9 +40,11 @@ public class OnlineRoutingCard extends BaseCard {
|
|||
private OsmandTextFieldBoxes textFieldBoxes;
|
||||
private EditText editText;
|
||||
private TextView tvHelperText;
|
||||
private TextView tvErrorText;
|
||||
private View bottomDivider;
|
||||
private View button;
|
||||
private OnTextChangedListener onTextChangedListener;
|
||||
private boolean fieldBoxHelperTextShowed;
|
||||
|
||||
public OnlineRoutingCard(@NonNull MapActivity mapActivity, boolean nightMode) {
|
||||
super(mapActivity);
|
||||
|
@ -64,6 +67,7 @@ public class OnlineRoutingCard extends BaseCard {
|
|||
textFieldBoxes = view.findViewById(R.id.field_box);
|
||||
editText = view.findViewById(R.id.edit_text);
|
||||
tvHelperText = view.findViewById(R.id.helper_text);
|
||||
tvErrorText = view.findViewById(R.id.error_text);
|
||||
bottomDivider = view.findViewById(R.id.bottom_divider);
|
||||
button = view.findViewById(R.id.button);
|
||||
|
||||
|
@ -80,7 +84,7 @@ public class OnlineRoutingCard extends BaseCard {
|
|||
public void afterTextChanged(Editable s) {
|
||||
if (onTextChangedListener != null) {
|
||||
boolean editedByUser = editText.getTag() == null;
|
||||
String text = editText.getText().toString();
|
||||
String text = editText.getText().toString().trim();
|
||||
onTextChangedListener.onTextChanged(editedByUser, text);
|
||||
}
|
||||
}
|
||||
|
@ -107,9 +111,9 @@ public class OnlineRoutingCard extends BaseCard {
|
|||
tvHeaderSubtitle.setText(subtitle);
|
||||
}
|
||||
|
||||
public void setSelectionMenu(List<HorizontalSelectionItem> items,
|
||||
String selectedItemTitle,
|
||||
final CallbackWithObject<HorizontalSelectionItem> callback) {
|
||||
public void setSelectionMenu(@NonNull List<HorizontalSelectionItem> items,
|
||||
@NonNull String selectedItemTitle,
|
||||
@NonNull final CallbackWithObject<HorizontalSelectionItem> callback) {
|
||||
showElements(rvSelectionMenu);
|
||||
rvSelectionMenu.setLayoutManager(
|
||||
new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false));
|
||||
|
@ -139,15 +143,31 @@ public class OnlineRoutingCard extends BaseCard {
|
|||
|
||||
public void setFieldBoxHelperText(@NonNull String helperText) {
|
||||
showElements(fieldBoxContainer, tvHelperText);
|
||||
fieldBoxHelperTextShowed = true;
|
||||
tvHelperText.setText(helperText);
|
||||
}
|
||||
|
||||
public void showFieldBoxError(@NonNull String errorText) {
|
||||
showElements(fieldBoxContainer, tvErrorText);
|
||||
hideElements(tvHelperText);
|
||||
tvErrorText.setText(errorText);
|
||||
}
|
||||
|
||||
public void hideFieldBoxError() {
|
||||
hideElements(tvErrorText);
|
||||
if (fieldBoxHelperTextShowed) {
|
||||
showElements(tvErrorText);
|
||||
}
|
||||
}
|
||||
|
||||
public void setEditedText(@NonNull String text) {
|
||||
editText.setTag(""); // needed to indicate that the text was edited programmatically
|
||||
showElements(fieldBoxContainer);
|
||||
editText.setTag(""); // indicate that the text was edited programmatically
|
||||
editText.setText(text);
|
||||
editText.setTag(null);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getEditedText() {
|
||||
return editText.getText().toString();
|
||||
}
|
||||
|
@ -156,7 +176,8 @@ public class OnlineRoutingCard extends BaseCard {
|
|||
showElements(bottomDivider);
|
||||
}
|
||||
|
||||
public void setButton(String title, OnClickListener listener) {
|
||||
public void setButton(@NonNull String title,
|
||||
@NonNull OnClickListener listener) {
|
||||
showElements(button);
|
||||
button.setOnClickListener(listener);
|
||||
UiUtilities.setupDialogButton(nightMode, button, DialogButtonType.PRIMARY, title);
|
||||
|
@ -186,11 +207,11 @@ public class OnlineRoutingCard extends BaseCard {
|
|||
AndroidUiHelper.setVisibility(View.GONE, views);
|
||||
}
|
||||
|
||||
public void setOnTextChangedListener(OnTextChangedListener onTextChangedListener) {
|
||||
public void setOnTextChangedListener(@Nullable OnTextChangedListener onTextChangedListener) {
|
||||
this.onTextChangedListener = onTextChangedListener;
|
||||
}
|
||||
|
||||
public interface OnTextChangedListener {
|
||||
void onTextChanged(boolean editedByUser, String text);
|
||||
void onTextChanged(boolean editedByUser, @NonNull String text);
|
||||
}
|
||||
}
|
|
@ -1,13 +1,11 @@
|
|||
package net.osmand.plus.onlinerouting;
|
||||
package net.osmand.plus.onlinerouting.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
@ -17,8 +15,6 @@ import androidx.appcompat.widget.Toolbar;
|
|||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import net.osmand.AndroidNetworkUtils;
|
||||
import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.CallbackWithObject;
|
||||
import net.osmand.data.LatLon;
|
||||
|
@ -29,33 +25,37 @@ import net.osmand.plus.UiUtilities.DialogButtonType;
|
|||
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.OnlineRoutingCard.OnTextChangedListener;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter;
|
||||
import net.osmand.plus.onlinerouting.EngineParameter;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingFactory;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
|
||||
import net.osmand.plus.onlinerouting.VehicleType;
|
||||
import net.osmand.plus.onlinerouting.ui.OnlineRoutingCard.OnTextChangedListener;
|
||||
import net.osmand.plus.onlinerouting.engine.EngineType;
|
||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
|
||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.CUSTOM_VEHICLE;
|
||||
|
||||
public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
||||
|
||||
public static final String TAG = OnlineRoutingEngineFragment.class.getSimpleName();
|
||||
|
||||
private static final String ENGINE_NAME_KEY = "engine_name";
|
||||
private static final String ENGINE_SERVER_KEY = "engine_server";
|
||||
private static final String ENGINE_SERVER_URL_KEY = "engine_server_url";
|
||||
private static final String ENGINE_VEHICLE_TYPE_KEY = "engine_vehicle_type";
|
||||
private static final String ENGINE_TYPE_KEY = "engine_type";
|
||||
private static final String ENGINE_CUSTOM_VEHICLE_KEY = "engine_custom_vehicle";
|
||||
private static final String ENGINE_API_KEY_KEY = "engine_api_key";
|
||||
private static final String EXAMPLE_LOCATION_KEY = "example_location";
|
||||
private static final String APP_MODE_KEY = "app_mode";
|
||||
private static final String EDITED_ENGINE_KEY = "edited_engine_key";
|
||||
|
||||
private OsmandApplication app;
|
||||
private ApplicationMode appMode;
|
||||
private MapActivity mapActivity;
|
||||
private OnlineRoutingHelper helper;
|
||||
|
||||
|
@ -67,61 +67,19 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
|||
private OnlineRoutingCard apiKeyCard;
|
||||
private OnlineRoutingCard exampleCard;
|
||||
private View testResultsContainer;
|
||||
private View saveButton;
|
||||
|
||||
private ApplicationMode appMode;
|
||||
|
||||
private OnlineRoutingEngineObject engine;
|
||||
private OnlineRoutingEngine engine;
|
||||
private String customVehicleKey;
|
||||
private ExampleLocation selectedLocation;
|
||||
private String editedEngineKey;
|
||||
|
||||
private enum ExampleLocation {
|
||||
|
||||
AMSTERDAM("Amsterdam",
|
||||
new LatLon(52.379189, 4.899431),
|
||||
new LatLon(52.308056, 4.764167)),
|
||||
|
||||
BERLIN("Berlin",
|
||||
new LatLon(52.520008, 13.404954),
|
||||
new LatLon(52.3666652, 13.501997992)),
|
||||
|
||||
NEW_YORK("New York",
|
||||
new LatLon(43.000000, -75.000000),
|
||||
new LatLon(40.641766, -73.780968)),
|
||||
|
||||
PARIS("Paris",
|
||||
new LatLon(48.864716, 2.349014),
|
||||
new LatLon(48.948437, 2.434931));
|
||||
|
||||
ExampleLocation(String name, LatLon cityCenterLatLon, LatLon cityAirportLatLon) {
|
||||
this.name = name;
|
||||
this.cityCenterLatLon = cityCenterLatLon;
|
||||
this.cityAirportLatLon = cityAirportLatLon;
|
||||
}
|
||||
|
||||
private String name;
|
||||
private LatLon cityCenterLatLon;
|
||||
private LatLon cityAirportLatLon;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public LatLon getCityCenterLatLon() {
|
||||
return cityCenterLatLon;
|
||||
}
|
||||
|
||||
public LatLon getCityAirportLatLon() {
|
||||
return cityAirportLatLon;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
app = requireMyApplication();
|
||||
mapActivity = getMapActivity();
|
||||
helper = app.getOnlineRoutingHelper();
|
||||
engine = new OnlineRoutingEngineObject();
|
||||
if (savedInstanceState != null) {
|
||||
restoreState(savedInstanceState);
|
||||
} else {
|
||||
|
@ -148,14 +106,43 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
|||
setupApiKeyCard();
|
||||
setupExampleCard();
|
||||
setupResultsContainer();
|
||||
addSpaceSegment();
|
||||
|
||||
setupButtons();
|
||||
|
||||
generateUniqueNameIfNeeded();
|
||||
updateCardViews(nameCard, typeCard, vehicleCard, exampleCard);
|
||||
return view;
|
||||
}
|
||||
|
||||
private void setupToolbar(Toolbar toolbar) {
|
||||
ImageView navigationIcon = toolbar.findViewById(R.id.close_button);
|
||||
navigationIcon.setImageResource(R.drawable.ic_action_close);
|
||||
navigationIcon.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
TextView title = toolbar.findViewById(R.id.toolbar_title);
|
||||
toolbar.findViewById(R.id.toolbar_subtitle).setVisibility(View.GONE);
|
||||
View actionBtn = toolbar.findViewById(R.id.action_button);
|
||||
if (isEditingMode()) {
|
||||
title.setText(getString(R.string.edit_online_routing_engine));
|
||||
ImageView ivBtn = toolbar.findViewById(R.id.action_button_icon);
|
||||
ivBtn.setImageDrawable(
|
||||
getIcon(R.drawable.ic_action_delete_dark, R.color.color_osm_edit_delete));
|
||||
actionBtn.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onDeleteEngine();
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
title.setText(getString(R.string.add_online_routing_engine));
|
||||
actionBtn.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupNameCard() {
|
||||
nameCard = new OnlineRoutingCard(mapActivity, isNightMode());
|
||||
nameCard.build(mapActivity);
|
||||
|
@ -164,9 +151,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
|||
nameCard.setFieldBoxLabelText(getString(R.string.shared_string_name));
|
||||
nameCard.setOnTextChangedListener(new OnTextChangedListener() {
|
||||
@Override
|
||||
public void onTextChanged(boolean changedByUser, String text) {
|
||||
public void onTextChanged(boolean changedByUser, @NonNull String text) {
|
||||
if (changedByUser) {
|
||||
engine.customName = text;
|
||||
engine.put(EngineParameter.CUSTOM_NAME, text);
|
||||
checkCustomNameUnique(engine);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -182,14 +170,13 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
|||
for (EngineType server : EngineType.values()) {
|
||||
serverItems.add(new HorizontalSelectionItem(server.getTitle(), server));
|
||||
}
|
||||
typeCard.setSelectionMenu(serverItems, engine.type.getTitle(),
|
||||
typeCard.setSelectionMenu(serverItems, engine.getType().getTitle(),
|
||||
new CallbackWithObject<HorizontalSelectionItem>() {
|
||||
@Override
|
||||
public boolean processResult(HorizontalSelectionItem result) {
|
||||
EngineType type = (EngineType) result.getObject();
|
||||
if (engine.type != type) {
|
||||
engine.type = type;
|
||||
updateCardViews(nameCard, typeCard, exampleCard);
|
||||
if (engine.getType() != type) {
|
||||
changeEngineType(type);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -197,9 +184,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
|||
});
|
||||
typeCard.setOnTextChangedListener(new OnTextChangedListener() {
|
||||
@Override
|
||||
public void onTextChanged(boolean editedByUser, String text) {
|
||||
public void onTextChanged(boolean editedByUser, @NonNull String text) {
|
||||
if (editedByUser) {
|
||||
engine.customServerUrl = text;
|
||||
engine.put(EngineParameter.CUSTOM_URL, text);
|
||||
updateCardViews(exampleCard);
|
||||
}
|
||||
}
|
||||
|
@ -213,37 +200,44 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
|||
vehicleCard = new OnlineRoutingCard(mapActivity, isNightMode());
|
||||
vehicleCard.build(mapActivity);
|
||||
vehicleCard.setHeaderTitle(getString(R.string.shared_string_vehicle));
|
||||
vehicleCard.setFieldBoxLabelText(getString(R.string.shared_string_custom));
|
||||
vehicleCard.setOnTextChangedListener(new OnTextChangedListener() {
|
||||
@Override
|
||||
public void onTextChanged(boolean editedByUser, @NonNull String text) {
|
||||
if (editedByUser) {
|
||||
customVehicleKey = text;
|
||||
engine.put(EngineParameter.VEHICLE_KEY, customVehicleKey);
|
||||
updateCardViews(nameCard, exampleCard);
|
||||
}
|
||||
}
|
||||
});
|
||||
vehicleCard.setEditedText(customVehicleKey);
|
||||
vehicleCard.setFieldBoxHelperText(getString(R.string.shared_string_enter_param));
|
||||
vehicleCard.showDivider();
|
||||
segmentsContainer.addView(vehicleCard.getView());
|
||||
setupVehicleTypes();
|
||||
}
|
||||
|
||||
private void setupVehicleTypes() {
|
||||
List<HorizontalSelectionItem> vehicleItems = new ArrayList<>();
|
||||
for (VehicleType vehicle : VehicleType.values()) {
|
||||
for (VehicleType vehicle : engine.getAllowedVehicles()) {
|
||||
vehicleItems.add(new HorizontalSelectionItem(vehicle.getTitle(app), vehicle));
|
||||
}
|
||||
vehicleCard.setSelectionMenu(vehicleItems, engine.vehicleType.getTitle(app),
|
||||
vehicleCard.setSelectionMenu(vehicleItems, engine.getSelectedVehicleType().getTitle(app),
|
||||
new CallbackWithObject<HorizontalSelectionItem>() {
|
||||
@Override
|
||||
public boolean processResult(HorizontalSelectionItem result) {
|
||||
VehicleType vehicle = (VehicleType) result.getObject();
|
||||
if (engine.vehicleType != vehicle) {
|
||||
engine.vehicleType = vehicle;
|
||||
if (!Algorithms.objectEquals(engine.getSelectedVehicleType(), vehicle)) {
|
||||
String vehicleKey = vehicle.equals(CUSTOM_VEHICLE) ? customVehicleKey : vehicle.getKey();
|
||||
engine.put(EngineParameter.VEHICLE_KEY, vehicleKey);
|
||||
generateUniqueNameIfNeeded();
|
||||
updateCardViews(nameCard, vehicleCard, exampleCard);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
vehicleCard.setFieldBoxLabelText(getString(R.string.shared_string_custom));
|
||||
vehicleCard.setOnTextChangedListener(new OnTextChangedListener() {
|
||||
@Override
|
||||
public void onTextChanged(boolean editedByUser, String text) {
|
||||
if (editedByUser) {
|
||||
engine.customVehicleKey = text;
|
||||
updateCardViews(nameCard, exampleCard);
|
||||
}
|
||||
}
|
||||
});
|
||||
vehicleCard.setEditedText(engine.customVehicleKey);
|
||||
vehicleCard.setFieldBoxHelperText(getString(R.string.shared_string_enter_param));
|
||||
vehicleCard.showDivider();
|
||||
segmentsContainer.addView(vehicleCard.getView());
|
||||
}
|
||||
|
||||
private void setupApiKeyCard() {
|
||||
|
@ -251,12 +245,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
|||
apiKeyCard.build(mapActivity);
|
||||
apiKeyCard.setHeaderTitle(getString(R.string.shared_string_api_key));
|
||||
apiKeyCard.setFieldBoxLabelText(getString(R.string.keep_it_empty_if_not));
|
||||
apiKeyCard.setEditedText(engine.apiKey);
|
||||
String apiKey = engine.get(EngineParameter.API_KEY);
|
||||
if (apiKey != null) {
|
||||
apiKeyCard.setEditedText(apiKey);
|
||||
}
|
||||
apiKeyCard.showDivider();
|
||||
apiKeyCard.setOnTextChangedListener(new OnTextChangedListener() {
|
||||
@Override
|
||||
public void onTextChanged(boolean editedByUser, String text) {
|
||||
engine.apiKey = text;
|
||||
public void onTextChanged(boolean editedByUser, @NonNull String text) {
|
||||
engine.put(EngineParameter.API_KEY, text);
|
||||
updateCardViews(exampleCard);
|
||||
}
|
||||
});
|
||||
|
@ -297,86 +294,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
|||
private void setupResultsContainer() {
|
||||
testResultsContainer = getInflater().inflate(
|
||||
R.layout.bottom_sheet_item_with_descr_64dp, segmentsContainer, false);
|
||||
testResultsContainer.setVisibility(View.GONE);
|
||||
testResultsContainer.setVisibility(View.INVISIBLE);
|
||||
segmentsContainer.addView(testResultsContainer);
|
||||
}
|
||||
|
||||
private void addSpaceSegment() {
|
||||
int space = (int) getResources().getDimension(R.dimen.empty_state_text_button_padding_top);
|
||||
View bottomSpaceView = new View(app);
|
||||
bottomSpaceView.setLayoutParams(
|
||||
new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, space));
|
||||
segmentsContainer.addView(bottomSpaceView);
|
||||
}
|
||||
|
||||
private void setupToolbar(Toolbar toolbar) {
|
||||
ImageView navigationIcon = toolbar.findViewById(R.id.close_button);
|
||||
navigationIcon.setImageResource(R.drawable.ic_action_close);
|
||||
navigationIcon.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
TextView title = toolbar.findViewById(R.id.toolbar_title);
|
||||
toolbar.findViewById(R.id.toolbar_subtitle).setVisibility(View.GONE);
|
||||
View actionBtn = toolbar.findViewById(R.id.action_button);
|
||||
if (isEditingMode()) {
|
||||
title.setText(getString(R.string.edit_online_routing_engine));
|
||||
ImageView ivBtn = toolbar.findViewById(R.id.action_button_icon);
|
||||
ivBtn.setImageDrawable(
|
||||
getIcon(R.drawable.ic_action_delete_dark, R.color.color_osm_edit_delete));
|
||||
actionBtn.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
deleteEngine();
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
title.setText(getString(R.string.add_online_routing_engine));
|
||||
actionBtn.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCardViews(BaseCard... cardsToUpdate) {
|
||||
for (BaseCard card : cardsToUpdate) {
|
||||
if (nameCard.equals(card)) {
|
||||
if (Algorithms.isEmpty(engine.customName)) {
|
||||
String name;
|
||||
if (Algorithms.isEmpty(engine.getVehicleKey())) {
|
||||
name = engine.type.getTitle();
|
||||
} else {
|
||||
name = OnlineRoutingEngine.getStandardName(app, engine.type, engine.getVehicleKey());
|
||||
}
|
||||
nameCard.setEditedText(name);
|
||||
}
|
||||
|
||||
} else if (typeCard.equals(card)) {
|
||||
typeCard.setHeaderSubtitle(engine.type.getTitle());
|
||||
typeCard.setEditedText(engine.getBaseUrl());
|
||||
if (engine.type == EngineType.GRAPHHOPPER || engine.type == EngineType.ORS) {
|
||||
apiKeyCard.show();
|
||||
} else {
|
||||
apiKeyCard.hide();
|
||||
}
|
||||
|
||||
} else if (vehicleCard.equals(card)) {
|
||||
VehicleType vt = VehicleType.getVehicleByKey(engine.getVehicleKey());
|
||||
vehicleCard.setHeaderSubtitle(vt.getTitle(app));
|
||||
if (vt == VehicleType.CUSTOM) {
|
||||
vehicleCard.showFieldBox();
|
||||
vehicleCard.setEditedText(engine.getVehicleKey());
|
||||
} else {
|
||||
vehicleCard.hideFieldBox();
|
||||
}
|
||||
|
||||
} else if (exampleCard.equals(card)) {
|
||||
exampleCard.setEditedText(getTestUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setupButtons() {
|
||||
boolean nightMode = isNightMode();
|
||||
View cancelButton = view.findViewById(R.id.dismiss_button);
|
||||
|
@ -391,149 +312,167 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
|||
|
||||
view.findViewById(R.id.buttons_divider).setVisibility(View.VISIBLE);
|
||||
|
||||
View saveButton = view.findViewById(R.id.right_bottom_button);
|
||||
saveButton = view.findViewById(R.id.right_bottom_button);
|
||||
UiUtilities.setupDialogButton(nightMode, saveButton,
|
||||
UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_save);
|
||||
saveButton.setVisibility(View.VISIBLE);
|
||||
saveButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
saveChanges();
|
||||
onSaveEngine();
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void saveChanges() {
|
||||
OnlineRoutingEngine engineToSave;
|
||||
if (isEditingMode()) {
|
||||
engineToSave = new OnlineRoutingEngine(editedEngineKey, engine.type, engine.getVehicleKey());
|
||||
private void changeEngineType(EngineType type) {
|
||||
OnlineRoutingEngine tmp = (OnlineRoutingEngine) engine.clone();
|
||||
engine = OnlineRoutingFactory.createEngine(type, tmp.getParams());
|
||||
|
||||
// after changing the type, select the vehicle
|
||||
// with the same name that was selected before
|
||||
VehicleType previous = tmp.getSelectedVehicleType();
|
||||
VehicleType next = null;
|
||||
for (VehicleType vt : engine.getAllowedVehicles()) {
|
||||
if (Algorithms.objectEquals(previous.getTitle(app), vt.getTitle(app))) {
|
||||
next = vt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
String vehicleKey;
|
||||
if (next != null) {
|
||||
vehicleKey = next.equals(CUSTOM_VEHICLE) ? customVehicleKey : next.getKey();
|
||||
} else {
|
||||
engineToSave = OnlineRoutingEngine.createNewEngine(engine.type, engine.getVehicleKey(), null);
|
||||
vehicleKey = engine.getAllowedVehicles().get(0).getKey();
|
||||
}
|
||||
engine.put(EngineParameter.VEHICLE_KEY, vehicleKey);
|
||||
|
||||
engineToSave.putParameter(EngineParameter.CUSTOM_NAME, engine.customName);
|
||||
engineToSave.putParameter(EngineParameter.CUSTOM_URL, engine.customServerUrl);
|
||||
if (engine.type == EngineType.GRAPHHOPPER || engine.type == EngineType.ORS) {
|
||||
engineToSave.putParameter(EngineParameter.API_KEY, engine.apiKey);
|
||||
setupVehicleTypes();
|
||||
generateUniqueNameIfNeeded();
|
||||
updateCardViews(nameCard, typeCard, vehicleCard, exampleCard);
|
||||
}
|
||||
|
||||
private void generateUniqueNameIfNeeded() {
|
||||
if (engine.get(EngineParameter.CUSTOM_NAME) == null) {
|
||||
engine.remove(EngineParameter.NAME_INDEX);
|
||||
if (hasNameDuplicate(engine.getName(app))) {
|
||||
int index = 0;
|
||||
do {
|
||||
engine.put(EngineParameter.NAME_INDEX, String.valueOf(++index));
|
||||
} while (hasNameDuplicate(engine.getName(app)));
|
||||
}
|
||||
}
|
||||
|
||||
helper.saveEngine(engineToSave);
|
||||
}
|
||||
|
||||
private void deleteEngine() {
|
||||
helper.deleteEngine(editedEngineKey);
|
||||
}
|
||||
|
||||
private String getTestUrl() {
|
||||
List<LatLon> path = new ArrayList<>();
|
||||
path.add(selectedLocation.getCityCenterLatLon());
|
||||
path.add(selectedLocation.getCityAirportLatLon());
|
||||
OnlineRoutingEngine tmpEngine =
|
||||
OnlineRoutingEngine.createNewEngine(engine.type, engine.getVehicleKey(), null);
|
||||
tmpEngine.putParameter(EngineParameter.CUSTOM_URL, engine.customServerUrl);
|
||||
tmpEngine.putParameter(EngineParameter.API_KEY, engine.apiKey);
|
||||
return helper.createFullUrl(tmpEngine, path);
|
||||
}
|
||||
|
||||
private void testEngineWork() {
|
||||
final EngineType type = engine.type;
|
||||
final ExampleLocation location = selectedLocation;
|
||||
AndroidNetworkUtils.sendRequestAsync(app, exampleCard.getEditedText(), null,
|
||||
null, false, false, new OnRequestResultListener() {
|
||||
@Override
|
||||
public void onResult(String response) {
|
||||
boolean resultOk = false;
|
||||
if (response != null) {
|
||||
try {
|
||||
JSONObject obj = new JSONObject(response);
|
||||
|
||||
if (type == EngineType.GRAPHHOPPER) {
|
||||
resultOk = obj.has("paths");
|
||||
} else if (type == EngineType.OSRM) {
|
||||
resultOk = obj.has("routes");
|
||||
} else if (type == EngineType.ORS) {
|
||||
resultOk = obj.has("features");
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
|
||||
}
|
||||
}
|
||||
showTestResults(resultOk, location);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showTestResults(boolean resultOk, ExampleLocation location) {
|
||||
testResultsContainer.setVisibility(View.VISIBLE);
|
||||
ImageView ivImage = testResultsContainer.findViewById(R.id.icon);
|
||||
TextView tvTitle = testResultsContainer.findViewById(R.id.title);
|
||||
TextView tvDescription = testResultsContainer.findViewById(R.id.description);
|
||||
if (resultOk) {
|
||||
ivImage.setImageDrawable(getContentIcon(R.drawable.ic_action_gdirections_dark));
|
||||
tvTitle.setText(getString(R.string.shared_string_ok));
|
||||
private void checkCustomNameUnique(@NonNull OnlineRoutingEngine engine) {
|
||||
if (hasNameDuplicate(engine.getName(app))) {
|
||||
nameCard.showFieldBoxError(getString(R.string.message_name_is_already_exists));
|
||||
saveButton.setEnabled(false);
|
||||
} else {
|
||||
ivImage.setImageDrawable(getContentIcon(R.drawable.ic_action_alert));
|
||||
tvTitle.setText(getString(R.string.message_error_recheck_parameters));
|
||||
nameCard.hideFieldBoxError();
|
||||
saveButton.setEnabled(true);
|
||||
}
|
||||
tvDescription.setText(location.getName());
|
||||
}
|
||||
|
||||
private boolean hasNameDuplicate(@NonNull String name) {
|
||||
for (OnlineRoutingEngine engine : helper.getEnginesExceptMentioned(editedEngineKey)) {
|
||||
if (Algorithms.objectEquals(engine.getName(app), name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void onSaveEngine() {
|
||||
if (engine != null) {
|
||||
helper.saveEngine(engine);
|
||||
}
|
||||
}
|
||||
|
||||
private void onDeleteEngine() {
|
||||
helper.deleteEngine(engine);
|
||||
}
|
||||
|
||||
private boolean isEditingMode() {
|
||||
return editedEngineKey != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
saveState(outState);
|
||||
private String getTestUrl() {
|
||||
List<LatLon> path = new ArrayList<>();
|
||||
path.add(selectedLocation.getCityCenterLatLon());
|
||||
path.add(selectedLocation.getCityAirportLatLon());
|
||||
return engine.getFullUrl(path);
|
||||
}
|
||||
|
||||
private void saveState(Bundle outState) {
|
||||
outState.putString(ENGINE_NAME_KEY, engine.customName);
|
||||
outState.putString(ENGINE_SERVER_KEY, engine.type.name());
|
||||
outState.putString(ENGINE_SERVER_URL_KEY, engine.customServerUrl);
|
||||
outState.putString(ENGINE_VEHICLE_TYPE_KEY, engine.vehicleType.name());
|
||||
outState.putString(ENGINE_CUSTOM_VEHICLE_KEY, engine.customVehicleKey);
|
||||
outState.putString(ENGINE_API_KEY_KEY, engine.apiKey);
|
||||
outState.putString(EXAMPLE_LOCATION_KEY, selectedLocation.name());
|
||||
if (appMode != null) {
|
||||
outState.putString(APP_MODE_KEY, appMode.getStringKey());
|
||||
}
|
||||
outState.putString(EDITED_ENGINE_KEY, editedEngineKey);
|
||||
}
|
||||
|
||||
private void restoreState(Bundle savedState) {
|
||||
engine.customName = savedState.getString(ENGINE_NAME_KEY);
|
||||
engine.type = EngineType.valueOf(savedState.getString(ENGINE_SERVER_KEY));
|
||||
engine.customServerUrl = savedState.getString(ENGINE_SERVER_URL_KEY);
|
||||
engine.vehicleType = VehicleType.valueOf(savedState.getString(ENGINE_VEHICLE_TYPE_KEY));
|
||||
engine.customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY);
|
||||
engine.apiKey = savedState.getString(ENGINE_API_KEY_KEY);
|
||||
selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY));
|
||||
appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null);
|
||||
editedEngineKey = savedState.getString(EDITED_ENGINE_KEY);
|
||||
}
|
||||
|
||||
private void initState() {
|
||||
engine.type = EngineType.values()[0];
|
||||
engine.vehicleType = VehicleType.values()[0];
|
||||
selectedLocation = ExampleLocation.values()[0];
|
||||
|
||||
if (isEditingMode()) {
|
||||
OnlineRoutingEngine editedEngine = helper.getEngineByKey(editedEngineKey);
|
||||
if (editedEngine != null) {
|
||||
engine.customName = editedEngine.getParameter(EngineParameter.CUSTOM_NAME);
|
||||
engine.type = editedEngine.getType();
|
||||
String vehicleKey = editedEngine.getVehicleKey();
|
||||
if (vehicleKey != null) {
|
||||
VehicleType vehicleType = VehicleType.getVehicleByKey(vehicleKey);
|
||||
if (vehicleType == VehicleType.CUSTOM) {
|
||||
engine.customVehicleKey = vehicleKey;
|
||||
}
|
||||
engine.vehicleType = vehicleType;
|
||||
private void testEngineWork() {
|
||||
final OnlineRoutingEngine requestedEngine = (OnlineRoutingEngine) engine.clone();
|
||||
final ExampleLocation location = selectedLocation;
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
StringBuilder message = new StringBuilder();
|
||||
boolean resultOk = false;
|
||||
try {
|
||||
String response = helper.makeRequest(exampleCard.getEditedText());
|
||||
resultOk = requestedEngine.parseServerMessage(message, response);
|
||||
} catch (IOException | JSONException e) {
|
||||
message.append(e.toString());
|
||||
}
|
||||
engine.apiKey = editedEngine.getParameter(EngineParameter.API_KEY);
|
||||
showTestResults(resultOk, message.toString(), location);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void showTestResults(final boolean resultOk,
|
||||
final @NonNull String message,
|
||||
final @NonNull ExampleLocation location) {
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
testResultsContainer.setVisibility(View.VISIBLE);
|
||||
ImageView ivImage = testResultsContainer.findViewById(R.id.icon);
|
||||
TextView tvTitle = testResultsContainer.findViewById(R.id.title);
|
||||
TextView tvDescription = testResultsContainer.findViewById(R.id.description);
|
||||
if (resultOk) {
|
||||
ivImage.setImageDrawable(getContentIcon(R.drawable.ic_action_gdirections_dark));
|
||||
tvTitle.setText(getString(R.string.shared_string_ok));
|
||||
} else {
|
||||
ivImage.setImageDrawable(getContentIcon(R.drawable.ic_action_alert));
|
||||
tvTitle.setText(String.format(getString(R.string.message_server_error), message));
|
||||
}
|
||||
tvDescription.setText(location.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateCardViews(@NonNull BaseCard... cardsToUpdate) {
|
||||
for (BaseCard card : cardsToUpdate) {
|
||||
if (nameCard.equals(card)) {
|
||||
if (Algorithms.isEmpty(engine.get(EngineParameter.CUSTOM_NAME))) {
|
||||
nameCard.setEditedText(engine.getName(app));
|
||||
}
|
||||
|
||||
} else if (typeCard.equals(card)) {
|
||||
typeCard.setHeaderSubtitle(engine.getType().getTitle());
|
||||
typeCard.setEditedText(engine.getBaseUrl());
|
||||
if (engine.isParameterAllowed(EngineParameter.API_KEY)) {
|
||||
apiKeyCard.show();
|
||||
} else {
|
||||
apiKeyCard.hide();
|
||||
}
|
||||
|
||||
} else if (vehicleCard.equals(card)) {
|
||||
VehicleType vt = engine.getSelectedVehicleType();
|
||||
vehicleCard.setHeaderSubtitle(vt.getTitle(app));
|
||||
if (vt.equals(CUSTOM_VEHICLE)) {
|
||||
vehicleCard.showFieldBox();
|
||||
vehicleCard.setEditedText(customVehicleKey);
|
||||
} else {
|
||||
vehicleCard.hideFieldBox();
|
||||
}
|
||||
|
||||
} else if (exampleCard.equals(card)) {
|
||||
exampleCard.setEditedText(getTestUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -546,7 +485,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
|||
}
|
||||
|
||||
private boolean isNightMode() {
|
||||
return !app.getSettings().isLightContentForMode(appMode);
|
||||
return !app.getSettings().isLightContentForMode(getAppMode());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private ApplicationMode getAppMode() {
|
||||
return appMode != null ? appMode : app.getSettings().getApplicationMode();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -563,9 +507,64 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
|||
return UiUtilities.getInflater(mapActivity, isNightMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
saveState(outState);
|
||||
}
|
||||
|
||||
private void saveState(@NonNull Bundle outState) {
|
||||
outState.putString(ENGINE_TYPE_KEY, engine.getType().name());
|
||||
for (EngineParameter key : EngineParameter.values()) {
|
||||
String value = engine.get(key);
|
||||
if (value != null) {
|
||||
outState.putString(key.name(), value);
|
||||
}
|
||||
}
|
||||
outState.putString(ENGINE_CUSTOM_VEHICLE_KEY, customVehicleKey);
|
||||
outState.putString(EXAMPLE_LOCATION_KEY, selectedLocation.name());
|
||||
outState.putString(APP_MODE_KEY, getAppMode().getStringKey());
|
||||
outState.putString(EDITED_ENGINE_KEY, editedEngineKey);
|
||||
}
|
||||
|
||||
private void restoreState(@NonNull Bundle savedState) {
|
||||
String typeKey = savedState.getString(ENGINE_TYPE_KEY);
|
||||
EngineType type = EngineType.getTypeByName(typeKey);
|
||||
engine = OnlineRoutingFactory.createEngine(type);
|
||||
for (EngineParameter key : EngineParameter.values()) {
|
||||
String value = savedState.getString(key.name());
|
||||
if (value != null) {
|
||||
engine.put(key, value);
|
||||
}
|
||||
}
|
||||
customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY);
|
||||
selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY));
|
||||
appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null);
|
||||
editedEngineKey = savedState.getString(EngineParameter.KEY.name());
|
||||
}
|
||||
|
||||
private void initState() {
|
||||
selectedLocation = ExampleLocation.values()[0];
|
||||
OnlineRoutingEngine editedEngine = helper.getEngineByKey(editedEngineKey);
|
||||
if (editedEngine != null) {
|
||||
engine = (OnlineRoutingEngine) editedEngine.clone();
|
||||
if (Algorithms.objectEquals(engine.getSelectedVehicleType(), CUSTOM_VEHICLE)) {
|
||||
customVehicleKey = engine.get(EngineParameter.VEHICLE_KEY);
|
||||
}
|
||||
} else {
|
||||
engine = OnlineRoutingFactory.createEngine(EngineType.values()[0]);
|
||||
String vehicle = engine.getAllowedVehicles().get(0).getKey();
|
||||
engine.put(EngineParameter.VEHICLE_KEY, vehicle);
|
||||
customVehicleKey = "";
|
||||
if (editedEngineKey != null) {
|
||||
engine.put(EngineParameter.KEY, editedEngineKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void showInstance(@NonNull FragmentActivity activity,
|
||||
@NonNull ApplicationMode appMode,
|
||||
String editedEngineKey) {
|
||||
@Nullable String editedEngineKey) {
|
||||
FragmentManager fm = activity.getSupportFragmentManager();
|
||||
if (!fm.isStateSaved() && fm.findFragmentByTag(OnlineRoutingEngineFragment.TAG) == null) {
|
||||
OnlineRoutingEngineFragment fragment = new OnlineRoutingEngineFragment();
|
||||
|
@ -576,34 +575,4 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
|
|||
.addToBackStack(TAG).commitAllowingStateLoss();
|
||||
}
|
||||
}
|
||||
|
||||
private static class OnlineRoutingEngineObject {
|
||||
private String customName;
|
||||
private EngineType type;
|
||||
private String customServerUrl;
|
||||
private VehicleType vehicleType;
|
||||
private String customVehicleKey;
|
||||
private String apiKey;
|
||||
|
||||
public String getVehicleKey() {
|
||||
if (vehicleType == VehicleType.CUSTOM) {
|
||||
return customVehicleKey;
|
||||
}
|
||||
return vehicleType.getKey();
|
||||
}
|
||||
|
||||
public String getName(Context ctx) {
|
||||
if (customName != null) {
|
||||
return customName;
|
||||
}
|
||||
return OnlineRoutingEngine.getStandardName(ctx, type, getVehicleKey());
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
if (Algorithms.isEmpty(customServerUrl)) {
|
||||
return type.getStandardUrl();
|
||||
}
|
||||
return customServerUrl;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,27 @@
|
|||
package net.osmand.plus.profiles;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import net.osmand.plus.R;
|
||||
|
||||
public class OnlineRoutingEngineDataObject extends ProfileDataObject {
|
||||
|
||||
private int order;
|
||||
|
||||
public OnlineRoutingEngineDataObject(String name,
|
||||
String description,
|
||||
String stringKey) {
|
||||
String stringKey,
|
||||
int order) {
|
||||
super(name, description, stringKey, R.drawable.ic_world_globe_dark, false, null);
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NonNull ProfileDataObject another) {
|
||||
if (another instanceof OnlineRoutingEngineDataObject) {
|
||||
OnlineRoutingEngineDataObject anotherEngine = (OnlineRoutingEngineDataObject) another;
|
||||
return Integer.compare(this.order, anotherEngine.order);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.content.Context;
|
|||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
|
||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
|
||||
import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.router.GeneralRouter;
|
||||
|
@ -56,7 +56,22 @@ public class ProfileDataUtils {
|
|||
Collections.sort(fileNames, new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String s, String t1) {
|
||||
return s.equals(OSMAND_NAVIGATION) ? -1 : t1.equals(OSMAND_NAVIGATION) ? 1 : s.compareToIgnoreCase(t1);
|
||||
// OsmAnd navigation should be at the top of the list
|
||||
if (s.equals(OSMAND_NAVIGATION)) {
|
||||
return -1;
|
||||
} else if (t1.equals(OSMAND_NAVIGATION)) {
|
||||
return 1;
|
||||
|
||||
// Online navigation should be at the bottom of the list
|
||||
} else if (s.equals(ONLINE_NAVIGATION)) {
|
||||
return 1;
|
||||
} else if (t1.equals(ONLINE_NAVIGATION)) {
|
||||
return -1;
|
||||
|
||||
// Other sorted by file names
|
||||
} else {
|
||||
return s.compareToIgnoreCase(t1);
|
||||
}
|
||||
}
|
||||
});
|
||||
for (String fileName : fileNames) {
|
||||
|
@ -71,9 +86,11 @@ public class ProfileDataUtils {
|
|||
|
||||
public static List<OnlineRoutingEngineDataObject> getOnlineRoutingProfiles(OsmandApplication app) {
|
||||
List<OnlineRoutingEngineDataObject> objects = new ArrayList<>();
|
||||
for (OnlineRoutingEngine engine : app.getOnlineRoutingHelper().getEngines()) {
|
||||
List<OnlineRoutingEngine> engines = app.getOnlineRoutingHelper().getEngines();
|
||||
for (int i = 0; i < engines.size(); i++) {
|
||||
OnlineRoutingEngine engine = engines.get(i);
|
||||
objects.add(new OnlineRoutingEngineDataObject(
|
||||
engine.getName(app), engine.getBaseUrl(), engine.getStringKey()));
|
||||
engine.getName(app), engine.getBaseUrl(), engine.getStringKey(), i));
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
|
|
|
@ -39,8 +39,9 @@ import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
|||
import net.osmand.plus.helpers.FontCache;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingEngineFragment;
|
||||
import net.osmand.plus.onlinerouting.ui.OnlineRoutingEngineFragment;
|
||||
import net.osmand.router.RoutingConfiguration;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
|
@ -250,7 +251,7 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet {
|
|||
tvTitle.setText(profile.getName());
|
||||
tvDescription.setText(profile.getDescription());
|
||||
|
||||
boolean isSelected = setupSelected && profile.getStringKey().equals(selectedItemKey);
|
||||
boolean isSelected = setupSelected && Algorithms.objectEquals(profile.getStringKey(), selectedItemKey);
|
||||
int iconColor;
|
||||
if (dialogMode == DialogMode.NAVIGATION_PROFILE) {
|
||||
iconColor = isSelected ? activeColorResId : iconDefaultColorResId;
|
||||
|
|
|
@ -2,7 +2,6 @@ package net.osmand.plus.routing;
|
|||
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Base64;
|
||||
|
||||
|
@ -20,16 +19,14 @@ import net.osmand.binary.BinaryMapIndexReader;
|
|||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.LocationPoint;
|
||||
import net.osmand.data.WptLocationPoint;
|
||||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
|
||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.settings.backend.CommonPreference;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.TargetPointsHelper;
|
||||
import net.osmand.plus.TargetPointsHelper.TargetPoint;
|
||||
import net.osmand.plus.Version;
|
||||
import net.osmand.plus.render.NativeOsmandLibrary;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.router.GeneralRouter;
|
||||
|
@ -48,21 +45,16 @@ import net.osmand.router.RoutingConfiguration.Builder;
|
|||
import net.osmand.router.RoutingContext;
|
||||
import net.osmand.router.TurnType;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.GeoPolylineParserUtil;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -1210,8 +1202,12 @@ public class RouteProvider {
|
|||
private RouteCalculationResult findOnlineRoute(RouteCalculationParams params) throws IOException, JSONException {
|
||||
OnlineRoutingHelper helper = params.ctx.getOnlineRoutingHelper();
|
||||
String stringKey = params.mode.getRoutingProfile();
|
||||
List<LatLon> route = helper.calculateRouteOnline(helper.getEngineByKey(stringKey), getFullPathFromParams(params));
|
||||
if (!route.isEmpty()) {
|
||||
OnlineRoutingEngine engine = helper.getEngineByKey(stringKey);
|
||||
List<LatLon> route = null;
|
||||
if (engine != null) {
|
||||
route = helper.calculateRouteOnline(engine, getFullPathFromParams(params));
|
||||
}
|
||||
if (!Algorithms.isEmpty(route)) {
|
||||
List<Location> res = new ArrayList<>();
|
||||
for (LatLon pt : route) {
|
||||
WptPt wpt = new WptPt();
|
||||
|
|
|
@ -7,8 +7,9 @@ import androidx.annotation.Nullable;
|
|||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter;
|
||||
import net.osmand.plus.onlinerouting.EngineParameter;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingFactory;
|
||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
|
||||
|
||||
import org.json.JSONException;
|
||||
|
@ -93,8 +94,8 @@ public class OnlineRoutingSettingsItem extends CollectionSettingsItem<OnlineRout
|
|||
int number = 0;
|
||||
while (true) {
|
||||
number++;
|
||||
OnlineRoutingEngine renamedItem = OnlineRoutingEngine.createNewEngine(item.getType(), item.getVehicleKey(), item.getParams());
|
||||
renamedItem.putParameter(EngineParameter.CUSTOM_NAME, renamedItem.getName(app) + "_" + number);
|
||||
OnlineRoutingEngine renamedItem = OnlineRoutingFactory.createEngine(item.getType(), item.getParams());
|
||||
renamedItem.put(EngineParameter.CUSTOM_NAME, renamedItem.getName(app) + "_" + number);
|
||||
if (!isDuplicate(renamedItem)) {
|
||||
return renamedItem;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ import net.osmand.plus.helpers.SearchHistoryHelper;
|
|||
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
|
||||
import net.osmand.plus.mapmarkers.MapMarker;
|
||||
import net.osmand.plus.mapmarkers.MapMarkersGroup;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
|
||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
|
||||
import net.osmand.plus.osmedit.OpenstreetmapPoint;
|
||||
import net.osmand.plus.osmedit.OsmEditingPlugin;
|
||||
import net.osmand.plus.osmedit.OsmNotesPoint;
|
||||
|
|
|
@ -23,7 +23,7 @@ import net.osmand.plus.helpers.FileNameTranslationHelper;
|
|||
import net.osmand.plus.helpers.GpxUiHelper;
|
||||
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
|
||||
import net.osmand.plus.mapmarkers.MapMarker;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
|
||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
import net.osmand.plus.profiles.ProfileIconColors;
|
||||
import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources;
|
||||
|
|
|
@ -40,7 +40,7 @@ import net.osmand.plus.helpers.FileNameTranslationHelper;
|
|||
import net.osmand.plus.helpers.GpxUiHelper;
|
||||
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
|
||||
import net.osmand.plus.mapmarkers.MapMarkersGroup;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
|
||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
|
||||
import net.osmand.plus.osmedit.OpenstreetmapPoint;
|
||||
import net.osmand.plus.osmedit.OsmEditingPlugin;
|
||||
import net.osmand.plus.osmedit.OsmNotesPoint;
|
||||
|
|
|
@ -34,7 +34,7 @@ import net.osmand.plus.base.BaseOsmAndFragment;
|
|||
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
|
||||
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
|
||||
import net.osmand.plus.mapmarkers.MapMarker;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
|
||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
|
||||
import net.osmand.plus.osmedit.OpenstreetmapPoint;
|
||||
import net.osmand.plus.osmedit.OsmNotesPoint;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
|
|
|
@ -36,7 +36,7 @@ import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
|
|||
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
|
||||
import net.osmand.plus.mapmarkers.MapMarker;
|
||||
import net.osmand.plus.mapmarkers.MapMarkersGroup;
|
||||
import net.osmand.plus.onlinerouting.OnlineRoutingEngine;
|
||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
|
||||
import net.osmand.plus.osmedit.OpenstreetmapPoint;
|
||||
import net.osmand.plus.osmedit.OsmNotesPoint;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
|
|
|
@ -27,7 +27,7 @@ import net.osmand.util.Algorithms;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import static net.osmand.plus.onlinerouting.OnlineRoutingEngine.ONLINE_ROUTING_ENGINE_PREFIX;
|
||||
import static net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.ONLINE_ROUTING_ENGINE_PREFIX;
|
||||
import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILES_LIST_UPDATED_ARG;
|
||||
import static net.osmand.plus.profiles.SelectProfileBottomSheet.PROFILE_KEY_ARG;
|
||||
import static net.osmand.plus.routepreparationmenu.RouteOptionsBottomSheet.DIALOG_MODE_KEY;
|
||||
|
|
Loading…
Reference in a new issue