From 0ef5d7ba6e4705161407be5b37c13c3d42376fcd Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Sat, 29 Sep 2012 13:55:44 +0200 Subject: [PATCH] Fix string values and add option for optimal/non-optimal route calculation --- OsmAnd/res/layout/calculate_route.xml | 2 + OsmAnd/res/values-ru/strings.xml | 6 +- OsmAnd/res/values/strings.xml | 2 + .../src/net/osmand/plus/OsmandSettings.java | 16 ++ .../plus/activities/MainMenuActivity.java | 2 +- .../osmand/plus/activities/MapActivity.java | 2 +- .../plus/activities/MapActivityActions.java | 41 +++-- .../osmand/plus/routing/RouteAnimation.java | 2 - .../plus/routing/RouteCalcuationParams.java | 28 ++++ .../osmand/plus/routing/RouteProvider.java | 154 +++++++++--------- .../osmand/plus/routing/RoutingHelper.java | 48 +++--- 11 files changed, 187 insertions(+), 116 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/routing/RouteCalcuationParams.java diff --git a/OsmAnd/res/layout/calculate_route.xml b/OsmAnd/res/layout/calculate_route.xml index e6c4724581..f146857810 100644 --- a/OsmAnd/res/layout/calculate_route.xml +++ b/OsmAnd/res/layout/calculate_route.xml @@ -11,6 +11,8 @@ + + diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 497aaaedc7..83ba8ebfd3 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -1,5 +1,7 @@ -Загрузите или обновите локальные данные. + + Рассчитать неоптимальный (возможно) маршрут на длинные дистанции + Загрузите или обновите локальные данные. \nЧтобы получить дополнительную информацию о карте, выделите её в списке. Удерживайте карту, если вы хотите удалить или деактивировать. \nДанные на устройстве (%1$s свободно): "Изменения в 0.8.3: @@ -735,7 +737,7 @@ ГГГ.ГГГГ ГГГ ММ.МММММ ГГГ ММ СС.ССССС - Отобразить на карте + Показать Отмена Выберите адрес Регион diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 8e6dc4fa18..d0d5d0c823 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,7 +9,9 @@ 1. All your modified/created strings are in the top of the file (to make easier find what\'s translated). PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy --> + Calculate possibly non-optimal route over long distances Changes in 0.8.4 : + Updated Changes in 0.8.3 : \n\t* Waypoints diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 17523b82b8..2f52caa5a8 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -59,6 +59,8 @@ public class OsmandSettings { boolean set(T obj); + boolean setModeValue(ApplicationMode m, T obj); + T getModeValue(ApplicationMode m); String getId(); @@ -144,6 +146,11 @@ public class OsmandSettings { public ApplicationMode getModeValue(ApplicationMode m) { return m; } + + @Override + public boolean setModeValue(ApplicationMode m, ApplicationMode obj) { + throw new UnsupportedOperationException(); + } }; public ApplicationMode getApplicationMode(){ @@ -241,6 +248,14 @@ public class OsmandSettings { defaultValues.put(mode, defValue); } + @Override + public boolean setModeValue(ApplicationMode mode, T obj){ + if(global) { + return set(obj); + } + return setValue(getProfilePreferences(mode), obj); + } + public T getProfileDefaultValue(){ if(global){ return defaultValue; @@ -596,6 +611,7 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference FAST_ROUTE_MODE = new BooleanPreference("fast_route_mode", true).makeProfile(); + public final OsmandPreference OPTIMAL_ROUTE_MODE = new BooleanPreference("optimal_route_mode", true).makeProfile(); public final OsmandPreference SHOW_SPEED_LIMITS = new BooleanPreference("show_speed_limits", true).makeGlobal().cache(); public final OsmandPreference SHOW_CAMERAS = new BooleanPreference("show_cameras", true).makeGlobal().cache(); diff --git a/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java b/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java index c6a3c416e0..785363f9d8 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java @@ -134,7 +134,7 @@ public class MainMenuActivity extends Activity { SharedPreferences prefs = activity.getApplicationContext().getSharedPreferences("net.osmand.settings", MODE_WORLD_READABLE); // only one commit should be with contribution version flag -// prefs.edit().putBoolean(CONTRIBUTION_VERSION_FLAG, true).commit(); + prefs.edit().putBoolean(CONTRIBUTION_VERSION_FLAG, true).commit(); if (prefs.contains(CONTRIBUTION_VERSION_FLAG)) { SpannableString content = new SpannableString(textVersion); content.setSpan(new ClickableSpan() { diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 2cc635eec6..a5ac39f332 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -292,7 +292,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe Object toShow = settings.getAndClearObjectToShow(); if(settings.isRouteToPointNavigateAndClear()){ // always enable and follow and let calculate it (GPS is not accessible in garage) - mapActions.getDirections(getLastKnownLocation(), false); + mapActions.getDirections(null, null, false); } if(mapLabelToShow != null && latLonToShow != null){ mapLayers.getContextMenuLayer().setSelectedObject(toShow); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 72700eaeaa..46f1e51e2e 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -407,13 +407,14 @@ public class MapActivityActions implements DialogProvider { } - public void getDirections(final Location from, boolean gpxRouteEnabled) { + public void getDirections(final Location fromOrCurrent, final LatLon to, boolean gpxRouteEnabled) { final RoutingHelper routingHelper = mapActivity.getRoutingHelper(); Builder builder = new AlertDialog.Builder(mapActivity); View view = mapActivity.getLayoutInflater().inflate(R.layout.calculate_route, null); + final CheckBox optimal = (CheckBox) view.findViewById(R.id.OptimalCheckox); final ToggleButton[] buttons = new ToggleButton[ApplicationMode.values().length]; buttons[ApplicationMode.CAR.ordinal()] = (ToggleButton) view.findViewById(R.id.CarButton); buttons[ApplicationMode.BICYCLE.ordinal()] = (ToggleButton) view.findViewById(R.id.BicycleButton); @@ -426,11 +427,16 @@ public class MapActivityActions implements DialogProvider { if (buttons[i] != null) { final int ind = i; ToggleButton b = buttons[i]; - b.setChecked(appMode == ApplicationMode.values()[i]); + final ApplicationMode buttonAppMode = ApplicationMode.values()[i]; + b.setChecked(appMode == buttonAppMode); + if(b.isChecked()) { + optimal.setChecked(settings.OPTIMAL_ROUTE_MODE.getModeValue(buttonAppMode)); + } b.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { + optimal.setChecked(settings.OPTIMAL_ROUTE_MODE.getModeValue(buttonAppMode)); for (int j = 0; j < buttons.length; j++) { if (buttons[j] != null) { if (buttons[j].isChecked() != (ind == j)) { @@ -461,15 +467,23 @@ public class MapActivityActions implements DialogProvider { DialogInterface.OnClickListener onlyShowCall = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + if(to != null) { + mapActivity.navigateToPoint(to, false, -1); + } if (!checkPointToNavigate()) { return; } + Location from = fromOrCurrent; + if(from == null) { + from = mapActivity.getLastKnownLocation(); + } if (from == null) { AccessibleToast.makeText(mapActivity, R.string.unknown_from_location, Toast.LENGTH_LONG).show(); return; } ApplicationMode mode = getAppMode(buttons, settings); routingHelper.setAppMode(mode); + settings.OPTIMAL_ROUTE_MODE.setModeValue(mode, optimal.isChecked()); settings.FOLLOW_THE_ROUTE.set(false); settings.FOLLOW_THE_GPX_ROUTE.set(null); routingHelper.setFollowingMode(false); @@ -481,12 +495,19 @@ public class MapActivityActions implements DialogProvider { DialogInterface.OnClickListener followCall = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + if(to != null) { + mapActivity.navigateToPoint(to, false, -1); + } if (!checkPointToNavigate()) { return; } boolean msg = true; - Location current = from; - if (!mapActivity.isPointAccurateForRouting(from)) { + Location current = fromOrCurrent; + if(current == null) { + current = mapActivity.getLastKnownLocation(); + } + + if (!mapActivity.isPointAccurateForRouting(current)) { current = null; } Location lastKnownLocation = mapActivity.getLastKnownLocation(); @@ -507,6 +528,9 @@ public class MapActivityActions implements DialogProvider { DialogInterface.OnClickListener useGpxNavigation = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + if(to != null) { + mapActivity.navigateToPoint(to, false, -1); + } ApplicationMode mode = getAppMode(buttons, settings); navigateUsingGPX(mode); } @@ -734,16 +758,14 @@ public class MapActivityActions implements DialogProvider { } else if (standardId == R.string.context_menu_item_navigate_point) { mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, -1); } else if (standardId == R.string.context_menu_item_directions) { - Location loc = mapActivity.getLastKnownLocation(); - mapActivity.navigateToPoint(new LatLon(latitude, longitude), false, -1); // always enable and follow and let calculate it (GPS is not accessible in garage) - getDirections(loc, true); + getDirections(null, new LatLon(latitude, longitude), true); } else if (standardId == R.string.context_menu_item_show_route) { if (checkPointToNavigate()) { Location loc = new Location("map"); loc.setLatitude(latitude); loc.setLongitude(longitude); - getDirections(loc, true); + getDirections(loc, null, true); } } else if (standardId == R.string.context_menu_item_intermediate_point) { mapActivity.navigateToPoint(new LatLon(latitude, longitude), true, mapActivity.getIntermediatePoints().size()); @@ -957,8 +979,7 @@ public class MapActivityActions implements DialogProvider { if (routingHelper.isRouteCalculated()) { aboutRoute(); } else { - Location loc = mapActivity.getLastKnownLocation(); - getDirections(loc, true); + getDirections(null, null, true); } return true; } diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteAnimation.java b/OsmAnd/src/net/osmand/plus/routing/RouteAnimation.java index 148c1d3914..b2ed5f17d7 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteAnimation.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteAnimation.java @@ -11,10 +11,8 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.routing.RouteProvider.GPXRouteParams; import android.app.AlertDialog; import android.app.AlertDialog.Builder; -import android.content.Context; import android.content.DialogInterface; import android.location.Location; -import android.location.LocationManager; import android.view.View; import android.widget.SeekBar; import android.widget.TextView; diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalcuationParams.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalcuationParams.java new file mode 100644 index 0000000000..6d19a29845 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalcuationParams.java @@ -0,0 +1,28 @@ +package net.osmand.plus.routing; + +import java.util.List; + +import net.osmand.osm.LatLon; +import net.osmand.plus.activities.ApplicationMode; +import net.osmand.plus.routing.RouteProvider.GPXRouteParams; +import net.osmand.plus.routing.RouteProvider.RouteService; +import net.osmand.router.Interruptable; +import android.content.Context; +import android.location.Location; + +public class RouteCalcuationParams { + + public Location start; + public LatLon end; + public List intermediates; + + public Context ctx; + public ApplicationMode mode; + public RouteService type; + public GPXRouteParams gpxRoute; + public RouteCalculationResult previousToRecalculate; + public boolean fast; + public boolean optimal; + public boolean leftSide; + public Interruptable interruptable; +} diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index b6fe240544..73cdaf6683 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -27,7 +27,6 @@ import net.osmand.GPXUtilities.Track; import net.osmand.GPXUtilities.TrkSegment; import net.osmand.GPXUtilities.WptPt; import net.osmand.LogUtil; -import net.osmand.access.AccessibleToast; import net.osmand.binary.BinaryMapIndexReader; import net.osmand.osm.LatLon; import net.osmand.plus.OsmandApplication; @@ -40,7 +39,6 @@ import net.osmand.router.BinaryRoutePlanner; import net.osmand.router.BinaryRoutePlanner.RouteSegment; import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter.GeneralRouterProfile; -import net.osmand.router.Interruptable; import net.osmand.router.RouteSegmentResult; import net.osmand.router.RoutingConfiguration; import net.osmand.router.RoutingContext; @@ -53,10 +51,8 @@ import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; -import android.app.ActivityManager; import android.content.Context; import android.location.Location; -import android.widget.Toast; public class RouteProvider { private static final org.apache.commons.logging.Log log = LogUtil.getLog(RouteProvider.class); @@ -150,29 +146,25 @@ public class RouteProvider { - public RouteCalculationResult calculateRouteImpl(Location start, LatLon end, List intermediates, ApplicationMode mode, RouteService type, Context ctx, - GPXRouteParams gpxRoute, RouteCalculationResult previousToRecalculate, boolean fast, boolean leftSide, Interruptable interruptable){ + public RouteCalculationResult calculateRouteImpl(RouteCalcuationParams params){ long time = System.currentTimeMillis(); - if (start != null && end != null) { + if (params.start != null && params.end != null) { if(log.isInfoEnabled()){ - log.info("Start finding route from " + start + " to " + end +" using " + type.getName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + log.info("Start finding route from " + params.start + " to " + params.end +" using " + + params.type.getName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } try { RouteCalculationResult res; - if(gpxRoute != null && !gpxRoute.points.isEmpty()){ - res = calculateGpxRoute(start, end, gpxRoute, ctx, leftSide); - } else if (type == RouteService.YOURS) { - res = findYOURSRoute(start, end, mode, fast, ctx, leftSide); - } else if (type == RouteService.ORS) { - res = findORSRoute(start, end, mode, fast, ctx, leftSide); - } else if (type == RouteService.OSMAND) { - List originalRoute = null; - if(previousToRecalculate != null) { - originalRoute = previousToRecalculate.getOriginalRoute(); - } - res = findVectorMapsRoute(start, end, intermediates, mode, (OsmandApplication)ctx.getApplicationContext(), originalRoute, leftSide, interruptable); + if(params.gpxRoute != null && !params.gpxRoute.points.isEmpty()){ + res = calculateGpxRoute(params); + } else if (params.type == RouteService.YOURS) { + res = findYOURSRoute(params); + } else if (params.type == RouteService.ORS) { + res = findORSRoute(params); + } else if (params.type == RouteService.OSMAND) { + res = findVectorMapsRoute(params); } else { - res = findCloudMadeRoute(start, end, intermediates, mode, ctx, fast, leftSide); + res = findCloudMadeRoute(params); } if(log.isInfoEnabled() ){ log.info("Finding route contained " + res.getImmutableLocations().size() + " points for " + (System.currentTimeMillis() - time) + " ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ @@ -189,27 +181,29 @@ public class RouteProvider { return new RouteCalculationResult(null); } - private RouteCalculationResult calculateGpxRoute(Location start, LatLon end, GPXRouteParams params, Context ctx, boolean leftSide) { + + private RouteCalculationResult calculateGpxRoute(RouteCalcuationParams pars) { RouteCalculationResult res; // get the closest point to start and to end float minDist = Integer.MAX_VALUE; int startI = 0; + GPXRouteParams params = pars.gpxRoute; List gpxRoute = params.points; int endI = gpxRoute.size(); - if (start != null) { + if (pars.start != null) { for (int i = 0; i < gpxRoute.size(); i++) { - float d = gpxRoute.get(i).distanceTo(start); + float d = gpxRoute.get(i).distanceTo(pars.start); if (d < minDist) { startI = i; minDist = d; } } } else { - start = gpxRoute.get(0); + pars.start = gpxRoute.get(0); } Location l = new Location("temp"); //$NON-NLS-1$ - l.setLatitude(end.getLatitude()); - l.setLongitude(end.getLongitude()); + l.setLatitude(pars.end.getLatitude()); + l.setLongitude(pars.end.getLongitude()); minDist = Integer.MAX_VALUE; // get in reverse order taking into account ways with cycle for (int i = gpxRoute.size() - 1; i >= startI; i--) { @@ -222,7 +216,8 @@ public class RouteProvider { } ArrayList sublist = new ArrayList(gpxRoute.subList(startI, endI)); if(params.directions == null){ - res = new RouteCalculationResult(sublist, params.directions, start, end, null, null, ctx, leftSide, true); + res = new RouteCalculationResult(sublist, params.directions, pars.start, pars.end, null, null, + pars.ctx, pars.leftSide, true); } else { List subdirections = new ArrayList(); for (RouteDirectionInfo info : params.directions) { @@ -237,7 +232,8 @@ public class RouteProvider { subdirections.add(ch); } } - res = new RouteCalculationResult(sublist, subdirections, start, end, null, null, ctx, leftSide, true); + res = new RouteCalculationResult(sublist, subdirections, pars.start, pars.end, null, null, + pars.ctx, pars.leftSide, true); } return res; } @@ -252,23 +248,23 @@ public class RouteProvider { - protected RouteCalculationResult findYOURSRoute(Location start, LatLon end, ApplicationMode mode, boolean fast, Context ctx, boolean leftSide) throws MalformedURLException, IOException, + protected RouteCalculationResult findYOURSRoute(RouteCalcuationParams params) throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException { List res = new ArrayList(); StringBuilder uri = new StringBuilder(); uri.append("http://www.yournavigation.org/api/1.0/gosmore.php?format=kml"); //$NON-NLS-1$ - uri.append("&flat=").append(start.getLatitude()); //$NON-NLS-1$ - uri.append("&flon=").append(start.getLongitude()); //$NON-NLS-1$ - uri.append("&tlat=").append(end.getLatitude()); //$NON-NLS-1$ - uri.append("&tlon=").append(end.getLongitude()); //$NON-NLS-1$ - if(ApplicationMode.PEDESTRIAN == mode){ + uri.append("&flat=").append(params.start.getLatitude()); //$NON-NLS-1$ + uri.append("&flon=").append(params.start.getLongitude()); //$NON-NLS-1$ + uri.append("&tlat=").append(params.end.getLatitude()); //$NON-NLS-1$ + uri.append("&tlon=").append(params.end.getLongitude()); //$NON-NLS-1$ + if(ApplicationMode.PEDESTRIAN == params.mode){ uri.append("&v=foot") ; //$NON-NLS-1$ - } else if(ApplicationMode.BICYCLE == mode){ + } else if(ApplicationMode.BICYCLE == params.mode){ uri.append("&v=bicycle") ; //$NON-NLS-1$ } else { uri.append("&v=motorcar"); //$NON-NLS-1$ } - uri.append("&fast=").append(fast ? "1" : "0").append("&layer=mapnik"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + uri.append("&fast=").append(params.fast ? "1" : "0").append("&layer=mapnik"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ log.info("URL route " + uri); URL url = new URL(uri.toString()); URLConnection connection = url.openConnection(); @@ -307,12 +303,12 @@ public class RouteProvider { } } - return new RouteCalculationResult(res, null, start, end, null, null, ctx, leftSide, true); + return new RouteCalculationResult(res, null, params.start, params.end, null, null, + params.ctx, params.leftSide, true); } - protected RouteCalculationResult findVectorMapsRoute(Location start, LatLon end, List intermediates, ApplicationMode mode, OsmandApplication app, - List previousRoute, - boolean leftSide, Interruptable interruptable) throws IOException { + protected RouteCalculationResult findVectorMapsRoute(RouteCalcuationParams params) throws IOException { + OsmandApplication app = (OsmandApplication) params.ctx.getApplicationContext(); BinaryMapIndexReader[] files = app.getResourceManager().getRoutingMapFiles(); BinaryRoutePlanner router = new BinaryRoutePlanner(); File routingXml = app.getSettings().extendOsmandPath(ResourceManager.ROUTING_XML); @@ -328,9 +324,9 @@ public class RouteProvider { } GeneralRouterProfile p ; - if (mode == ApplicationMode.BICYCLE) { + if (params.mode == ApplicationMode.BICYCLE) { p = GeneralRouterProfile.BICYCLE; - } else if (mode == ApplicationMode.PEDESTRIAN) { + } else if (params.mode == ApplicationMode.PEDESTRIAN) { p = GeneralRouterProfile.PEDESTRIAN; } else { p = GeneralRouterProfile.CAR; @@ -355,26 +351,33 @@ public class RouteProvider { float mb = (1 << 20); Runtime rt = Runtime.getRuntime(); // make visible - int memoryLimit = (int) (0.9 * ((rt.maxMemory() - rt.totalMemory()) + rt.freeMemory()) / mb); + int memoryLimit = (int) (0.95 * ((rt.maxMemory() - rt.totalMemory()) + rt.freeMemory()) / mb); log.warn("Use " + memoryLimit + " MB Free " + rt.freeMemory() / mb + " of " + rt.totalMemory() / mb + " max " + rt.maxMemory() / mb); - RoutingConfiguration cf = config.build(p.name().toLowerCase(), start.hasBearing() ? start.getBearing() / 180d * Math.PI : null, + RoutingConfiguration cf = config.build(p.name().toLowerCase(), params.start.hasBearing() ? + params.start.getBearing() / 180d * Math.PI : null, memoryLimit, specialization); + if(!params.optimal){ + cf.heuristicCoefficient *= 1.5; + } RoutingContext ctx = new RoutingContext(cf, NativeOsmandLibrary.getLoadedLibrary(), files); - ctx.interruptable = interruptable; - ctx.previouslyCalculatedRoute = previousRoute; - RouteSegment st= router.findRouteSegment(start.getLatitude(), start.getLongitude(), ctx); + ctx.interruptable = params.interruptable; + if(params.previousToRecalculate != null) { + ctx.previouslyCalculatedRoute = params.previousToRecalculate.getOriginalRoute(); + } + RouteSegment st= router.findRouteSegment(params.start.getLatitude(), params.start.getLongitude(), ctx); if (st == null) { return new RouteCalculationResult(app.getString(R.string.starting_point_too_far)); } - RouteSegment en = router.findRouteSegment(end.getLatitude(), end.getLongitude(), ctx); + RouteSegment en = router.findRouteSegment(params.end.getLatitude(), + params.end.getLongitude(), ctx); if (en == null) { return new RouteCalculationResult(app.getString(R.string.ending_point_too_far)); } List inters = new ArrayList(); - if (intermediates != null) { + if (params.intermediates != null) { int ind = 1; - for (LatLon il : intermediates) { + for (LatLon il : params.intermediates) { RouteSegment is = router.findRouteSegment(il.getLatitude(), il.getLongitude(), ctx); if (is == null) { return new RouteCalculationResult(app.getString(R.string.intermediate_point_too_far, "'" + ind + "'")); @@ -386,15 +389,16 @@ public class RouteProvider { try { List result; if(inters.size() > 0){ - result = router.searchRoute(ctx, st, en, inters, leftSide); + result = router.searchRoute(ctx, st, en, inters, params.leftSide); } else { - result = router.searchRoute(ctx, st, en, leftSide); + result = router.searchRoute(ctx, st, en, params.leftSide); } if(result == null || result.isEmpty()) { // something really strange better to see that message on the scren return new RouteCalculationResult("Empty result"); } else { - return new RouteCalculationResult(result, start, end, intermediates, app, leftSide); + return new RouteCalculationResult(result, params.start, params.end, + params.intermediates, app, params.leftSide); } } catch (InterruptedException e) { return new RouteCalculationResult("Route calculation was interrupted"); @@ -411,19 +415,19 @@ public class RouteProvider { } - protected RouteCalculationResult findCloudMadeRoute(Location start, LatLon end, List intermediates, ApplicationMode mode, Context ctx, boolean fast, boolean leftSide) + protected RouteCalculationResult findCloudMadeRoute(RouteCalcuationParams params) throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException { List res = new ArrayList(); List directions = null; StringBuilder uri = new StringBuilder(); // possibly hide that API key because it is privacy of osmand uri.append("http://routes.cloudmade.com/A6421860EBB04234AB5EF2D049F2CD8F/api/0.3/"); //$NON-NLS-1$ - uri.append(start.getLatitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$ - uri.append(start.getLongitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$ - if(intermediates != null && intermediates.size() > 0) { + uri.append(params.start.getLatitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$ + uri.append(params.start.getLongitude() + "").append(","); //$NON-NLS-1$ //$NON-NLS-2$ + if(params.intermediates != null && params.intermediates.size() > 0) { uri.append("["); boolean first = true; - for(LatLon il : intermediates) { + for(LatLon il : params.intermediates) { if(!first){ uri.append(","); } else { @@ -434,18 +438,18 @@ public class RouteProvider { } uri.append("],"); } - uri.append(end.getLatitude() + "").append(","); //$NON-NLS-1$//$NON-NLS-2$ - uri.append(end.getLongitude() + "").append("/"); //$NON-NLS-1$ //$NON-NLS-2$ + uri.append(params.end.getLatitude() + "").append(","); //$NON-NLS-1$//$NON-NLS-2$ + uri.append(params.end.getLongitude() + "").append("/"); //$NON-NLS-1$ //$NON-NLS-2$ float speed = 1.5f; - if (ApplicationMode.PEDESTRIAN == mode) { + if (ApplicationMode.PEDESTRIAN == params.mode) { uri.append("foot.gpx"); //$NON-NLS-1$ - } else if (ApplicationMode.BICYCLE == mode) { + } else if (ApplicationMode.BICYCLE == params.mode) { speed = 5.5f; uri.append("bicycle.gpx"); //$NON-NLS-1$ } else { speed = 15.3f; - if (fast) { + if (params.fast) { uri.append("car.gpx"); //$NON-NLS-1$ } else { uri.append("car/shortest.gpx"); //$NON-NLS-1$ @@ -455,10 +459,11 @@ public class RouteProvider { log.info("URL route " + uri); URL url = new URL(uri.toString()); URLConnection connection = url.openConnection(); - GPXFile gpxFile = GPXUtilities.loadGPXFile(ctx, connection.getInputStream(), false); - directions = parseCloudmadeRoute(res, gpxFile, false, leftSide, speed); + GPXFile gpxFile = GPXUtilities.loadGPXFile(params.ctx, connection.getInputStream(), false); + directions = parseCloudmadeRoute(res, gpxFile, false, params.leftSide, speed); - return new RouteCalculationResult(res, directions, start, end, intermediates, null, ctx, leftSide, true); + return new RouteCalculationResult(res, directions, params.start, params.end, params.intermediates, + null, params.ctx, params.leftSide, true); } private static List parseCloudmadeRoute(List res, GPXFile gpxFile, boolean osmandRouter, @@ -577,15 +582,14 @@ public class RouteProvider { return directions; } - protected RouteCalculationResult findORSRoute(Location start, LatLon end, ApplicationMode mode, boolean fast, Context ctx, - boolean leftSide) throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError, + protected RouteCalculationResult findORSRoute(RouteCalcuationParams params) throws MalformedURLException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException { List res = new ArrayList(); String rpref = "Fastest"; - if (ApplicationMode.PEDESTRIAN == mode) { + if (ApplicationMode.PEDESTRIAN == params.mode) { rpref = "Pedestrian"; - } else if (ApplicationMode.BICYCLE == mode) { + } else if (ApplicationMode.BICYCLE == params.mode) { rpref = "Bicycle"; // } else if (ApplicationMode.LOWTRAFFIC == mode) { // rpref = "BicycleSafety"; @@ -595,13 +599,13 @@ public class RouteProvider { // rpref = "BicycleRoute"; // } else if (ApplicationMode.MTBIKE == mode) { // rpref = "BicycleMTB"; - } else if (!fast) { + } else if (!params.fast) { rpref = "Shortest"; } StringBuilder request = new StringBuilder(); - request.append("http://openls.geog.uni-heidelberg.de/osm/eu/routing?").append("start=").append(start.getLongitude()).append(',') - .append(start.getLatitude()).append("&end=").append(end.getLongitude()).append(',').append(end.getLatitude()) + request.append("http://openls.geog.uni-heidelberg.de/osm/eu/routing?").append("start=").append(params.start.getLongitude()).append(',') + .append(params.start.getLatitude()).append("&end=").append(params.end.getLongitude()).append(',').append(params.end.getLatitude()) .append("&preference=").append(rpref); // TODO if we would get instructions from the service, we could use this language setting // .append("&language=").append(Locale.getDefault().getLanguage()); @@ -637,7 +641,7 @@ public class RouteProvider { } } - return new RouteCalculationResult(res, null, start, end, null, null, ctx, leftSide, true); + return new RouteCalculationResult(res, null, params.start, params.end, null, null, params.ctx, params.leftSide, true); } public GPXFile createOsmandRouterGPX(RouteCalculationResult srcRoute){ diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index 7759a12cce..0c73b8d79a 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -254,8 +254,8 @@ public class RoutingHelper { } if (calculateRoute) { - recalculateRouteInBackground(currentLocation, finalLocation, intermediatePoints, currentGPXRoute, - route.isCalculated()? route : null); + recalculateRouteInBackground(currentLocation, finalLocation, intermediatePoints, currentGPXRoute, route.isCalculated() ? route + : null); } double projectDist = mode == ApplicationMode.CAR ? posTolerance : posTolerance / 2; if(returnUpdatedLocation && locationProjection != null && currentLocation.distanceTo(locationProjection) < projectDist) { @@ -569,26 +569,15 @@ public class RoutingHelper { private class RouteRecalculationThread extends Thread implements Interruptable { - private final Location start; - private final LatLon end; - private final GPXRouteParams gpxRoute; - private final RouteCalculationResult previousRoute; - private RouteService service; private boolean interrupted = false; - private final List intermediates; + private final RouteCalcuationParams params; - public RouteRecalculationThread(String name, - Location start, LatLon end, List intermediates, GPXRouteParams gpxRoute, RouteCalculationResult previousRoute){ + public RouteRecalculationThread(String name, RouteCalcuationParams params) { super(name); - this.start = start; - this.end = end; - this.intermediates = intermediates; - this.gpxRoute = gpxRoute; - this.previousRoute = previousRoute; - service = settings.ROUTER_SERVICE.getModeValue(mode); - + this.params = params; + params.interruptable = this; } - + public void stopCalculation(){ interrupted = true; } @@ -600,10 +589,8 @@ public class RoutingHelper { @Override public void run() { - boolean leftSide = settings.LEFT_SIDE_NAVIGATION.get(); - boolean fastRoute = settings.FAST_ROUTE_MODE.get(); - RouteCalculationResult res = provider.calculateRouteImpl(start, end, intermediates, mode, service, app, gpxRoute, previousRoute, fastRoute, - leftSide, this); + + RouteCalculationResult res = provider.calculateRouteImpl(params); if (interrupted) { currentRunningJob = null; return; @@ -611,7 +598,7 @@ public class RoutingHelper { synchronized (RoutingHelper.this) { if (res.isCalculated()) { - setNewRoute(res, start); + setNewRoute(res, params.start); } else { evalWaitInterval = evalWaitInterval * 3 / 2; evalWaitInterval = Math.min(evalWaitInterval, 120000); @@ -622,7 +609,7 @@ public class RoutingHelper { if (res.isCalculated()) { showMessage(app.getString(R.string.new_route_calculated_dist) + ": " + OsmAndFormatter.getFormattedDistance(res.getWholeDistance(), app)); //$NON-NLS-1$ - } else if (service != RouteService.OSMAND && !settings.isInternetConnectionAvailable()) { + } else if (params.type != RouteService.OSMAND && !settings.isInternetConnectionAvailable()) { showMessage(app.getString(R.string.error_calculating_route) + ":\n" + app.getString(R.string.internet_connection_required_for_online_route), Toast.LENGTH_LONG); //$NON-NLS-1$ } else { @@ -644,8 +631,19 @@ public class RoutingHelper { if(currentRunningJob == null){ // do not evaluate very often if (System.currentTimeMillis() - lastTimeEvaluatedRoute > evalWaitInterval) { + RouteCalcuationParams params = new RouteCalcuationParams(); + params.start = start; + params.end = end; + params.intermediates = intermediates; + params.gpxRoute = gpxRoute; + params.previousToRecalculate = previousRoute; + params.leftSide = settings.LEFT_SIDE_NAVIGATION.get(); + params.optimal = settings.OPTIMAL_ROUTE_MODE.get(); + params.fast = settings.FAST_ROUTE_MODE.get(); + params.type = settings.ROUTER_SERVICE.getModeValue(mode); + params.mode = mode; synchronized (this) { - currentRunningJob = new RouteRecalculationThread("Calculating route", start, end, intermediates, gpxRoute, previousRoute); //$NON-NLS-1$ + currentRunningJob = new RouteRecalculationThread("Calculating route", params); //$NON-NLS-1$ currentRunningJob.start(); } }