From baa888d9105c19d49ea69a7bb46e9fa70aa769e6 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Wed, 11 Jul 2012 23:50:21 +0200 Subject: [PATCH] Smart route recalculation --- .../net/osmand/router/BinaryRoutePlanner.java | 27 ++++++++++--------- .../src/net/osmand/swing/MapRouterLayer.java | 5 +--- .../plus/routing/RouteCalculationResult.java | 14 ++++++++++ .../osmand/plus/routing/RouteProvider.java | 13 ++++++--- .../osmand/plus/routing/RoutingHelper.java | 7 ++--- Osmand-kernel/osmand/src/java_wrap.cpp | 13 ++++----- 6 files changed, 50 insertions(+), 29 deletions(-) diff --git a/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java b/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java index 405101e485..4bcafb118c 100644 --- a/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java +++ b/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java @@ -210,19 +210,19 @@ public class BinaryRoutePlanner { TLongObjectHashMap visitedDirectSegments = new TLongObjectHashMap(); TLongObjectHashMap visitedOppositeSegments = new TLongObjectHashMap(); - if(ctx.previouslyCalculatedRoute != null && ctx.previouslyCalculatedRoute.size() >0) { + boolean runRecalculation = ctx.previouslyCalculatedRoute != null && ctx.previouslyCalculatedRoute.size() > 0; + if (runRecalculation) { RouteSegment previous = null; - int previousSegmentEnd = 0; - for(RouteSegmentResult rr : ctx.previouslyCalculatedRoute) { + for (RouteSegmentResult rr : ctx.previouslyCalculatedRoute) { RouteSegment segment = new RouteSegment(rr.getObject(), rr.getEndPointIndex()); - if(previous != null) { - segment.parentRoute = previous; - segment.parentSegmentEnd = previousSegmentEnd; + if (previous != null) { + previous.parentRoute = segment; + previous.parentSegmentEnd = rr.getStartPointIndex(); + long t = (rr.getObject().getId() << ROUTE_POINTS) + segment.segmentStart; + visitedOppositeSegments.put(t, segment); } previous = segment; - previousSegmentEnd = rr.getStartPointIndex(); - long t = rr.getObject().getId() << ROUTE_POINTS + rr.getEndPointIndex(); - visitedOppositeSegments.put(t, segment); + } end = previous; } @@ -266,8 +266,9 @@ public class BinaryRoutePlanner { if (graphReverseSegments.isEmpty() || graphDirectSegments.isEmpty() || routeFound) { break; } - if(ctx.previouslyCalculatedRoute != null){ - // nothing change + if(runRecalculation) { + // nothing to do + inverse = false; } else if (!init) { inverse = !inverse; init = true; @@ -1105,14 +1106,14 @@ public class BinaryRoutePlanner { if(attachedRoutes != null){ for(RouteSegmentResult rs : attachedRoutes){ double ex = MapUtils.degreesDiff(rs.getBearingBegin(), rr.getBearingBegin()); - if(ex < 60 && ex >= 0) { + if(ex < 45 && ex >= 0) { kl = true; int lns = rs.getObject().getLanes(); if (lns > 0) { right += lns; } speak = speak || !highwayLowEnd(rs.getObject().getHighway()); - } else if(ex > -60 && ex <= 0) { + } else if(ex > -45 && ex <= 0) { kr = true; int lns = rs.getObject().getLanes(); if (lns > 0) { diff --git a/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java b/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java index 237ca1086e..5c0c4a19ac 100644 --- a/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java +++ b/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java @@ -591,9 +591,6 @@ public class MapRouterLayer implements MapPanelLayer { ctx.previouslyCalculatedRoute = previousRoute; log.info("Use " + config.routerName + "mode for routing"); -// int dir = DataExtractionSettings.getSettings().getRouteDirection(); -// ctx.setPlanRoadDirection(dir); - // find closest way RouteSegment st = router.findRouteSegment(start.getLatitude(), start.getLongitude(), ctx); if (st == null) { @@ -664,7 +661,7 @@ public class MapRouterLayer implements MapPanelLayer { }); List searchRoute = router.searchRoute(ctx, st, e, false); - previousRoute = searchRoute; + this.previousRoute = searchRoute; if (animateRoutingCalculation) { playPauseButton.setVisible(false); nextTurn.setText("FINISH"); diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java index ca13d9749e..87ec9dfffd 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java @@ -96,6 +96,20 @@ public class RouteCalculationResult { } } } + + public List getOriginalRoute() { + if (segments.size() == 0) { + return null; + } + List list = new ArrayList(); + list.add(segments.get(0)); + for (int i = 1; i < segments.size(); i++) { + if (segments.get(i - 1) != segments.get(i)) { + list.add(segments.get(i)); + } + } + return list; + } /** * PREPARATION diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 640b4de5aa..f3780e44e2 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -147,7 +147,7 @@ public class RouteProvider { public RouteCalculationResult calculateRouteImpl(Location start, LatLon end, ApplicationMode mode, RouteService type, Context ctx, - GPXRouteParams gpxRoute, boolean fast, boolean leftSide){ + GPXRouteParams gpxRoute, RouteCalculationResult previousToRecalculate, boolean fast, boolean leftSide){ long time = System.currentTimeMillis(); if (start != null && end != null) { if(log.isInfoEnabled()){ @@ -162,7 +162,11 @@ public class RouteProvider { } else if (type == RouteService.ORS) { res = findORSRoute(start, end, mode, fast, ctx, leftSide); } else if (type == RouteService.OSMAND) { - res = findVectorMapsRoute(start, end, mode, fast, (OsmandApplication)ctx.getApplicationContext(), leftSide); + List originalRoute = null; + if(previousToRecalculate != null) { + originalRoute = previousToRecalculate.getOriginalRoute(); + } + res = findVectorMapsRoute(start, end, mode, fast, (OsmandApplication)ctx.getApplicationContext(), originalRoute, leftSide); } else { res = findCloudMadeRoute(start, end, mode, ctx, fast, leftSide); } @@ -302,7 +306,9 @@ public class RouteProvider { return new RouteCalculationResult(res, null, start, end, null, ctx, leftSide, true); } - protected RouteCalculationResult findVectorMapsRoute(Location start, LatLon end, ApplicationMode mode, boolean fast, OsmandApplication app, boolean leftSide) throws IOException { + protected RouteCalculationResult findVectorMapsRoute(Location start, LatLon end, ApplicationMode mode, boolean fast, OsmandApplication app, + List previousRoute, + boolean leftSide) throws IOException { BinaryMapIndexReader[] files = app.getResourceManager().getRoutingMapFiles(); BinaryRoutePlanner router = new BinaryRoutePlanner(NativeOsmandLibrary.getLoadedLibrary(), files); File routingXml = app.getSettings().extendOsmandPath(ResourceManager.ROUTING_XML); @@ -326,6 +332,7 @@ public class RouteProvider { p = GeneralRouterProfile.CAR; } RoutingContext ctx = new RoutingContext(config.build(p.name().toLowerCase(), !fast, start.hasBearing() ? start.getBearing() / 180d * Math.PI : null)); + ctx.previouslyCalculatedRoute = previousRoute; RouteSegment st= router.findRouteSegment(start.getLatitude(), start.getLongitude(), ctx); if (st == null) { return new RouteCalculationResult(app.getString(R.string.starting_point_too_far)); diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index dbcdd24790..785438d9e4 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -235,7 +235,8 @@ public class RoutingHelper { } if (calculateRoute) { - recalculateRouteInBackground(lastFixedLocation, finalLocation, currentGPXRoute); + recalculateRouteInBackground(lastFixedLocation, finalLocation, currentGPXRoute, + route.isCalculated()? route : null); } return locationProjection; } @@ -497,7 +498,7 @@ public class RoutingHelper { - private void recalculateRouteInBackground(final Location start, final LatLon end, final GPXRouteParams gpxRoute){ + private void recalculateRouteInBackground(final Location start, final LatLon end, final GPXRouteParams gpxRoute, final RouteCalculationResult previousRoute){ if (start == null || end == null) { return; } @@ -514,7 +515,7 @@ public class RoutingHelper { @Override public void run() { boolean leftSide = settings.LEFT_SIDE_NAVIGATION.get(); - RouteCalculationResult res = provider.calculateRouteImpl(start, end, mode, service, context, gpxRoute, fastRouteMode, + RouteCalculationResult res = provider.calculateRouteImpl(start, end, mode, service, context, gpxRoute, previousRoute, fastRouteMode, leftSide); synchronized (RoutingHelper.this) { if (res.isCalculated()) { diff --git a/Osmand-kernel/osmand/src/java_wrap.cpp b/Osmand-kernel/osmand/src/java_wrap.cpp index b5a031feef..f1aae94779 100644 --- a/Osmand-kernel/osmand/src/java_wrap.cpp +++ b/Osmand-kernel/osmand/src/java_wrap.cpp @@ -15,6 +15,8 @@ JavaVM* globalJVM = NULL; void loadJniRenderingContext(JNIEnv* env); void loadJniRenderingRules(JNIEnv* env); +jclass jclassIntArray ; +jclass jclassString; extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { @@ -24,6 +26,8 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) globalJVM = vm; loadJniRenderingContext(globalJniEnv); loadJniRenderingRules(globalJniEnv); + jclassIntArray = findClass(globalJniEnv, "[I"); + jclassString = findClass(globalJniEnv, "java/lang/String"); osmand_log_print(LOG_INFO, "JNI_OnLoad completed"); @@ -441,8 +445,7 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_loadRout RoutingIndex ind; ind.filePointer = filepointer; ind.name = getString(ienv, regName); - jclass jclIntArray = findClass(ienv, "[I"); - jclass jclstring = findClass(ienv, "java/lang/String"); + std::vector result; SearchQuery q(left, right, top, bottom); @@ -453,7 +456,7 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_loadRout if (result[i] != NULL) { jintArray nameInts = ienv->NewIntArray(result[i]->names.size()); jobjectArray nameStrings = ienv->NewObjectArray(result[i]->names.size(), - jclstring, NULL); + jclassString, NULL); jint ar[result[i]->names.size()]; UNORDERED(map)::iterator itNames = result[i]->names.begin(); jsize sz = 0; @@ -502,7 +505,7 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_loadRout ienv->DeleteLocalRef(restrictions); - jobjectArray pointTypes = ienv->NewObjectArray(result[i]->pointTypes.size(), jclIntArray, NULL); + jobjectArray pointTypes = ienv->NewObjectArray(result[i]->pointTypes.size(), jclassIntArray, NULL); for(jint k = 0; k < result[i]->pointTypes.size(); k++ ) { std::vector ts = result[i]->pointTypes[k]; if (ts.size() > 0) { @@ -522,8 +525,6 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_loadRout ienv->DeleteLocalRef(robj); } } - ienv->DeleteLocalRef(jclIntArray); - ienv->DeleteLocalRef(jclstring); for (unsigned int i = 0; i < result.size(); i++) { delete result[i]; result[i] = NULL;