Adjust route planner
This commit is contained in:
parent
ca090e9a74
commit
7e5601c0d8
6 changed files with 231 additions and 217 deletions
|
@ -30,6 +30,7 @@ public class BinaryRoutePlanner {
|
||||||
|
|
||||||
private static final int ROUTE_POINTS = 11;
|
private static final int ROUTE_POINTS = 11;
|
||||||
private static final float TURN_DEGREE_MIN = 45;
|
private static final float TURN_DEGREE_MIN = 45;
|
||||||
|
private static final boolean TRACE_ROUTING = false;
|
||||||
|
|
||||||
|
|
||||||
private static double squareRootDist(int x1, int y1, int x2, int y2) {
|
private static double squareRootDist(int x1, int y1, int x2, int y2) {
|
||||||
|
@ -298,10 +299,10 @@ public class BinaryRoutePlanner {
|
||||||
(graphDirectSegments.size() +
|
(graphDirectSegments.size() +
|
||||||
graphReverseSegments.size()) * STANDARD_ROAD_IN_QUEUE_OVERHEAD;
|
graphReverseSegments.size()) * STANDARD_ROAD_IN_QUEUE_OVERHEAD;
|
||||||
|
|
||||||
|
if(TRACE_ROUTING){
|
||||||
// String pr = " pend="+segment.parentSegmentEnd +" " +( segment.parentRoute == null ? "" : (" parent=" + segment.parentRoute.road));
|
System.out.print(">");
|
||||||
// System.out.println("Seg " + segment.road + " ind=" + segment.segmentStart +
|
printRoad(segment);
|
||||||
// " ds=" + ((float)segment.distanceFromStart) + " es="+((float)segment.distanceToEnd) + pr);
|
}
|
||||||
if(segment instanceof FinalRouteSegment) {
|
if(segment instanceof FinalRouteSegment) {
|
||||||
if(RoutingContext.SHOW_GC_SIZE){
|
if(RoutingContext.SHOW_GC_SIZE){
|
||||||
log.warn("Estimated overhead " + (ctx.memoryOverhead / (1<<20))+ " mb");
|
log.warn("Estimated overhead " + (ctx.memoryOverhead / (1<<20))+ " mb");
|
||||||
|
@ -317,16 +318,16 @@ public class BinaryRoutePlanner {
|
||||||
throw new IllegalStateException("There is no enough memory " + ctx.config.memoryLimitation/(1<<20) + " Mb");
|
throw new IllegalStateException("There is no enough memory " + ctx.config.memoryLimitation/(1<<20) + " Mb");
|
||||||
}
|
}
|
||||||
ctx.visitedSegments++;
|
ctx.visitedSegments++;
|
||||||
// for debug purposes
|
|
||||||
if (ctx.visitor != null) {
|
|
||||||
ctx.visitor.visitSegment(segment, true);
|
|
||||||
}
|
|
||||||
if (!inverse) {
|
if (!inverse) {
|
||||||
processRouteSegment(ctx, false, graphDirectSegments, visitedDirectSegments, targetEndX, targetEndY,
|
processRouteSegment(ctx, false, graphDirectSegments, visitedDirectSegments, targetEndX, targetEndY,
|
||||||
segment, visitedOppositeSegments);
|
segment, visitedOppositeSegments, true);
|
||||||
|
processRouteSegment(ctx, false, graphDirectSegments, visitedDirectSegments, targetEndX, targetEndY,
|
||||||
|
segment, visitedOppositeSegments, false);
|
||||||
} else {
|
} else {
|
||||||
processRouteSegment(ctx, true, graphReverseSegments, visitedOppositeSegments, startX, startY, segment,
|
processRouteSegment(ctx, true, graphReverseSegments, visitedOppositeSegments, startX, startY, segment,
|
||||||
visitedDirectSegments);
|
visitedDirectSegments, true);
|
||||||
|
processRouteSegment(ctx, true, graphReverseSegments, visitedOppositeSegments, startX, startY, segment,
|
||||||
|
visitedDirectSegments, false);
|
||||||
}
|
}
|
||||||
if(graphReverseSegments.isEmpty()){
|
if(graphReverseSegments.isEmpty()){
|
||||||
throw new IllegalArgumentException("Route is not found to selected target point.");
|
throw new IllegalArgumentException("Route is not found to selected target point.");
|
||||||
|
@ -372,10 +373,21 @@ public class BinaryRoutePlanner {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void printRoad(RouteSegment segment) {
|
||||||
|
String pr;
|
||||||
|
if(segment.parentRoute != null){
|
||||||
|
pr = " pend="+segment.parentSegmentEnd +" parent=" + segment.parentRoute.road;
|
||||||
|
} else {
|
||||||
|
pr = "";
|
||||||
|
}
|
||||||
|
System.out.println("" + segment.road + " ind=" + segment.getSegmentStart() +
|
||||||
|
" ds=" + ((float)segment.distanceFromStart) + " es="+((float)segment.distanceToEnd) + pr);
|
||||||
|
}
|
||||||
|
|
||||||
private void relaxNotNeededSegments(RoutingContext ctx, PriorityQueue<RouteSegment> graphSegments, boolean inverse) {
|
private void relaxNotNeededSegments(RoutingContext ctx, PriorityQueue<RouteSegment> graphSegments, boolean inverse) {
|
||||||
// relax strategy is incorrect if we already found a route but it is very long due to some obstacles
|
// relax strategy is incorrect if we already found a route but it is very long due to some obstacles
|
||||||
RouteSegment next = graphSegments.peek();
|
RouteSegment next = graphSegments.peek();
|
||||||
double mine = next.distanceToEnd;
|
double mine = next.distanceFromStart;
|
||||||
// int before = graphSegments.size();
|
// int before = graphSegments.size();
|
||||||
// SegmentStat statStart = new SegmentStat("Distance from start (" + inverse + ") ");
|
// SegmentStat statStart = new SegmentStat("Distance from start (" + inverse + ") ");
|
||||||
// SegmentStat statEnd = new SegmentStat("Distance to end (" + inverse + ") ");
|
// SegmentStat statEnd = new SegmentStat("Distance to end (" + inverse + ") ");
|
||||||
|
@ -388,7 +400,8 @@ public class BinaryRoutePlanner {
|
||||||
mine = s.distanceToEnd;
|
mine = s.distanceToEnd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double d = mine * ctx.config.RELAX_NODES_IF_START_DIST_COEF;
|
double d = mine + 5000; // ctx.config.RELAX_NODES_IF_START_DIST_COEF;
|
||||||
|
if (d > 0) {
|
||||||
iterator = graphSegments.iterator();
|
iterator = graphSegments.iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
RouteSegment s = iterator.next();
|
RouteSegment s = iterator.next();
|
||||||
|
@ -397,6 +410,7 @@ public class BinaryRoutePlanner {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// int after = graphSegments.size();
|
// int after = graphSegments.size();
|
||||||
// println(statStart.toString());
|
// println(statStart.toString());
|
||||||
// println(statEnd.toString());
|
// println(statEnd.toString());
|
||||||
|
@ -443,12 +457,12 @@ public class BinaryRoutePlanner {
|
||||||
printInfo("Loaded tiles " + ctx.loadedTiles + " (distinct "+ctx.distinctLoadedTiles+ "), unloaded tiles " + ctx.unloadedTiles +
|
printInfo("Loaded tiles " + ctx.loadedTiles + " (distinct "+ctx.distinctLoadedTiles+ "), unloaded tiles " + ctx.unloadedTiles +
|
||||||
", loaded more than once same tiles "
|
", loaded more than once same tiles "
|
||||||
+ ctx.loadedPrevUnloadedTiles );
|
+ ctx.loadedPrevUnloadedTiles );
|
||||||
printInfo("Visited roads, " + ctx.visitedSegments + ", relaxed roads " + ctx.relaxedSegments);
|
printInfo("Visited roads " + ctx.visitedSegments + ", relaxed roads " + ctx.relaxedSegments);
|
||||||
if (graphDirectSegments != null && graphReverseSegments != null) {
|
if (graphDirectSegments != null && graphReverseSegments != null) {
|
||||||
printInfo("Priority queues sizes : " + graphDirectSegments.size() + "/" + graphReverseSegments.size());
|
printInfo("Priority queues sizes : " + graphDirectSegments.size() + "/" + graphReverseSegments.size());
|
||||||
}
|
}
|
||||||
if (visitedDirectSegments != null && visitedOppositeSegments != null) {
|
if (visitedDirectSegments != null && visitedOppositeSegments != null) {
|
||||||
printInfo("Visited segments sizes: " + visitedDirectSegments.size() + "/" + visitedOppositeSegments.size());
|
printInfo("Visited interval sizes: " + visitedDirectSegments.size() + "/" + visitedOppositeSegments.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -456,131 +470,153 @@ public class BinaryRoutePlanner {
|
||||||
|
|
||||||
private void processRouteSegment(final RoutingContext ctx, boolean reverseWaySearch,
|
private void processRouteSegment(final RoutingContext ctx, boolean reverseWaySearch,
|
||||||
PriorityQueue<RouteSegment> graphSegments, TLongObjectHashMap<RouteSegment> visitedSegments, int targetEndX, int targetEndY,
|
PriorityQueue<RouteSegment> graphSegments, TLongObjectHashMap<RouteSegment> visitedSegments, int targetEndX, int targetEndY,
|
||||||
RouteSegment segment, TLongObjectHashMap<RouteSegment> oppositeSegments) throws IOException {
|
RouteSegment segment, TLongObjectHashMap<RouteSegment> oppositeSegments, boolean direction) throws IOException {
|
||||||
// Always start from segmentStart (!), not from segmentEnd
|
|
||||||
// It makes difference only for the first start segment
|
|
||||||
// Middle point will always be skipped from observation considering already visited
|
|
||||||
final RouteDataObject road = segment.road;
|
final RouteDataObject road = segment.road;
|
||||||
|
boolean initDirectionAllowed = checkIfInitialMovementAllowedOnSegment(ctx, reverseWaySearch, visitedSegments, segment, direction, road);
|
||||||
|
boolean directionAllowed = initDirectionAllowed;
|
||||||
|
// Go through all point of the way and find ways to continue
|
||||||
|
// ! Actually there is small bug when there is restriction to move forward on the way (it doesn't take into account)
|
||||||
|
float obstaclesTime = 0;
|
||||||
|
if(segment.getParentRoute() != null && directionAllowed) {
|
||||||
|
obstaclesTime = (float) ctx.getRouter().calculateTurnTime(segment, direction? segment.getRoad().getPointsLength() - 1 : 0,
|
||||||
|
segment.getParentRoute(), segment.getParentSegmentEnd());
|
||||||
|
}
|
||||||
|
float segmentDist = 0;
|
||||||
|
// +/- diff from middle point
|
||||||
|
int segmentEnd = segment.getSegmentStart();
|
||||||
|
while (directionAllowed) {
|
||||||
|
int prevInd = segmentEnd;
|
||||||
|
if(direction) {
|
||||||
|
segmentEnd ++;
|
||||||
|
} else {
|
||||||
|
segmentEnd --;
|
||||||
|
}
|
||||||
|
if (segmentEnd < 0 || segmentEnd >= road.getPointsLength()) {
|
||||||
|
directionAllowed = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final int intervalId = direction ? segmentEnd - 1 : segmentEnd;
|
||||||
|
visitedSegments.put(calculateRoutePointId(road, intervalId, direction), segment);
|
||||||
|
|
||||||
|
final int x = road.getPoint31XTile(segmentEnd);
|
||||||
|
final int y = road.getPoint31YTile(segmentEnd);
|
||||||
|
final int prevx = road.getPoint31XTile(prevInd);
|
||||||
|
final int prevy = road.getPoint31YTile(prevInd);
|
||||||
|
if(x == prevx && y == prevy) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 2. calculate point and try to load neighbor ways if they are not loaded
|
||||||
|
segmentDist += squareRootDist(x, y, prevx, prevy);
|
||||||
|
|
||||||
|
// 2.1 calculate possible obstacle plus time
|
||||||
|
double obstacle = ctx.getRouter().defineRoutingObstacle(road, segmentEnd);
|
||||||
|
if (obstacle < 0) {
|
||||||
|
directionAllowed = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
obstaclesTime += obstacle;
|
||||||
|
|
||||||
|
boolean alreadyVisited = checkIfOppositieSegmentWasVisited(ctx, reverseWaySearch, graphSegments, segment, oppositeSegments, road,
|
||||||
|
segmentEnd, direction, intervalId, segmentDist, obstaclesTime);
|
||||||
|
if (alreadyVisited) {
|
||||||
|
directionAllowed = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// could be expensive calculation
|
||||||
|
// 3. get intersected ways
|
||||||
|
final RouteSegment roadNext = ctx.loadRouteSegment(x, y, ctx.config.memoryLimitation - ctx.memoryOverhead);
|
||||||
|
if(roadNext != null &&
|
||||||
|
!((roadNext == segment || roadNext.road.id == road.id) && roadNext.next == null)) {
|
||||||
|
// check if there are outgoing connections in that case we need to stop processing
|
||||||
|
boolean outgoingConnections = false;
|
||||||
|
RouteSegment r = roadNext;
|
||||||
|
while(r != null && !outgoingConnections) {
|
||||||
|
if(r.road.id != road.id || r.getSegmentStart() != 0 || r.road.getOneway() != 1){
|
||||||
|
outgoingConnections = true;
|
||||||
|
}
|
||||||
|
r = r.next;
|
||||||
|
}
|
||||||
|
if (outgoingConnections) {
|
||||||
|
directionAllowed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float distToFinalPoint = (float) squareRootDist(x, y, targetEndX, targetEndY);
|
||||||
|
float distStartObstacles = segment.distanceFromStart + calculateTimeWithObstacles(ctx, road, segmentDist , obstaclesTime);
|
||||||
|
processIntersections(ctx, graphSegments, visitedSegments,
|
||||||
|
distStartObstacles, distToFinalPoint, segment, segmentEnd, roadNext, reverseWaySearch, outgoingConnections);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(initDirectionAllowed && ctx.visitor != null){
|
||||||
|
ctx.visitor.visitSegment(segment, segmentEnd, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkIfInitialMovementAllowedOnSegment(final RoutingContext ctx, boolean reverseWaySearch,
|
||||||
|
TLongObjectHashMap<RouteSegment> visitedSegments, RouteSegment segment, boolean direction, final RouteDataObject road
|
||||||
|
) {
|
||||||
|
boolean directionAllowed;
|
||||||
final int middle = segment.getSegmentStart();
|
final int middle = segment.getSegmentStart();
|
||||||
float obstaclePlusTime = 0;
|
|
||||||
float obstacleMinusTime = 0;
|
|
||||||
|
|
||||||
|
|
||||||
int oneway = ctx.getRouter().isOneWay(road);
|
int oneway = ctx.getRouter().isOneWay(road);
|
||||||
boolean minusAllowed;
|
|
||||||
boolean plusAllowed;
|
|
||||||
// use positive direction as agreed
|
// use positive direction as agreed
|
||||||
if(ctx.firstRoadId == calculateRoutePointId(road, middle, true) ) {
|
if(ctx.firstRoadId == calculateRoutePointId(road, middle, true) ) {
|
||||||
minusAllowed = ctx.firstRoadDirection <= 0;
|
if(direction){
|
||||||
plusAllowed = ctx.firstRoadDirection >= 0;
|
directionAllowed = ctx.firstRoadDirection >= 0;
|
||||||
} else if (!reverseWaySearch) {
|
|
||||||
minusAllowed = oneway <= 0;
|
|
||||||
plusAllowed = oneway >= 0;
|
|
||||||
} else {
|
} else {
|
||||||
minusAllowed = oneway >= 0;
|
directionAllowed = ctx.firstRoadDirection <= 0;
|
||||||
plusAllowed = oneway <= 0;
|
|
||||||
}
|
}
|
||||||
|
} else if (!reverseWaySearch) {
|
||||||
|
if(direction){
|
||||||
|
directionAllowed = oneway >= 0;
|
||||||
|
} else {
|
||||||
|
directionAllowed = oneway <= 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(direction){
|
||||||
|
directionAllowed = oneway <= 0;
|
||||||
|
} else {
|
||||||
|
directionAllowed = oneway >= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(direction) {
|
||||||
if(middle == road.getPointsLength() - 1 ||
|
if(middle == road.getPointsLength() - 1 ||
|
||||||
visitedSegments.containsKey(calculateRoutePointId(road, middle, true)) ||
|
visitedSegments.containsKey(calculateRoutePointId(road, middle, true)) ||
|
||||||
segment.getAllowedDirection() == -1) {
|
segment.getAllowedDirection() == -1) {
|
||||||
plusAllowed = false;
|
directionAllowed = false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if(middle == 0 || visitedSegments.containsKey(calculateRoutePointId(road, middle - 1, false)) ||
|
if(middle == 0 || visitedSegments.containsKey(calculateRoutePointId(road, middle - 1, false)) ||
|
||||||
segment.getAllowedDirection() == 1) {
|
segment.getAllowedDirection() == 1) {
|
||||||
minusAllowed = false;
|
directionAllowed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return directionAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// +/- diff from middle point
|
private boolean checkIfOppositieSegmentWasVisited(final RoutingContext ctx, boolean reverseWaySearch,
|
||||||
int d = plusAllowed ? 1 : -1;
|
PriorityQueue<RouteSegment> graphSegments, RouteSegment segment, TLongObjectHashMap<RouteSegment> oppositeSegments,
|
||||||
if(segment.getParentRoute() != null) {
|
final RouteDataObject road, int segmentEnd, boolean positive, int intervalId, float segmentDist, float obstaclesTime) {
|
||||||
if(plusAllowed && middle < segment.getRoad().getPointsLength() - 1) {
|
|
||||||
obstaclePlusTime = (float) ctx.getRouter().calculateTurnTime(segment, segment.getRoad().getPointsLength() - 1,
|
|
||||||
segment.getParentRoute(), segment.getParentSegmentEnd());
|
|
||||||
}
|
|
||||||
if(minusAllowed && middle > 0) {
|
|
||||||
obstacleMinusTime = (float) ctx.getRouter().calculateTurnTime(segment, 0,
|
|
||||||
segment.getParentRoute(), segment.getParentSegmentEnd());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Go through all point of the way and find ways to continue
|
|
||||||
// ! Actually there is small bug when there is restriction to move forward on the way (it doesn't take into account)
|
|
||||||
float posSegmentDist = 0;
|
|
||||||
float negSegmentDist = 0;
|
|
||||||
while (minusAllowed || plusAllowed) {
|
|
||||||
// 1. calculate point not equal to middle
|
|
||||||
// (algorithm should visit all point on way if it is not oneway)
|
|
||||||
int segmentEnd = middle + d;
|
|
||||||
boolean positive = d > 0;
|
|
||||||
// calculate d for next iteration
|
|
||||||
if (!minusAllowed && d > 0) {
|
|
||||||
d++;
|
|
||||||
} else if (!plusAllowed && d < 0) {
|
|
||||||
d--;
|
|
||||||
} else {
|
|
||||||
if (d <= 0) {
|
|
||||||
d = -d + 1;
|
|
||||||
} else {
|
|
||||||
d = -d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (segmentEnd < 0) {
|
|
||||||
minusAllowed = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (segmentEnd >= road.getPointsLength()) {
|
|
||||||
plusAllowed = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int intervalId = positive ? segmentEnd - 1 : segmentEnd;
|
|
||||||
long nds = calculateRoutePointId(road, intervalId, positive);
|
|
||||||
visitedSegments.put(nds, segment);
|
|
||||||
RouteSegment opposite = null;
|
|
||||||
// check if that segment was already visited in different direction
|
|
||||||
long opp = calculateRoutePointId(road, intervalId, !positive);
|
long opp = calculateRoutePointId(road, intervalId, !positive);
|
||||||
if (oppositeSegments.containsKey(opp)) {
|
if (oppositeSegments.containsKey(opp)) {
|
||||||
opposite = oppositeSegments.get(opp);
|
RouteSegment opposite = oppositeSegments.get(opp);
|
||||||
if (opposite.getSegmentStart() != segmentEnd) {
|
if (opposite.getSegmentStart() == segmentEnd) {
|
||||||
opposite = null;
|
FinalRouteSegment frs = new FinalRouteSegment(road, segment.getSegmentStart());
|
||||||
|
float distStartObstacles = segment.distanceFromStart + calculateTimeWithObstacles(ctx, road, segmentDist , obstaclesTime);
|
||||||
|
frs.setParentRoute(segment.getParentRoute());
|
||||||
|
frs.setParentSegmentEnd(segment.getParentSegmentEnd());
|
||||||
|
frs.reverseWaySearch = reverseWaySearch;
|
||||||
|
frs.distanceFromStart = opposite.distanceFromStart + distStartObstacles;
|
||||||
|
frs.distanceToEnd = 0;
|
||||||
|
frs.opposite = opposite;
|
||||||
|
graphSegments.add(frs);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 2. calculate point and try to load neighbor ways if they are not loaded
|
private float calculateTimeWithObstacles(RoutingContext ctx, RouteDataObject road, float distOnRoadToPass, float obstaclesTime) {
|
||||||
int x = road.getPoint31XTile(segmentEnd);
|
|
||||||
int y = road.getPoint31YTile(segmentEnd);
|
|
||||||
if(positive) {
|
|
||||||
posSegmentDist += squareRootDist(x, y,
|
|
||||||
road.getPoint31XTile(segmentEnd - 1), road.getPoint31YTile(segmentEnd - 1));
|
|
||||||
} else {
|
|
||||||
negSegmentDist += squareRootDist(x, y,
|
|
||||||
road.getPoint31XTile(segmentEnd + 1), road.getPoint31YTile(segmentEnd + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2.1 calculate possible obstacle plus time
|
|
||||||
if(positive){
|
|
||||||
double obstacle = ctx.getRouter().defineRoutingObstacle(road, segmentEnd);
|
|
||||||
if (obstacle < 0) {
|
|
||||||
plusAllowed = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
obstaclePlusTime += obstacle;
|
|
||||||
} else {
|
|
||||||
double obstacle = ctx.getRouter().defineRoutingObstacle(road, segmentEnd);
|
|
||||||
if (obstacle < 0) {
|
|
||||||
minusAllowed = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
obstacleMinusTime += obstacle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// could be expensive calculation
|
|
||||||
RouteSegment next = ctx.loadRouteSegment(x, y, ctx.config.memoryLimitation - ctx.memoryOverhead);
|
|
||||||
// 3. get intersected ways
|
|
||||||
if (next != null || opposite != null) {
|
|
||||||
// Using A* routing algorithm
|
|
||||||
// g(x) - calculate distance to that point and calculate time
|
|
||||||
|
|
||||||
float priority = ctx.getRouter().defineSpeedPriority(road);
|
float priority = ctx.getRouter().defineSpeedPriority(road);
|
||||||
float speed = (ctx.getRouter().defineSpeed(road) * priority);
|
float speed = (ctx.getRouter().defineSpeed(road) * priority);
|
||||||
if (speed == 0) {
|
if (speed == 0) {
|
||||||
|
@ -590,61 +626,11 @@ public class BinaryRoutePlanner {
|
||||||
if(speed > ctx.getRouter().getMaxDefaultSpeed()) {
|
if(speed > ctx.getRouter().getMaxDefaultSpeed()) {
|
||||||
speed = ctx.getRouter().getMaxDefaultSpeed();
|
speed = ctx.getRouter().getMaxDefaultSpeed();
|
||||||
}
|
}
|
||||||
float distOnRoadToPass = positive? posSegmentDist : negSegmentDist;
|
float distStartObstacles = obstaclesTime +
|
||||||
float distStartObstacles = segment.distanceFromStart + ( positive ? obstaclePlusTime : obstacleMinusTime) +
|
|
||||||
distOnRoadToPass / speed;
|
distOnRoadToPass / speed;
|
||||||
|
return distStartObstacles;
|
||||||
if(opposite != null) {
|
|
||||||
FinalRouteSegment frs = new FinalRouteSegment(road, segment.getSegmentStart());
|
|
||||||
frs.setParentRoute(segment.getParentRoute());
|
|
||||||
frs.setParentSegmentEnd(segment.getParentSegmentEnd());
|
|
||||||
frs.reverseWaySearch = reverseWaySearch;
|
|
||||||
frs.distanceFromStart = opposite.distanceFromStart + distStartObstacles;
|
|
||||||
frs.distanceToEnd = 0;
|
|
||||||
frs.opposite = opposite;
|
|
||||||
graphSegments.add(frs);
|
|
||||||
if(positive) {
|
|
||||||
plusAllowed = false;
|
|
||||||
} else {
|
|
||||||
minusAllowed = false;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(next == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TO-DO U-Turn
|
|
||||||
if((next == segment || next.road.id == road.id) && next.next == null) {
|
|
||||||
// simplification if there is no real intersection
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// check if there are outgoing connections in that case we need to stop processing
|
|
||||||
boolean outgoingConnections = false;
|
|
||||||
RouteSegment r = next;
|
|
||||||
while(r != null && !outgoingConnections) {
|
|
||||||
if(r.road.id != road.id || r.getSegmentStart() != 0 || r.road.getOneway() != 1){
|
|
||||||
outgoingConnections = true;
|
|
||||||
}
|
|
||||||
r = r.next;
|
|
||||||
}
|
|
||||||
if (outgoingConnections) {
|
|
||||||
if (positive) {
|
|
||||||
plusAllowed = false;
|
|
||||||
} else {
|
|
||||||
minusAllowed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float distToFinalPoint = (float) squareRootDist(x, y, targetEndX, targetEndY);
|
|
||||||
processIntersections(ctx, graphSegments, visitedSegments,
|
|
||||||
distStartObstacles, distToFinalPoint, segment, segmentEnd, next, reverseWaySearch, outgoingConnections);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private long calculateRoutePointId(final RouteDataObject road, int intervalId, boolean positive) {
|
private long calculateRoutePointId(final RouteDataObject road, int intervalId, boolean positive) {
|
||||||
return (road.getId() << ROUTE_POINTS) + (intervalId << 1) + (positive ? 1 : 0);
|
return (road.getId() << ROUTE_POINTS) + (intervalId << 1) + (positive ? 1 : 0);
|
||||||
|
@ -738,6 +724,9 @@ public class BinaryRoutePlanner {
|
||||||
Iterator<RouteSegment> nextIterator = null;
|
Iterator<RouteSegment> nextIterator = null;
|
||||||
if (thereAreRestrictions) {
|
if (thereAreRestrictions) {
|
||||||
nextIterator = ctx.segmentsToVisitPrescripted.iterator();
|
nextIterator = ctx.segmentsToVisitPrescripted.iterator();
|
||||||
|
if(TRACE_ROUTING){
|
||||||
|
System.out.println(" >> There are restrictions");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Calculate possible ways to put into priority queue
|
// Calculate possible ways to put into priority queue
|
||||||
RouteSegment next = inputNext;
|
RouteSegment next = inputNext;
|
||||||
|
@ -774,13 +763,18 @@ public class BinaryRoutePlanner {
|
||||||
if(sameRoadFutureDirection) {
|
if(sameRoadFutureDirection) {
|
||||||
next.setAllowedDirection((byte) (segment.getSegmentStart() < next.getSegmentStart() ? 1 : - 1));
|
next.setAllowedDirection((byte) (segment.getSegmentStart() < next.getSegmentStart() ? 1 : - 1));
|
||||||
}
|
}
|
||||||
|
if(TRACE_ROUTING) {
|
||||||
|
System.out.print(" >>");
|
||||||
|
printRoad(next);
|
||||||
|
}
|
||||||
// put additional information to recover whole route after
|
// put additional information to recover whole route after
|
||||||
next.setParentRoute(segment);
|
next.setParentRoute(segment);
|
||||||
next.setParentSegmentEnd(segmentEnd);
|
next.setParentSegmentEnd(segmentEnd);
|
||||||
|
|
||||||
graphSegments.add(next);
|
graphSegments.add(next);
|
||||||
}
|
}
|
||||||
if (ctx.visitor != null) {
|
if (ctx.visitor != null) {
|
||||||
ctx.visitor.visitSegment(next, false);
|
// ctx.visitor.visitSegment(next, false);
|
||||||
}
|
}
|
||||||
} else if(!sameRoadFutureDirection){
|
} else if(!sameRoadFutureDirection){
|
||||||
// the segment was already visited! We need to follow better route if it exists
|
// the segment was already visited! We need to follow better route if it exists
|
||||||
|
@ -797,7 +791,7 @@ public class BinaryRoutePlanner {
|
||||||
next.setParentRoute(segment);
|
next.setParentRoute(segment);
|
||||||
next.setParentSegmentEnd(segmentEnd);
|
next.setParentSegmentEnd(segmentEnd);
|
||||||
if (ctx.visitor != null) {
|
if (ctx.visitor != null) {
|
||||||
ctx.visitor.visitSegment(next, false);
|
// ctx.visitor.visitSegment(next, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1295,7 +1289,7 @@ public class BinaryRoutePlanner {
|
||||||
|
|
||||||
public interface RouteSegmentVisitor {
|
public interface RouteSegmentVisitor {
|
||||||
|
|
||||||
public void visitSegment(RouteSegment segment, boolean poll);
|
public void visitSegment(RouteSegment segment, int segmentEnd, boolean poll);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RouteSegment {
|
public static class RouteSegment {
|
||||||
|
|
|
@ -18,7 +18,7 @@ import org.xml.sax.helpers.DefaultHandler;
|
||||||
public class RoutingConfiguration {
|
public class RoutingConfiguration {
|
||||||
// 1. parameters of routing and different tweaks
|
// 1. parameters of routing and different tweaks
|
||||||
// Influence on A* : f(x) + heuristicCoefficient*g(X)
|
// Influence on A* : f(x) + heuristicCoefficient*g(X)
|
||||||
public double heuristicCoefficient = 1;
|
public float heuristicCoefficient = 1;
|
||||||
|
|
||||||
public static final int DEFAULT_MEMORY_LIMIT = 30;
|
public static final int DEFAULT_MEMORY_LIMIT = 30;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ public class RoutingConfiguration {
|
||||||
// 1.3 Relaxing strategy
|
// 1.3 Relaxing strategy
|
||||||
public boolean useRelaxingStrategy = true;
|
public boolean useRelaxingStrategy = true;
|
||||||
public int ITERATIONS_TO_RELAX_NODES = 100;
|
public int ITERATIONS_TO_RELAX_NODES = 100;
|
||||||
public double RELAX_NODES_IF_START_DIST_COEF = 3;
|
public float RELAX_NODES_IF_START_DIST_COEF = 3;
|
||||||
|
|
||||||
// 1.4 Build A* graph in backward/forward direction (can affect results)
|
// 1.4 Build A* graph in backward/forward direction (can affect results)
|
||||||
// 0 - 2 ways, 1 - direct way, -1 - reverse way
|
// 0 - 2 ways, 1 - direct way, -1 - reverse way
|
||||||
|
@ -63,7 +63,7 @@ public class RoutingConfiguration {
|
||||||
}
|
}
|
||||||
RoutingConfiguration i = new RoutingConfiguration();
|
RoutingConfiguration i = new RoutingConfiguration();
|
||||||
i.initialDirection = direction;
|
i.initialDirection = direction;
|
||||||
i.heuristicCoefficient = parseSilentDouble(getAttribute(router, "heuristicCoefficient"), i.heuristicCoefficient);
|
i.heuristicCoefficient = parseSilentFloat(getAttribute(router, "heuristicCoefficient"), i.heuristicCoefficient);
|
||||||
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
|
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
|
||||||
int desirable = parseSilentInt(getAttribute(router, "memoryLimitInMB"), 0);
|
int desirable = parseSilentInt(getAttribute(router, "memoryLimitInMB"), 0);
|
||||||
if(desirable != 0) {
|
if(desirable != 0) {
|
||||||
|
@ -78,7 +78,7 @@ public class RoutingConfiguration {
|
||||||
i.useRelaxingStrategy = parseSilentBoolean(getAttribute(router, "useRelaxingStrategy"), i.useRelaxingStrategy);
|
i.useRelaxingStrategy = parseSilentBoolean(getAttribute(router, "useRelaxingStrategy"), i.useRelaxingStrategy);
|
||||||
i.dynamicRoadPriorityDistance = parseSilentInt(getAttribute(router, "dynamicRoadPriorityDistance"), i.dynamicRoadPriorityDistance);
|
i.dynamicRoadPriorityDistance = parseSilentInt(getAttribute(router, "dynamicRoadPriorityDistance"), i.dynamicRoadPriorityDistance);
|
||||||
i.ITERATIONS_TO_RELAX_NODES = parseSilentInt(getAttribute(router, "iterationsToRelaxRoutes"), i.ITERATIONS_TO_RELAX_NODES);
|
i.ITERATIONS_TO_RELAX_NODES = parseSilentInt(getAttribute(router, "iterationsToRelaxRoutes"), i.ITERATIONS_TO_RELAX_NODES);
|
||||||
i.RELAX_NODES_IF_START_DIST_COEF = parseSilentDouble(getAttribute(router, "relaxNodesIfStartDistSmallCoeff"), i.RELAX_NODES_IF_START_DIST_COEF);
|
i.RELAX_NODES_IF_START_DIST_COEF = parseSilentFloat(getAttribute(router, "relaxNodesIfStartDistSmallCoeff"), i.RELAX_NODES_IF_START_DIST_COEF);
|
||||||
i.planRoadDirection = parseSilentInt(getAttribute(router, "planRoadDirection"), i.planRoadDirection);
|
i.planRoadDirection = parseSilentInt(getAttribute(router, "planRoadDirection"), i.planRoadDirection);
|
||||||
|
|
||||||
if (!routers.containsKey(router)) {
|
if (!routers.containsKey(router)) {
|
||||||
|
@ -117,11 +117,11 @@ public class RoutingConfiguration {
|
||||||
return Boolean.parseBoolean(t);
|
return Boolean.parseBoolean(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double parseSilentDouble(String t, double v) {
|
private static float parseSilentFloat(String t, float v) {
|
||||||
if (t == null || t.length() == 0) {
|
if (t == null || t.length() == 0) {
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
return Double.parseDouble(t);
|
return Float.parseFloat(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -173,22 +173,22 @@ public class RoutingConfiguration {
|
||||||
if (previousKey != null) {
|
if (previousKey != null) {
|
||||||
String k = in + ":" + previousKey;
|
String k = in + ":" + previousKey;
|
||||||
if (attributes.getValue("penalty") != null) {
|
if (attributes.getValue("penalty") != null) {
|
||||||
double penalty = parseSilentDouble(attributes.getValue("penalty"), 0);
|
float penalty = parseSilentFloat(attributes.getValue("penalty"), 0);
|
||||||
currentRouter.obstacles.put(k, penalty);
|
currentRouter.obstacles.put(k, penalty);
|
||||||
double routingPenalty = parseSilentDouble(attributes.getValue("routingPenalty"), penalty );
|
float routingPenalty = parseSilentFloat(attributes.getValue("routingPenalty"), penalty );
|
||||||
currentRouter.routingObstacles.put(k, routingPenalty);
|
currentRouter.routingObstacles.put(k, routingPenalty);
|
||||||
}
|
}
|
||||||
if (attributes.getValue("priority") != null) {
|
if (attributes.getValue("priority") != null) {
|
||||||
currentRouter.highwayPriorities.put(k, parseSilentDouble(attributes.getValue("priority"), 0));
|
currentRouter.highwayPriorities.put(k, parseSilentFloat(attributes.getValue("priority"), 0));
|
||||||
}
|
}
|
||||||
if (attributes.getValue("dynamicPriority") != null) {
|
if (attributes.getValue("dynamicPriority") != null) {
|
||||||
currentRouter.highwayFuturePriorities.put(k, parseSilentDouble(attributes.getValue("dynamicPriority"), 0));
|
currentRouter.highwayFuturePriorities.put(k, parseSilentFloat(attributes.getValue("dynamicPriority"), 0));
|
||||||
}
|
}
|
||||||
if (attributes.getValue("speed") != null) {
|
if (attributes.getValue("speed") != null) {
|
||||||
currentRouter.highwaySpeed.put(k, parseSilentDouble(attributes.getValue("speed"), 0));
|
currentRouter.highwaySpeed.put(k, parseSilentFloat(attributes.getValue("speed"), 0));
|
||||||
}
|
}
|
||||||
if ("avoid".equals(previousTag)) {
|
if ("avoid".equals(previousTag)) {
|
||||||
double priority = parseSilentDouble(attributes.getValue("decreasedPriority"), 0);
|
float priority = parseSilentFloat(attributes.getValue("decreasedPriority"), 0);
|
||||||
if (priority == 0) {
|
if (priority == 0) {
|
||||||
currentRouter.avoid.put(k, priority);
|
currentRouter.avoid.put(k, priority);
|
||||||
} else {
|
} else {
|
||||||
|
@ -200,23 +200,23 @@ public class RoutingConfiguration {
|
||||||
} else if("road".equals(name)) {
|
} else if("road".equals(name)) {
|
||||||
previousTag = name;
|
previousTag = name;
|
||||||
previousKey = attributes.getValue("tag") +"$" + attributes.getValue("value");
|
previousKey = attributes.getValue("tag") +"$" + attributes.getValue("value");
|
||||||
currentRouter.highwayPriorities.put(previousKey, parseSilentDouble(attributes.getValue("priority"),
|
currentRouter.highwayPriorities.put(previousKey, parseSilentFloat(attributes.getValue("priority"),
|
||||||
1));
|
1));
|
||||||
currentRouter.highwayFuturePriorities.put(previousKey, parseSilentDouble(attributes.getValue("dynamicPriority"),
|
currentRouter.highwayFuturePriorities.put(previousKey, parseSilentFloat(attributes.getValue("dynamicPriority"),
|
||||||
1));
|
1));
|
||||||
currentRouter.highwaySpeed.put(previousKey, parseSilentDouble(attributes.getValue("speed"),
|
currentRouter.highwaySpeed.put(previousKey, parseSilentFloat(attributes.getValue("speed"),
|
||||||
10));
|
10));
|
||||||
} else if("obstacle".equals(name)) {
|
} else if("obstacle".equals(name)) {
|
||||||
previousTag = name;
|
previousTag = name;
|
||||||
previousKey = attributes.getValue("tag") + "$" + attributes.getValue("value");
|
previousKey = attributes.getValue("tag") + "$" + attributes.getValue("value");
|
||||||
double penalty = parseSilentDouble(attributes.getValue("penalty"), 0);
|
float penalty = parseSilentFloat(attributes.getValue("penalty"), 0);
|
||||||
currentRouter.obstacles.put(previousKey, penalty);
|
currentRouter.obstacles.put(previousKey, penalty);
|
||||||
double routingPenalty = parseSilentDouble(attributes.getValue("routingPenalty"), penalty );
|
float routingPenalty = parseSilentFloat(attributes.getValue("routingPenalty"), penalty );
|
||||||
currentRouter.routingObstacles.put(previousKey, routingPenalty);
|
currentRouter.routingObstacles.put(previousKey, routingPenalty);
|
||||||
} else if("avoid".equals(name)) {
|
} else if("avoid".equals(name)) {
|
||||||
previousTag = name;
|
previousTag = name;
|
||||||
previousKey = attributes.getValue("tag") + "$" + attributes.getValue("value");
|
previousKey = attributes.getValue("tag") + "$" + attributes.getValue("value");
|
||||||
double priority = parseSilentDouble(attributes.getValue("decreasedPriority"),
|
float priority = parseSilentFloat(attributes.getValue("decreasedPriority"),
|
||||||
0);
|
0);
|
||||||
if(priority == 0) {
|
if(priority == 0) {
|
||||||
currentRouter.avoid.put(previousKey, priority);
|
currentRouter.avoid.put(previousKey, priority);
|
||||||
|
|
|
@ -34,7 +34,7 @@ import org.apache.commons.logging.Log;
|
||||||
public class RoutingContext {
|
public class RoutingContext {
|
||||||
|
|
||||||
public static final boolean SHOW_GC_SIZE = false;
|
public static final boolean SHOW_GC_SIZE = false;
|
||||||
public boolean USE_BASEMAP = false;
|
|
||||||
|
|
||||||
private final static Log log = LogUtil.getLog(RoutingContext.class);
|
private final static Log log = LogUtil.getLog(RoutingContext.class);
|
||||||
public static final int OPTION_NO_LOAD = 0;
|
public static final int OPTION_NO_LOAD = 0;
|
||||||
|
@ -42,6 +42,7 @@ public class RoutingContext {
|
||||||
public static final int OPTION_IN_MEMORY_LOAD = 2;
|
public static final int OPTION_IN_MEMORY_LOAD = 2;
|
||||||
// Final context variables
|
// Final context variables
|
||||||
public final RoutingConfiguration config;
|
public final RoutingConfiguration config;
|
||||||
|
private final boolean useBaseMap;
|
||||||
public final NativeLibrary nativeLib;
|
public final NativeLibrary nativeLib;
|
||||||
public final Map<BinaryMapIndexReader, List<RouteSubregion>> map = new LinkedHashMap<BinaryMapIndexReader, List<RouteSubregion>>();
|
public final Map<BinaryMapIndexReader, List<RouteSubregion>> map = new LinkedHashMap<BinaryMapIndexReader, List<RouteSubregion>>();
|
||||||
public final Map<RouteRegion, BinaryMapIndexReader> reverseMap = new LinkedHashMap<RouteRegion, BinaryMapIndexReader>();
|
public final Map<RouteRegion, BinaryMapIndexReader> reverseMap = new LinkedHashMap<RouteRegion, BinaryMapIndexReader>();
|
||||||
|
@ -96,6 +97,7 @@ public class RoutingContext {
|
||||||
public RoutingContext(RoutingContext cp) {
|
public RoutingContext(RoutingContext cp) {
|
||||||
this.config = cp.config;
|
this.config = cp.config;
|
||||||
this.map.putAll(cp.map);
|
this.map.putAll(cp.map);
|
||||||
|
this.useBaseMap = cp.useBaseMap;
|
||||||
this.reverseMap.putAll(cp.reverseMap);
|
this.reverseMap.putAll(cp.reverseMap);
|
||||||
this.nativeLib = cp.nativeLib;
|
this.nativeLib = cp.nativeLib;
|
||||||
// copy local data and clear caches
|
// copy local data and clear caches
|
||||||
|
@ -117,11 +119,16 @@ public class RoutingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
public RoutingContext(RoutingConfiguration config, NativeLibrary nativeLibrary, BinaryMapIndexReader[] map) {
|
public RoutingContext(RoutingConfiguration config, NativeLibrary nativeLibrary, BinaryMapIndexReader[] map) {
|
||||||
|
this(config, nativeLibrary, map, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoutingContext(RoutingConfiguration config, NativeLibrary nativeLibrary, BinaryMapIndexReader[] map, boolean useBasemap) {
|
||||||
|
this.useBaseMap = useBasemap;
|
||||||
for (BinaryMapIndexReader mr : map) {
|
for (BinaryMapIndexReader mr : map) {
|
||||||
List<RouteRegion> rr = mr.getRoutingIndexes();
|
List<RouteRegion> rr = mr.getRoutingIndexes();
|
||||||
List<RouteSubregion> subregions = new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>();
|
List<RouteSubregion> subregions = new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>();
|
||||||
for (RouteRegion r : rr) {
|
for (RouteRegion r : rr) {
|
||||||
List<RouteSubregion> subregs = USE_BASEMAP ? r.getBaseSubregions() :
|
List<RouteSubregion> subregs = useBaseMap ? r.getBaseSubregions() :
|
||||||
r.getSubregions();
|
r.getSubregions();
|
||||||
for (RouteSubregion rs : subregs) {
|
for (RouteSubregion rs : subregs) {
|
||||||
subregions.add(new RouteSubregion(rs));
|
subregions.add(new RouteSubregion(rs));
|
||||||
|
@ -193,7 +200,7 @@ public class RoutingContext {
|
||||||
config.router = router;
|
config.router = router;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHeuristicCoefficient(double heuristicCoefficient) {
|
public void setHeuristicCoefficient(float heuristicCoefficient) {
|
||||||
config.heuristicCoefficient = heuristicCoefficient;
|
config.heuristicCoefficient = heuristicCoefficient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<attribute name="zoomToLoadTiles" value="16" />
|
<attribute name="zoomToLoadTiles" value="16" />
|
||||||
<!-- by default it is 30. Value specified here overwrites all others
|
<!-- by default it is 30. Value specified here overwrites all others
|
||||||
(don't specify here ! it is device dependent) -->
|
(don't specify here ! it is device dependent) -->
|
||||||
<attribute name="memoryLimitInMB" value="" />
|
<attribute name="memoryLimitInMB" value="450" />
|
||||||
|
|
||||||
<!-- 1.2 Dynamic road prioritizing (heuristic) -->
|
<!-- 1.2 Dynamic road prioritizing (heuristic) -->
|
||||||
<attribute name="useDynamicRoadPrioritising" value="false" />
|
<attribute name="useDynamicRoadPrioritising" value="false" />
|
||||||
|
|
|
@ -138,8 +138,9 @@ public class MapClusterLayer implements MapPanelLayer {
|
||||||
|
|
||||||
ctx.setVisitor(new RouteSegmentVisitor() {
|
ctx.setVisitor(new RouteSegmentVisitor() {
|
||||||
private List<RouteSegment> cache = new ArrayList<RouteSegment>();
|
private List<RouteSegment> cache = new ArrayList<RouteSegment>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitSegment(RouteSegment s, boolean poll) {
|
public void visitSegment(RouteSegment s, int endSegment, boolean poll) {
|
||||||
if(!ANIMATE_CLUSTERING){
|
if(!ANIMATE_CLUSTERING){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -269,7 +270,7 @@ public class MapClusterLayer implements MapPanelLayer {
|
||||||
if (!onTheMap.contains(toAdd.getRoad().getId())) {
|
if (!onTheMap.contains(toAdd.getRoad().getId())) {
|
||||||
onTheMap.add(toAdd.getRoad().getId());
|
onTheMap.add(toAdd.getRoad().getId());
|
||||||
// Visualization of steps !
|
// Visualization of steps !
|
||||||
ctx.getVisitor().visitSegment(toAdd, true);
|
ctx.getVisitor().visitSegment(toAdd, -1, true);
|
||||||
}
|
}
|
||||||
List<RouteSegment> nextSegments = new ArrayList<BinaryRoutePlanner.RouteSegment>();
|
List<RouteSegment> nextSegments = new ArrayList<BinaryRoutePlanner.RouteSegment>();
|
||||||
boolean out = false;
|
boolean out = false;
|
||||||
|
|
|
@ -617,8 +617,7 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
RoutingConfiguration config = builder.build(props[0], RoutingConfiguration.DEFAULT_MEMORY_LIMIT / 2, props);
|
RoutingConfiguration config = builder.build(props[0], RoutingConfiguration.DEFAULT_MEMORY_LIMIT / 2, props);
|
||||||
// config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 300;
|
// config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 300;
|
||||||
// config.ZOOM_TO_LOAD_TILES = 14;
|
// config.ZOOM_TO_LOAD_TILES = 14;
|
||||||
RoutingContext ctx = new RoutingContext(config, NativeSwingRendering.getDefaultFromSettings(), rs);
|
RoutingContext ctx = new RoutingContext(config, NativeSwingRendering.getDefaultFromSettings(), rs, useBasemap);
|
||||||
ctx.USE_BASEMAP = useBasemap;
|
|
||||||
ctx.previouslyCalculatedRoute = previousRoute;
|
ctx.previouslyCalculatedRoute = previousRoute;
|
||||||
log.info("Use " + config.routerName + "mode for routing");
|
log.info("Use " + config.routerName + "mode for routing");
|
||||||
|
|
||||||
|
@ -655,9 +654,10 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
|
|
||||||
private List<RouteSegment> cache = new ArrayList<RouteSegment>();
|
private List<RouteSegment> cache = new ArrayList<RouteSegment>();
|
||||||
private List<RouteSegment> pollCache = new ArrayList<RouteSegment>();
|
private List<RouteSegment> pollCache = new ArrayList<RouteSegment>();
|
||||||
|
private List<Integer> cacheInt = new ArrayList<Integer>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitSegment(RouteSegment s, boolean poll) {
|
public void visitSegment(RouteSegment s, int endSegment, boolean poll) {
|
||||||
if(stop) {
|
if(stop) {
|
||||||
throw new RuntimeException("Interrupted");
|
throw new RuntimeException("Interrupted");
|
||||||
}
|
}
|
||||||
|
@ -670,33 +670,45 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.add(s);
|
cache.add(s);
|
||||||
|
cacheInt.add(endSegment);
|
||||||
if (cache.size() < steps) {
|
if (cache.size() < steps) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(pause) {
|
if(pause) {
|
||||||
registerObjects(points, poll, pollCache);
|
registerObjects(points, poll, pollCache, null);
|
||||||
pollCache.clear();
|
pollCache.clear();
|
||||||
}
|
}
|
||||||
registerObjects(points, !poll, cache);
|
registerObjects(points, !poll, cache, cacheInt);
|
||||||
cache.clear();
|
cache.clear();
|
||||||
|
cacheInt.clear();
|
||||||
redraw();
|
redraw();
|
||||||
if (pause) {
|
if (pause) {
|
||||||
waitNextPress();
|
waitNextPress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerObjects(final DataTileManager<Entity> points, boolean white,
|
private void registerObjects(final DataTileManager<Entity> points, boolean white, List<RouteSegment> registerCache,
|
||||||
List<RouteSegment> registerCache) {
|
List<Integer> cacheInt) {
|
||||||
for (RouteSegment segment : registerCache) {
|
for (int l = 0; l < registerCache.size(); l++) {
|
||||||
|
RouteSegment segment = registerCache.get(l);
|
||||||
Way way = new Way(-1);
|
Way way = new Way(-1);
|
||||||
way.putTag(OSMTagKey.NAME.getValue(), segment.getTestName());
|
way.putTag(OSMTagKey.NAME.getValue(), segment.getTestName());
|
||||||
if (white) {
|
if (white) {
|
||||||
way.putTag("color", "white");
|
way.putTag("color", "white");
|
||||||
}
|
}
|
||||||
for (int i = 0; i < segment.getRoad().getPointsLength(); i++) {
|
int from = cacheInt != null ? segment.getSegmentStart() : segment.getSegmentStart() - 2;
|
||||||
|
int to = cacheInt != null ? cacheInt.get(l) : segment.getSegmentStart() + 2;
|
||||||
|
if(from > to) {
|
||||||
|
int x = from;
|
||||||
|
from = to;
|
||||||
|
to = x;
|
||||||
|
}
|
||||||
|
for (int i = from; i <= to; i++) {
|
||||||
|
if (i >= 0 && i < segment.getRoad().getPointsLength()) {
|
||||||
net.osmand.osm.Node n = createNode(segment, i);
|
net.osmand.osm.Node n = createNode(segment, i);
|
||||||
way.addNode(n);
|
way.addNode(n);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
LatLon n = way.getLatLon();
|
LatLon n = way.getLatLon();
|
||||||
points.registerObject(n.getLatitude(), n.getLongitude(), way);
|
points.registerObject(n.getLatitude(), n.getLongitude(), way);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue