Intermediate commit for exact routing

This commit is contained in:
Victor Shcherb 2012-10-26 18:45:41 +02:00
parent 61d26ab009
commit 6b959dd7a9
2 changed files with 57 additions and 22 deletions

View file

@ -437,7 +437,7 @@ public class BinaryRoutePlanner {
protected static float h(RoutingContext ctx, int begX, int begY, int endX, int endY,
RouteSegment next) {
double distToFinalPoint = squareRootDist(begX, begY, endX, endY);
if (RoutingContext.USE_BORDER_LINES) {
if (RoutingContext.USE_BORDER_LINES && true) {
int begBorder = ctx.searchBorderLineIndex(begY);
int endBorder = ctx.searchBorderLineIndex(endY);
if (begBorder != endBorder) {
@ -449,33 +449,41 @@ public class BinaryRoutePlanner {
boolean endEqTarget = endX == ctx.targetX && endY == ctx.targetY;
if(endEqStart || endEqTarget) {
// we start from intermediate point and end in target or start
List<RouteDataBorderLinePoint> pnts = ctx.borderLines[plus ? begBorder : begBorder - 1].borderPoints;
for (RouteDataBorderLinePoint p : pnts) {
double f = (endEqTarget? p.distanceToEndPoint : p.distanceToStartPoint) + squareRootDist(p.x, p.y, begX, begY);
if (res > f || res <= 0) {
res = f;
if (begX > ctx.leftBorderBoundary && begX < ctx.rightBorderBoundary) {
List<RouteDataBorderLinePoint> pnts = ctx.borderLines[plus ? begBorder : begBorder - 1].borderPoints;
for (RouteDataBorderLinePoint p : pnts) {
double f = (endEqTarget ? p.distanceToEndPoint : p.distanceToStartPoint) + squareRootDist(p.x, p.y, begX, begY);
if (res > f || res <= 0) {
res = f;
}
}
}
} else if(beginEqStart || beginEqTarget) {
List<RouteDataBorderLinePoint> pnts = ctx.borderLines[plus ? endBorder -1 : endBorder].borderPoints;
for (RouteDataBorderLinePoint p : pnts) {
double f = (beginEqTarget? p.distanceToEndPoint : p.distanceToStartPoint) + squareRootDist(p.x, p.y, endX, endY);
if (res > f || res <= 0) {
res = f;
if (endX > ctx.leftBorderBoundary && endX < ctx.rightBorderBoundary) {
List<RouteDataBorderLinePoint> pnts = ctx.borderLines[plus ? endBorder - 1 : endBorder].borderPoints;
for (RouteDataBorderLinePoint p : pnts) {
double f = (beginEqTarget ? p.distanceToEndPoint : p.distanceToStartPoint)
+ squareRootDist(p.x, p.y, endX, endY);
if (res > f || res <= 0) {
res = f;
}
}
}
} else {
throw new IllegalStateException();
}
if(res > 0) {
if(res > distToFinalPoint) {
// System.out.println("& " + res + " > " + distToFinalPoint);
if(res < distToFinalPoint - 0.01) {
throw new IllegalStateException("Estimated distance " + res + " > " + distToFinalPoint);
}
// if(endEqStart && res - distToFinalPoint > 13000) {
// System.out.println(" Res="+res + " dist=" +distToFinalPoint);
// }
distToFinalPoint = res;
} else {
System.out.println("&" + distToFinalPoint);
// FIXME need to put penalty
distToFinalPoint = distToFinalPoint * 5;
// FIXME put penalty
// distToFinalPoint = distToFinalPoint;
}
}
}
@ -520,6 +528,10 @@ public class BinaryRoutePlanner {
if (visitedDirectSegments != null && visitedOppositeSegments != null) {
printInfo("Visited interval sizes: " + visitedDirectSegments.size() + "/" + visitedOppositeSegments.size());
}
for(int k=0; k<ctx.borderLines.length; k++) {
System.out.println("Line " + (ctx.borderLineCoordinates[k] >> 17) + " points " + ctx.borderLines[k].borderPoints.size());
}
}
@ -564,16 +576,22 @@ public class BinaryRoutePlanner {
int st = ctx.searchBorderLineIndex(y);
int tt = ctx.searchBorderLineIndex(prevy);
if(st != tt){
// System.out.println(" " + st + " != " + tt + " " + road.id);
// System.out.print(" " + st + " != " + tt + " " + road.id + " ? ");
for(int i = Math.min(st, tt); i < Math.max(st, tt) & i < ctx.borderLines.length ; i++) {
Iterator<RouteDataBorderLinePoint> pnts = ctx.borderLines[i].borderPoints.iterator();
boolean changed = false;
while(pnts.hasNext()) {
RouteDataBorderLinePoint o = pnts.next();
if(o.id == road.id) {
// System.out.println("Point removed !");
pnts.remove();
changed = true;
}
}
if(changed){
ctx.updateDistanceForBorderPoints(ctx.startX, ctx.startY, true);
ctx.updateDistanceForBorderPoints(ctx.targetX, ctx.targetY, false);
}
}
}
}

View file

@ -72,6 +72,8 @@ public class RoutingContext {
RouteDataBorderLine[] borderLines = new RouteDataBorderLine[0];
int[] borderLineCoordinates = new int[0];
int leftBorderBoundary;
int rightBorderBoundary;
// Needs to be a sorted array list . Another option to use hashmap but it will be more memory expensive
List<RoutingSubregionTile> subregionTiles = new ArrayList<RoutingSubregionTile>();
@ -102,7 +104,8 @@ public class RoutingContext {
public int relaxedSegments = 0;
// callback of processing segments
RouteSegmentVisitor visitor = null;
public RoutingContext(RoutingContext cp) {
@ -310,6 +313,8 @@ public class RoutingContext {
// one tile of 12th zoom around (?)
int zoomAround = 10;
int distAround = 1 << (31 - zoomAround);
leftBorderBoundary = sleft - distAround;
rightBorderBoundary = sright + distAround;
SearchRequest<RouteDataBorderLinePoint> req = BinaryMapIndexReader.buildSearchRouteBorderRequest(sleft, sright, stop, sbottom);
while(it.hasNext()) {
Entry<RouteRegion, BinaryMapIndexReader> entry = it.next();
@ -317,9 +322,20 @@ public class RoutingContext {
}
TIntObjectHashMap<RouteDataBorderLine> lines = new TIntObjectHashMap<RoutingContext.RouteDataBorderLine>();
for(RouteDataBorderLinePoint p : req.getSearchResults()) {
if(config.router.acceptLine(p.types, p.region) && p.x > sleft - distAround && p.x < sright + distAround) {
if(config.router.acceptLine(p.types, p.region) && p.x > leftBorderBoundary && p.x < rightBorderBoundary) {
if(!lines.containsKey(p.y)) {
lines.put(p.y, new RouteDataBorderLine(p.y));
RouteDataBorderLine line = new RouteDataBorderLine(p.y);
lines.put(p.y, line);
RouteDataBorderLinePoint lft = new RouteDataBorderLinePoint(p.region);
lft.y = p.y;
lft.id = Long.MIN_VALUE;
lft.x = leftBorderBoundary;
line.borderPoints.add(lft);
RouteDataBorderLinePoint rht = new RouteDataBorderLinePoint(p.region);
rht.y = p.y;
rht.id = Long.MIN_VALUE;
rht.x = rightBorderBoundary;
line.borderPoints.add(rht);
}
lines.get(p.y).borderPoints.add(p);
}
@ -343,7 +359,7 @@ public class RoutingContext {
}
private void updateDistanceForBorderPoints(int sX, int sy, boolean distanceToStart) {
protected void updateDistanceForBorderPoints(int sX, int sy, boolean distanceToStart) {
boolean plus = borderLines.length > 0 && sy < borderLines[0].borderLine;
if(borderLines.length > 0 && !plus && sy< borderLines[borderLines.length - 1].borderLine){
throw new IllegalStateException();
@ -352,7 +368,7 @@ public class RoutingContext {
for(int i=0; i<borderLines.length; i++) {
int ind = plus ? i : borderLines.length - i - 1;
for(RouteDataBorderLinePoint ps : borderLines[ind].borderPoints){
float res = (float) Math.sqrt(MapUtils.squareDist31TileMetric(sX, sy, ps.x, ps.y));
float res = (float) Math.sqrt(MapUtils.squareDist31TileMetric(sX, sy, ps.x, ps.y)) ;
if(i > 0){
int prevInd = plus ? i - 1 : borderLines.length - i;
double minDist = 0;
@ -364,6 +380,7 @@ public class RoutingContext {
}
}
if (minDist > 0) {
// System.out.println("Border line " + i + " exp="+res + " min="+ minDist);
res = (float) minDist;
}
}