Smart route recalculation

This commit is contained in:
Victor Shcherb 2012-07-11 23:50:21 +02:00
parent b9f2473be0
commit baa888d910
6 changed files with 50 additions and 29 deletions

View file

@ -210,19 +210,19 @@ public class BinaryRoutePlanner {
TLongObjectHashMap<RouteSegment> visitedDirectSegments = new TLongObjectHashMap<RouteSegment>(); TLongObjectHashMap<RouteSegment> visitedDirectSegments = new TLongObjectHashMap<RouteSegment>();
TLongObjectHashMap<RouteSegment> visitedOppositeSegments = new TLongObjectHashMap<RouteSegment>(); TLongObjectHashMap<RouteSegment> visitedOppositeSegments = new TLongObjectHashMap<RouteSegment>();
if(ctx.previouslyCalculatedRoute != null && ctx.previouslyCalculatedRoute.size() >0) { boolean runRecalculation = ctx.previouslyCalculatedRoute != null && ctx.previouslyCalculatedRoute.size() > 0;
if (runRecalculation) {
RouteSegment previous = null; RouteSegment previous = null;
int previousSegmentEnd = 0; for (RouteSegmentResult rr : ctx.previouslyCalculatedRoute) {
for(RouteSegmentResult rr : ctx.previouslyCalculatedRoute) {
RouteSegment segment = new RouteSegment(rr.getObject(), rr.getEndPointIndex()); RouteSegment segment = new RouteSegment(rr.getObject(), rr.getEndPointIndex());
if(previous != null) { if (previous != null) {
segment.parentRoute = previous; previous.parentRoute = segment;
segment.parentSegmentEnd = previousSegmentEnd; previous.parentSegmentEnd = rr.getStartPointIndex();
long t = (rr.getObject().getId() << ROUTE_POINTS) + segment.segmentStart;
visitedOppositeSegments.put(t, segment);
} }
previous = segment; previous = segment;
previousSegmentEnd = rr.getStartPointIndex();
long t = rr.getObject().getId() << ROUTE_POINTS + rr.getEndPointIndex();
visitedOppositeSegments.put(t, segment);
} }
end = previous; end = previous;
} }
@ -266,8 +266,9 @@ public class BinaryRoutePlanner {
if (graphReverseSegments.isEmpty() || graphDirectSegments.isEmpty() || routeFound) { if (graphReverseSegments.isEmpty() || graphDirectSegments.isEmpty() || routeFound) {
break; break;
} }
if(ctx.previouslyCalculatedRoute != null){ if(runRecalculation) {
// nothing change // nothing to do
inverse = false;
} else if (!init) { } else if (!init) {
inverse = !inverse; inverse = !inverse;
init = true; init = true;
@ -1105,14 +1106,14 @@ public class BinaryRoutePlanner {
if(attachedRoutes != null){ if(attachedRoutes != null){
for(RouteSegmentResult rs : attachedRoutes){ for(RouteSegmentResult rs : attachedRoutes){
double ex = MapUtils.degreesDiff(rs.getBearingBegin(), rr.getBearingBegin()); double ex = MapUtils.degreesDiff(rs.getBearingBegin(), rr.getBearingBegin());
if(ex < 60 && ex >= 0) { if(ex < 45 && ex >= 0) {
kl = true; kl = true;
int lns = rs.getObject().getLanes(); int lns = rs.getObject().getLanes();
if (lns > 0) { if (lns > 0) {
right += lns; right += lns;
} }
speak = speak || !highwayLowEnd(rs.getObject().getHighway()); speak = speak || !highwayLowEnd(rs.getObject().getHighway());
} else if(ex > -60 && ex <= 0) { } else if(ex > -45 && ex <= 0) {
kr = true; kr = true;
int lns = rs.getObject().getLanes(); int lns = rs.getObject().getLanes();
if (lns > 0) { if (lns > 0) {

View file

@ -591,9 +591,6 @@ public class MapRouterLayer implements MapPanelLayer {
ctx.previouslyCalculatedRoute = previousRoute; ctx.previouslyCalculatedRoute = previousRoute;
log.info("Use " + config.routerName + "mode for routing"); log.info("Use " + config.routerName + "mode for routing");
// int dir = DataExtractionSettings.getSettings().getRouteDirection();
// ctx.setPlanRoadDirection(dir);
// find closest way // find closest way
RouteSegment st = router.findRouteSegment(start.getLatitude(), start.getLongitude(), ctx); RouteSegment st = router.findRouteSegment(start.getLatitude(), start.getLongitude(), ctx);
if (st == null) { if (st == null) {
@ -664,7 +661,7 @@ public class MapRouterLayer implements MapPanelLayer {
}); });
List<RouteSegmentResult> searchRoute = router.searchRoute(ctx, st, e, false); List<RouteSegmentResult> searchRoute = router.searchRoute(ctx, st, e, false);
previousRoute = searchRoute; this.previousRoute = searchRoute;
if (animateRoutingCalculation) { if (animateRoutingCalculation) {
playPauseButton.setVisible(false); playPauseButton.setVisible(false);
nextTurn.setText("FINISH"); nextTurn.setText("FINISH");

View file

@ -97,6 +97,20 @@ public class RouteCalculationResult {
} }
} }
public List<RouteSegmentResult> getOriginalRoute() {
if (segments.size() == 0) {
return null;
}
List<RouteSegmentResult> list = new ArrayList<RouteSegmentResult>();
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 * PREPARATION
*/ */

View file

@ -147,7 +147,7 @@ public class RouteProvider {
public RouteCalculationResult calculateRouteImpl(Location start, LatLon end, ApplicationMode mode, RouteService type, Context ctx, 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(); long time = System.currentTimeMillis();
if (start != null && end != null) { if (start != null && end != null) {
if(log.isInfoEnabled()){ if(log.isInfoEnabled()){
@ -162,7 +162,11 @@ public class RouteProvider {
} else if (type == RouteService.ORS) { } else if (type == RouteService.ORS) {
res = findORSRoute(start, end, mode, fast, ctx, leftSide); res = findORSRoute(start, end, mode, fast, ctx, leftSide);
} else if (type == RouteService.OSMAND) { } else if (type == RouteService.OSMAND) {
res = findVectorMapsRoute(start, end, mode, fast, (OsmandApplication)ctx.getApplicationContext(), leftSide); List<RouteSegmentResult> originalRoute = null;
if(previousToRecalculate != null) {
originalRoute = previousToRecalculate.getOriginalRoute();
}
res = findVectorMapsRoute(start, end, mode, fast, (OsmandApplication)ctx.getApplicationContext(), originalRoute, leftSide);
} else { } else {
res = findCloudMadeRoute(start, end, mode, ctx, fast, leftSide); 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); 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<RouteSegmentResult> previousRoute,
boolean leftSide) throws IOException {
BinaryMapIndexReader[] files = app.getResourceManager().getRoutingMapFiles(); BinaryMapIndexReader[] files = app.getResourceManager().getRoutingMapFiles();
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeOsmandLibrary.getLoadedLibrary(), files); BinaryRoutePlanner router = new BinaryRoutePlanner(NativeOsmandLibrary.getLoadedLibrary(), files);
File routingXml = app.getSettings().extendOsmandPath(ResourceManager.ROUTING_XML); File routingXml = app.getSettings().extendOsmandPath(ResourceManager.ROUTING_XML);
@ -326,6 +332,7 @@ public class RouteProvider {
p = GeneralRouterProfile.CAR; p = GeneralRouterProfile.CAR;
} }
RoutingContext ctx = new RoutingContext(config.build(p.name().toLowerCase(), !fast, start.hasBearing() ? start.getBearing() / 180d * Math.PI : null)); 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); RouteSegment st= router.findRouteSegment(start.getLatitude(), start.getLongitude(), ctx);
if (st == null) { if (st == null) {
return new RouteCalculationResult(app.getString(R.string.starting_point_too_far)); return new RouteCalculationResult(app.getString(R.string.starting_point_too_far));

View file

@ -235,7 +235,8 @@ public class RoutingHelper {
} }
if (calculateRoute) { if (calculateRoute) {
recalculateRouteInBackground(lastFixedLocation, finalLocation, currentGPXRoute); recalculateRouteInBackground(lastFixedLocation, finalLocation, currentGPXRoute,
route.isCalculated()? route : null);
} }
return locationProjection; 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) { if (start == null || end == null) {
return; return;
} }
@ -514,7 +515,7 @@ public class RoutingHelper {
@Override @Override
public void run() { public void run() {
boolean leftSide = settings.LEFT_SIDE_NAVIGATION.get(); 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); leftSide);
synchronized (RoutingHelper.this) { synchronized (RoutingHelper.this) {
if (res.isCalculated()) { if (res.isCalculated()) {

View file

@ -15,6 +15,8 @@
JavaVM* globalJVM = NULL; JavaVM* globalJVM = NULL;
void loadJniRenderingContext(JNIEnv* env); void loadJniRenderingContext(JNIEnv* env);
void loadJniRenderingRules(JNIEnv* env); void loadJniRenderingRules(JNIEnv* env);
jclass jclassIntArray ;
jclass jclassString;
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) 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; globalJVM = vm;
loadJniRenderingContext(globalJniEnv); loadJniRenderingContext(globalJniEnv);
loadJniRenderingRules(globalJniEnv); loadJniRenderingRules(globalJniEnv);
jclassIntArray = findClass(globalJniEnv, "[I");
jclassString = findClass(globalJniEnv, "java/lang/String");
osmand_log_print(LOG_INFO, "JNI_OnLoad completed"); osmand_log_print(LOG_INFO, "JNI_OnLoad completed");
@ -441,8 +445,7 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_loadRout
RoutingIndex ind; RoutingIndex ind;
ind.filePointer = filepointer; ind.filePointer = filepointer;
ind.name = getString(ienv, regName); ind.name = getString(ienv, regName);
jclass jclIntArray = findClass(ienv, "[I");
jclass jclstring = findClass(ienv, "java/lang/String");
std::vector<RouteDataObject*> result; std::vector<RouteDataObject*> result;
SearchQuery q(left, right, top, bottom); SearchQuery q(left, right, top, bottom);
@ -453,7 +456,7 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_loadRout
if (result[i] != NULL) { if (result[i] != NULL) {
jintArray nameInts = ienv->NewIntArray(result[i]->names.size()); jintArray nameInts = ienv->NewIntArray(result[i]->names.size());
jobjectArray nameStrings = ienv->NewObjectArray(result[i]->names.size(), jobjectArray nameStrings = ienv->NewObjectArray(result[i]->names.size(),
jclstring, NULL); jclassString, NULL);
jint ar[result[i]->names.size()]; jint ar[result[i]->names.size()];
UNORDERED(map)<int, std::string >::iterator itNames = result[i]->names.begin(); UNORDERED(map)<int, std::string >::iterator itNames = result[i]->names.begin();
jsize sz = 0; jsize sz = 0;
@ -502,7 +505,7 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_loadRout
ienv->DeleteLocalRef(restrictions); 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++ ) { for(jint k = 0; k < result[i]->pointTypes.size(); k++ ) {
std::vector<uint32_t> ts = result[i]->pointTypes[k]; std::vector<uint32_t> ts = result[i]->pointTypes[k];
if (ts.size() > 0) { if (ts.size() > 0) {
@ -522,8 +525,6 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_loadRout
ienv->DeleteLocalRef(robj); ienv->DeleteLocalRef(robj);
} }
} }
ienv->DeleteLocalRef(jclIntArray);
ienv->DeleteLocalRef(jclstring);
for (unsigned int i = 0; i < result.size(); i++) { for (unsigned int i = 0; i < result.size(); i++) {
delete result[i]; delete result[i];
result[i] = NULL; result[i] = NULL;