Smart route recalculation
This commit is contained in:
parent
b9f2473be0
commit
baa888d910
6 changed files with 50 additions and 29 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue