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> 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;
int previousSegmentEnd = 0;
for (RouteSegmentResult rr : ctx.previouslyCalculatedRoute) {
RouteSegment segment = new RouteSegment(rr.getObject(), rr.getEndPointIndex());
if (previous != null) {
segment.parentRoute = previous;
segment.parentSegmentEnd = previousSegmentEnd;
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) {

View file

@ -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<RouteSegmentResult> searchRoute = router.searchRoute(ctx, st, e, false);
previousRoute = searchRoute;
this.previousRoute = searchRoute;
if (animateRoutingCalculation) {
playPauseButton.setVisible(false);
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
*/

View file

@ -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<RouteSegmentResult> 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<RouteSegmentResult> 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));

View file

@ -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()) {

View file

@ -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<RouteDataObject*> 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)<int, std::string >::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<uint32_t> 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;