Tweak bidirectional routing
This commit is contained in:
parent
968ff424d9
commit
8c47374245
4 changed files with 74 additions and 45 deletions
|
@ -32,7 +32,7 @@ public class BinaryRoutePlanner {
|
|||
|
||||
private final static boolean PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
|
||||
private final BinaryMapIndexReader[] map;
|
||||
private static int DEFAULT_HEURISTIC_COEFFICIENT = 1;
|
||||
private static int DEFAULT_HEURISTIC_COEFFICIENT = 3;
|
||||
|
||||
private static final Log log = LogUtil.getLog(BinaryRoutePlanner.class);
|
||||
|
||||
|
@ -159,7 +159,6 @@ public class BinaryRoutePlanner {
|
|||
// measure time
|
||||
ctx.timeToLoad = 0;
|
||||
ctx.visitedSegments = 0;
|
||||
|
||||
long startNanoTime = System.nanoTime();
|
||||
|
||||
// Initializing priority queue to visit way segments
|
||||
|
@ -184,13 +183,6 @@ public class BinaryRoutePlanner {
|
|||
TLongObjectHashMap<RouteSegment> visitedDirectSegments = new TLongObjectHashMap<RouteSegment>();
|
||||
TLongObjectHashMap<RouteSegment> visitedOppositeSegments = new TLongObjectHashMap<RouteSegment>();
|
||||
|
||||
|
||||
// if(reverseWaySearch){
|
||||
// RouteSegment t = start;
|
||||
// start = end;
|
||||
// end = t;
|
||||
// }
|
||||
|
||||
int targetEndX = end.road.getPoint31XTile(end.segmentStart);
|
||||
int targetEndY = end.road.getPoint31YTile(end.segmentStart);
|
||||
int startX = start.road.getPoint31XTile(start.segmentStart);
|
||||
|
@ -222,25 +214,19 @@ public class BinaryRoutePlanner {
|
|||
ctx.visitor.visitSegment(segment);
|
||||
}
|
||||
if (!inverse) {
|
||||
finalDirectRoute = processRouteSegment(ctx, end, false, graphDirectSegments, visitedDirectSegments, targetEndX,
|
||||
RoutePair pair = processRouteSegment(ctx, end, false, graphDirectSegments, visitedDirectSegments, targetEndX,
|
||||
targetEndY, segment, visitedOppositeSegments);
|
||||
if (finalDirectRoute != null) {
|
||||
long nt = (finalDirectRoute.road.getId() << 8l) + finalDirectRoute.segmentEnd;
|
||||
finalReverseRoute = visitedOppositeSegments.get(nt);
|
||||
if(finalReverseRoute != null){
|
||||
finalReverseRoute.segmentEnd = finalDirectRoute.segmentEnd;
|
||||
}
|
||||
if (pair != null) {
|
||||
finalDirectRoute = pair.a;
|
||||
finalReverseRoute = pair.b;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
finalReverseRoute = processRouteSegment(ctx, start, true, graphReverseSegments, visitedOppositeSegments, startX,
|
||||
RoutePair pair = processRouteSegment(ctx, start, true, graphReverseSegments, visitedOppositeSegments, startX,
|
||||
startY, segment, visitedDirectSegments);
|
||||
if (finalReverseRoute != null) {
|
||||
long nt = (finalReverseRoute.road.getId() << 8l) + finalReverseRoute.segmentEnd;
|
||||
finalDirectRoute = visitedDirectSegments.get(nt);
|
||||
if(finalDirectRoute != null){
|
||||
finalDirectRoute.segmentEnd = finalReverseRoute.segmentEnd;
|
||||
}
|
||||
if (pair != null) {
|
||||
finalReverseRoute = pair.a;
|
||||
finalDirectRoute = pair.b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -257,8 +243,7 @@ public class BinaryRoutePlanner {
|
|||
return prepareResult(ctx, start, end, startNanoTime, finalDirectRoute, finalReverseRoute);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void visitAllStartSegments(final RoutingContext ctx, RouteSegment start, PriorityQueue<RouteSegment> graphDirectSegments,
|
||||
TLongObjectHashMap<RouteSegment> visitedSegments, int startX, int startY) throws IOException {
|
||||
|
@ -285,7 +270,7 @@ public class BinaryRoutePlanner {
|
|||
}
|
||||
}
|
||||
|
||||
private RouteSegment processRouteSegment(final RoutingContext ctx, RouteSegment end, boolean reverseWaySearch,
|
||||
private RoutePair processRouteSegment(final RoutingContext ctx, RouteSegment end, boolean reverseWaySearch,
|
||||
PriorityQueue<RouteSegment> graphSegments, TLongObjectHashMap<RouteSegment> visitedSegments, int targetEndX, int targetEndY,
|
||||
RouteSegment segment, TLongObjectHashMap<RouteSegment> oppositeSegments) throws IOException {
|
||||
// Always start from segmentStart (!), not from segmentEnd
|
||||
|
@ -300,12 +285,13 @@ public class BinaryRoutePlanner {
|
|||
long nt = (road.getId() << 8l) + middle;
|
||||
visitedSegments.put(nt, segment);
|
||||
if (oppositeSegments.contains(nt)) {
|
||||
// if(end.road.getId() == road.getId() && end.segmentStart == middle){
|
||||
segment.segmentEnd = middle;
|
||||
return segment;
|
||||
RouteSegment opposite = oppositeSegments.get(nt);
|
||||
opposite.segmentEnd = middle;
|
||||
return new RoutePair(segment, opposite);
|
||||
}
|
||||
|
||||
boolean oneway = ctx.router.isOneWay(road.getHighwayAttributes());
|
||||
boolean oneway = ctx.router.isOneWay(road);
|
||||
boolean minusAllowed = !oneway || reverseWaySearch;
|
||||
boolean plusAllowed = !oneway || !reverseWaySearch;
|
||||
|
||||
|
@ -340,9 +326,10 @@ public class BinaryRoutePlanner {
|
|||
// if we found end point break cycle
|
||||
long nts = (road.getId() << 8l) + segmentEnd;
|
||||
if (oppositeSegments.contains(nts)) {
|
||||
// if(end.road.getId() == road.getId() && end.segmentStart == segmentEnd){
|
||||
segment.segmentEnd = segmentEnd;
|
||||
return segment;
|
||||
RouteSegment opposite = oppositeSegments.get(nts);
|
||||
opposite.segmentEnd = segmentEnd;
|
||||
return new RoutePair(segment, opposite);
|
||||
}
|
||||
visitedSegments.put(nts, segment);
|
||||
|
||||
|
@ -357,8 +344,13 @@ public class BinaryRoutePlanner {
|
|||
if (next != null) {
|
||||
double distOnRoadToPass = squareRootDist(x, y, middlex, middley);
|
||||
double distToFinalPoint = squareRootDist(x, y, targetEndX, targetEndY);
|
||||
processIntersectionsWithWays(ctx, graphSegments, visitedSegments, distOnRoadToPass, distToFinalPoint, segment, road,
|
||||
RouteSegment foundIntersection = processIntersectionsWithWays(ctx, graphSegments, visitedSegments, oppositeSegments,
|
||||
distOnRoadToPass, distToFinalPoint, segment, road,
|
||||
d == 0, segmentEnd, next);
|
||||
if(foundIntersection != null){
|
||||
segment.segmentEnd = segmentEnd;
|
||||
return new RoutePair(segment, foundIntersection);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -366,8 +358,9 @@ public class BinaryRoutePlanner {
|
|||
|
||||
|
||||
|
||||
private void processIntersectionsWithWays(RoutingContext ctx, PriorityQueue<RouteSegment> graphSegments,
|
||||
TLongObjectHashMap<RouteSegment> visitedSegments, double distOnRoadToPass, double distToFinalPoint,
|
||||
private RouteSegment processIntersectionsWithWays(RoutingContext ctx, PriorityQueue<RouteSegment> graphSegments,
|
||||
TLongObjectHashMap<RouteSegment> visitedSegments, TLongObjectHashMap<RouteSegment> oppositeSegments,
|
||||
double distOnRoadToPass, double distToFinalPoint,
|
||||
RouteSegment segment, BinaryMapDataObject road, boolean firstOfSegment, int segmentEnd, RouteSegment next) {
|
||||
|
||||
// This variables can be in routing context
|
||||
|
@ -390,6 +383,11 @@ public class BinaryRoutePlanner {
|
|||
// 3.2 calculate possible ways to put into priority queue
|
||||
while (next != null) {
|
||||
long nts = (next.road.getId() << 8l) + next.segmentStart;
|
||||
if(oppositeSegments.containsKey(nts)){
|
||||
RouteSegment oppSegment = oppositeSegments.get(nts);
|
||||
oppSegment.segmentEnd = next.segmentStart;
|
||||
return oppSegment;
|
||||
}
|
||||
/* next.road.getId() >> 3 (1) != road.getId() >> 3 (1) - used that line for debug with osm map */
|
||||
// road.id could be equal on roundabout, but we should accept them
|
||||
if (!visitedSegments.contains(nts)) {
|
||||
|
@ -455,6 +453,7 @@ public class BinaryRoutePlanner {
|
|||
for (RouteSegment s : segmentsToVisitPrescripted) {
|
||||
graphSegments.add(s);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
@ -484,8 +483,9 @@ public class BinaryRoutePlanner {
|
|||
segment = segment.parentRoute;
|
||||
// reverse start and end point for start if needed
|
||||
// rely that point.segmentStart <= point.segmentEnd for end, start
|
||||
if(segment == null && res.startPointIndex <= res.endPointIndex){
|
||||
res.endPointIndex = end.segmentEnd;
|
||||
if(segment == null && res.startPointIndex >= res.endPointIndex &&
|
||||
res.endPointIndex < res.object.getPointsLength() - 1){
|
||||
res.endPointIndex ++;
|
||||
}
|
||||
// do not add segments consists from 1 point
|
||||
if(res.startPointIndex != res.endPointIndex) {
|
||||
|
@ -508,8 +508,8 @@ public class BinaryRoutePlanner {
|
|||
segment = segment.parentRoute;
|
||||
// reverse start and end point for start if needed
|
||||
// rely that point.segmentStart <= point.segmentEnd for end, start
|
||||
if(segment == null && res.startPointIndex >= res.endPointIndex){
|
||||
res.startPointIndex = start.segmentEnd;
|
||||
if(segment == null && res.startPointIndex < res.endPointIndex){
|
||||
res.startPointIndex ++;
|
||||
}
|
||||
// do not add segments consists from 1 point
|
||||
if(res.startPointIndex != res.endPointIndex) {
|
||||
|
@ -672,7 +672,18 @@ public class BinaryRoutePlanner {
|
|||
return road;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class RoutePair {
|
||||
RouteSegment a;
|
||||
RouteSegment b;
|
||||
public RoutePair(RouteSegment a, RouteSegment b) {
|
||||
super();
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -66,6 +66,12 @@ public class PedestrianRouter extends VehicleRouter {
|
|||
pedestrianPriorityValues.put("services", 1d);
|
||||
pedestrianPriorityValues.put("steps", 1.2d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOneWay(BinaryMapDataObject road) {
|
||||
// for now all ways are bidirectional
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean acceptLine(TagValuePair pair) {
|
||||
if (pair.tag.equals("highway")) {
|
||||
|
|
|
@ -24,8 +24,9 @@ public abstract class VehicleRouter {
|
|||
public abstract boolean acceptPoint(TagValuePair pair);
|
||||
|
||||
|
||||
public boolean isOneWay(int highwayAttributes) {
|
||||
return MapRenderingTypes.isOneWayWay(highwayAttributes) || MapRenderingTypes.isRoundabout(highwayAttributes);
|
||||
public boolean isOneWay(BinaryMapDataObject road) {
|
||||
int attributes = road.getHighwayAttributes();
|
||||
return MapRenderingTypes.isOneWayWay(attributes) || MapRenderingTypes.isRoundabout(attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -49,7 +49,7 @@ import org.xml.sax.SAXException;
|
|||
public class MapRouterLayer implements MapPanelLayer {
|
||||
|
||||
private /*final */ static boolean ANIMATE_CALCULATING_ROUTE = false;
|
||||
private /*final */ static int SIZE_OF_ROUTES_TO_ANIMATE = 250;
|
||||
private /*final */ static int SIZE_OF_ROUTES_TO_ANIMATE = 50;
|
||||
|
||||
|
||||
private MapPanel map;
|
||||
|
@ -413,14 +413,22 @@ public class MapRouterLayer implements MapPanelLayer {
|
|||
}
|
||||
}
|
||||
|
||||
for(RouteSegmentResult s : searchRoute){
|
||||
// double dist = MapUtils.getDistance(s.startPoint, s.endPoint);
|
||||
net.osmand.osm.Node prevWayNode = null;
|
||||
for (RouteSegmentResult s : searchRoute) {
|
||||
// double dist = MapUtils.getDistance(s.startPoint, s.endPoint);
|
||||
Way way = new Way(-1);
|
||||
boolean plus = s.startPointIndex < s.endPointIndex;
|
||||
int i=s.startPointIndex;
|
||||
int i = s.startPointIndex;
|
||||
while (true) {
|
||||
net.osmand.osm.Node n = new net.osmand.osm.Node(MapUtils.get31LatitudeY(s.object.getPoint31YTile(i)), MapUtils
|
||||
.get31LongitudeX(s.object.getPoint31XTile(i)), -1);
|
||||
if (prevWayNode != null) {
|
||||
if (MapUtils.getDistance(prevWayNode, n) > 0) {
|
||||
System.out.println("Warning not connected road " + " " + s.object.getName() + " dist "
|
||||
+ MapUtils.getDistance(prevWayNode, n));
|
||||
}
|
||||
prevWayNode = null;
|
||||
}
|
||||
way.addNode(n);
|
||||
if (i == s.endPointIndex) {
|
||||
break;
|
||||
|
@ -431,6 +439,9 @@ public class MapRouterLayer implements MapPanelLayer {
|
|||
i--;
|
||||
}
|
||||
}
|
||||
if (way.getNodes().size() > 0) {
|
||||
prevWayNode = way.getNodes().get(way.getNodes().size() - 1);
|
||||
}
|
||||
res.add(way);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
|
Loading…
Reference in a new issue