Adjust route planner

This commit is contained in:
Victor Shcherb 2012-10-13 13:38:54 +02:00
parent ca090e9a74
commit 7e5601c0d8
6 changed files with 231 additions and 217 deletions

View file

@ -30,6 +30,7 @@ public class BinaryRoutePlanner {
private static final int ROUTE_POINTS = 11;
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) {
@ -298,10 +299,10 @@ public class BinaryRoutePlanner {
(graphDirectSegments.size() +
graphReverseSegments.size()) * STANDARD_ROAD_IN_QUEUE_OVERHEAD;
// String pr = " pend="+segment.parentSegmentEnd +" " +( segment.parentRoute == null ? "" : (" parent=" + segment.parentRoute.road));
// System.out.println("Seg " + segment.road + " ind=" + segment.segmentStart +
// " ds=" + ((float)segment.distanceFromStart) + " es="+((float)segment.distanceToEnd) + pr);
if(TRACE_ROUTING){
System.out.print(">");
printRoad(segment);
}
if(segment instanceof FinalRouteSegment) {
if(RoutingContext.SHOW_GC_SIZE){
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");
}
ctx.visitedSegments++;
// for debug purposes
if (ctx.visitor != null) {
ctx.visitor.visitSegment(segment, true);
}
if (!inverse) {
processRouteSegment(ctx, false, graphDirectSegments, visitedDirectSegments, targetEndX, targetEndY,
segment, visitedOppositeSegments);
segment, visitedOppositeSegments, true);
processRouteSegment(ctx, false, graphDirectSegments, visitedDirectSegments, targetEndX, targetEndY,
segment, visitedOppositeSegments, false);
} else {
processRouteSegment(ctx, true, graphReverseSegments, visitedOppositeSegments, startX, startY, segment,
visitedDirectSegments);
visitedDirectSegments, true);
processRouteSegment(ctx, true, graphReverseSegments, visitedOppositeSegments, startX, startY, segment,
visitedDirectSegments, false);
}
if(graphReverseSegments.isEmpty()){
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) {
// relax strategy is incorrect if we already found a route but it is very long due to some obstacles
RouteSegment next = graphSegments.peek();
double mine = next.distanceToEnd;
double mine = next.distanceFromStart;
// int before = graphSegments.size();
// SegmentStat statStart = new SegmentStat("Distance from start (" + inverse + ") ");
// SegmentStat statEnd = new SegmentStat("Distance to end (" + inverse + ") ");
@ -388,13 +400,15 @@ public class BinaryRoutePlanner {
mine = s.distanceToEnd;
}
}
double d = mine * ctx.config.RELAX_NODES_IF_START_DIST_COEF;
iterator = graphSegments.iterator();
while (iterator.hasNext()) {
RouteSegment s = iterator.next();
if (s.distanceToEnd > d) {
ctx.relaxedSegments++;
iterator.remove();
double d = mine + 5000; // ctx.config.RELAX_NODES_IF_START_DIST_COEF;
if (d > 0) {
iterator = graphSegments.iterator();
while (iterator.hasNext()) {
RouteSegment s = iterator.next();
if (s.distanceToEnd > d) {
ctx.relaxedSegments++;
iterator.remove();
}
}
}
// int after = graphSegments.size();
@ -443,185 +457,80 @@ public class BinaryRoutePlanner {
printInfo("Loaded tiles " + ctx.loadedTiles + " (distinct "+ctx.distinctLoadedTiles+ "), unloaded tiles " + ctx.unloadedTiles +
", loaded more than once same tiles "
+ 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) {
printInfo("Priority queues sizes : " + graphDirectSegments.size() + "/" + graphReverseSegments.size());
}
if (visitedDirectSegments != null && visitedOppositeSegments != null) {
printInfo("Visited segments sizes: " + visitedDirectSegments.size() + "/" + visitedOppositeSegments.size());
printInfo("Visited interval sizes: " + visitedDirectSegments.size() + "/" + visitedOppositeSegments.size());
}
}
private void processRouteSegment(final RoutingContext ctx, 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
// It makes difference only for the first start segment
// Middle point will always be skipped from observation considering already visited
RouteSegment segment, TLongObjectHashMap<RouteSegment> oppositeSegments, boolean direction) throws IOException {
final RouteDataObject road = segment.road;
final int middle = segment.getSegmentStart();
float obstaclePlusTime = 0;
float obstacleMinusTime = 0;
int oneway = ctx.getRouter().isOneWay(road);
boolean minusAllowed;
boolean plusAllowed;
// use positive direction as agreed
if(ctx.firstRoadId == calculateRoutePointId(road, middle, true) ) {
minusAllowed = ctx.firstRoadDirection <= 0;
plusAllowed = ctx.firstRoadDirection >= 0;
} else if (!reverseWaySearch) {
minusAllowed = oneway <= 0;
plusAllowed = oneway >= 0;
} else {
minusAllowed = oneway >= 0;
plusAllowed = oneway <= 0;
}
if(middle == road.getPointsLength() - 1 ||
visitedSegments.containsKey(calculateRoutePointId(road, middle, true)) ||
segment.getAllowedDirection() == -1) {
plusAllowed = false;
}
if(middle == 0 || visitedSegments.containsKey(calculateRoutePointId(road, middle - 1, false)) ||
segment.getAllowedDirection() == 1) {
minusAllowed = false;
}
// +/- diff from middle point
int d = plusAllowed ? 1 : -1;
if(segment.getParentRoute() != null) {
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());
}
}
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 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--;
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 {
if (d <= 0) {
d = -d + 1;
} else {
d = -d;
}
segmentEnd --;
}
if (segmentEnd < 0) {
minusAllowed = false;
if (segmentEnd < 0 || segmentEnd >= road.getPointsLength()) {
directionAllowed = 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);
if (oppositeSegments.containsKey(opp)) {
opposite = oppositeSegments.get(opp);
if (opposite.getSegmentStart() != segmentEnd) {
opposite = null;
}
}
final int intervalId = direction ? segmentEnd - 1 : segmentEnd;
visitedSegments.put(calculateRoutePointId(road, intervalId, direction), segment);
// 2. calculate point and try to load neighbor ways if they are not loaded
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));
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
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;
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
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 speed = (ctx.getRouter().defineSpeed(road) * priority);
if (speed == 0) {
speed = (ctx.getRouter().getMinDefaultSpeed() * priority);
}
// speed can not exceed max default speed according to A*
if(speed > ctx.getRouter().getMaxDefaultSpeed()) {
speed = ctx.getRouter().getMaxDefaultSpeed();
}
float distOnRoadToPass = positive? posSegmentDist : negSegmentDist;
float distStartObstacles = segment.distanceFromStart + ( positive ? obstaclePlusTime : obstacleMinusTime) +
distOnRoadToPass / speed;
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;
}
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 = next;
RouteSegment r = roadNext;
while(r != null && !outgoingConnections) {
if(r.road.id != road.id || r.getSegmentStart() != 0 || r.road.getOneway() != 1){
outgoingConnections = true;
@ -629,23 +538,100 @@ public class BinaryRoutePlanner {
r = r.next;
}
if (outgoingConnections) {
if (positive) {
plusAllowed = false;
} else {
minusAllowed = false;
}
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, next, reverseWaySearch, outgoingConnections);
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();
int oneway = ctx.getRouter().isOneWay(road);
// use positive direction as agreed
if(ctx.firstRoadId == calculateRoutePointId(road, middle, true) ) {
if(direction){
directionAllowed = ctx.firstRoadDirection >= 0;
} else {
directionAllowed = ctx.firstRoadDirection <= 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 ||
visitedSegments.containsKey(calculateRoutePointId(road, middle, true)) ||
segment.getAllowedDirection() == -1) {
directionAllowed = false;
}
} else {
if(middle == 0 || visitedSegments.containsKey(calculateRoutePointId(road, middle - 1, false)) ||
segment.getAllowedDirection() == 1) {
directionAllowed = false;
}
}
return directionAllowed;
}
private boolean checkIfOppositieSegmentWasVisited(final RoutingContext ctx, boolean reverseWaySearch,
PriorityQueue<RouteSegment> graphSegments, RouteSegment segment, TLongObjectHashMap<RouteSegment> oppositeSegments,
final RouteDataObject road, int segmentEnd, boolean positive, int intervalId, float segmentDist, float obstaclesTime) {
long opp = calculateRoutePointId(road, intervalId, !positive);
if (oppositeSegments.containsKey(opp)) {
RouteSegment opposite = oppositeSegments.get(opp);
if (opposite.getSegmentStart() == segmentEnd) {
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;
}
private float calculateTimeWithObstacles(RoutingContext ctx, RouteDataObject road, float distOnRoadToPass, float obstaclesTime) {
float priority = ctx.getRouter().defineSpeedPriority(road);
float speed = (ctx.getRouter().defineSpeed(road) * priority);
if (speed == 0) {
speed = (ctx.getRouter().getMinDefaultSpeed() * priority);
}
// speed can not exceed max default speed according to A*
if(speed > ctx.getRouter().getMaxDefaultSpeed()) {
speed = ctx.getRouter().getMaxDefaultSpeed();
}
float distStartObstacles = obstaclesTime +
distOnRoadToPass / speed;
return distStartObstacles;
}
private long calculateRoutePointId(final RouteDataObject road, int intervalId, boolean positive) {
return (road.getId() << ROUTE_POINTS) + (intervalId << 1) + (positive ? 1 : 0);
}
@ -738,6 +724,9 @@ public class BinaryRoutePlanner {
Iterator<RouteSegment> nextIterator = null;
if (thereAreRestrictions) {
nextIterator = ctx.segmentsToVisitPrescripted.iterator();
if(TRACE_ROUTING){
System.out.println(" >> There are restrictions");
}
}
// Calculate possible ways to put into priority queue
RouteSegment next = inputNext;
@ -774,13 +763,18 @@ public class BinaryRoutePlanner {
if(sameRoadFutureDirection) {
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
next.setParentRoute(segment);
next.setParentSegmentEnd(segmentEnd);
graphSegments.add(next);
}
if (ctx.visitor != null) {
ctx.visitor.visitSegment(next, false);
// ctx.visitor.visitSegment(next, false);
}
} else if(!sameRoadFutureDirection){
// 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.setParentSegmentEnd(segmentEnd);
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 void visitSegment(RouteSegment segment, boolean poll);
public void visitSegment(RouteSegment segment, int segmentEnd, boolean poll);
}
public static class RouteSegment {

View file

@ -18,7 +18,7 @@ import org.xml.sax.helpers.DefaultHandler;
public class RoutingConfiguration {
// 1. parameters of routing and different tweaks
// Influence on A* : f(x) + heuristicCoefficient*g(X)
public double heuristicCoefficient = 1;
public float heuristicCoefficient = 1;
public static final int DEFAULT_MEMORY_LIMIT = 30;
@ -34,7 +34,7 @@ public class RoutingConfiguration {
// 1.3 Relaxing strategy
public boolean useRelaxingStrategy = true;
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)
// 0 - 2 ways, 1 - direct way, -1 - reverse way
@ -63,7 +63,7 @@ public class RoutingConfiguration {
}
RoutingConfiguration i = new RoutingConfiguration();
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);
int desirable = parseSilentInt(getAttribute(router, "memoryLimitInMB"), 0);
if(desirable != 0) {
@ -78,7 +78,7 @@ public class RoutingConfiguration {
i.useRelaxingStrategy = parseSilentBoolean(getAttribute(router, "useRelaxingStrategy"), i.useRelaxingStrategy);
i.dynamicRoadPriorityDistance = parseSilentInt(getAttribute(router, "dynamicRoadPriorityDistance"), i.dynamicRoadPriorityDistance);
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);
if (!routers.containsKey(router)) {
@ -117,11 +117,11 @@ public class RoutingConfiguration {
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) {
return v;
}
return Double.parseDouble(t);
return Float.parseFloat(t);
}
@ -173,22 +173,22 @@ public class RoutingConfiguration {
if (previousKey != null) {
String k = in + ":" + previousKey;
if (attributes.getValue("penalty") != null) {
double penalty = parseSilentDouble(attributes.getValue("penalty"), 0);
float penalty = parseSilentFloat(attributes.getValue("penalty"), 0);
currentRouter.obstacles.put(k, penalty);
double routingPenalty = parseSilentDouble(attributes.getValue("routingPenalty"), penalty );
float routingPenalty = parseSilentFloat(attributes.getValue("routingPenalty"), penalty );
currentRouter.routingObstacles.put(k, routingPenalty);
}
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) {
currentRouter.highwayFuturePriorities.put(k, parseSilentDouble(attributes.getValue("dynamicPriority"), 0));
currentRouter.highwayFuturePriorities.put(k, parseSilentFloat(attributes.getValue("dynamicPriority"), 0));
}
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)) {
double priority = parseSilentDouble(attributes.getValue("decreasedPriority"), 0);
float priority = parseSilentFloat(attributes.getValue("decreasedPriority"), 0);
if (priority == 0) {
currentRouter.avoid.put(k, priority);
} else {
@ -200,23 +200,23 @@ public class RoutingConfiguration {
} else if("road".equals(name)) {
previousTag = name;
previousKey = attributes.getValue("tag") +"$" + attributes.getValue("value");
currentRouter.highwayPriorities.put(previousKey, parseSilentDouble(attributes.getValue("priority"),
currentRouter.highwayPriorities.put(previousKey, parseSilentFloat(attributes.getValue("priority"),
1));
currentRouter.highwayFuturePriorities.put(previousKey, parseSilentDouble(attributes.getValue("dynamicPriority"),
currentRouter.highwayFuturePriorities.put(previousKey, parseSilentFloat(attributes.getValue("dynamicPriority"),
1));
currentRouter.highwaySpeed.put(previousKey, parseSilentDouble(attributes.getValue("speed"),
currentRouter.highwaySpeed.put(previousKey, parseSilentFloat(attributes.getValue("speed"),
10));
} else if("obstacle".equals(name)) {
previousTag = name;
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);
double routingPenalty = parseSilentDouble(attributes.getValue("routingPenalty"), penalty );
float routingPenalty = parseSilentFloat(attributes.getValue("routingPenalty"), penalty );
currentRouter.routingObstacles.put(previousKey, routingPenalty);
} else if("avoid".equals(name)) {
previousTag = name;
previousKey = attributes.getValue("tag") + "$" + attributes.getValue("value");
double priority = parseSilentDouble(attributes.getValue("decreasedPriority"),
float priority = parseSilentFloat(attributes.getValue("decreasedPriority"),
0);
if(priority == 0) {
currentRouter.avoid.put(previousKey, priority);

View file

@ -34,7 +34,7 @@ import org.apache.commons.logging.Log;
public class RoutingContext {
public static final boolean SHOW_GC_SIZE = false;
public boolean USE_BASEMAP = false;
private final static Log log = LogUtil.getLog(RoutingContext.class);
public static final int OPTION_NO_LOAD = 0;
@ -42,6 +42,7 @@ public class RoutingContext {
public static final int OPTION_IN_MEMORY_LOAD = 2;
// Final context variables
public final RoutingConfiguration config;
private final boolean useBaseMap;
public final NativeLibrary nativeLib;
public final Map<BinaryMapIndexReader, List<RouteSubregion>> map = new LinkedHashMap<BinaryMapIndexReader, List<RouteSubregion>>();
public final Map<RouteRegion, BinaryMapIndexReader> reverseMap = new LinkedHashMap<RouteRegion, BinaryMapIndexReader>();
@ -96,6 +97,7 @@ public class RoutingContext {
public RoutingContext(RoutingContext cp) {
this.config = cp.config;
this.map.putAll(cp.map);
this.useBaseMap = cp.useBaseMap;
this.reverseMap.putAll(cp.reverseMap);
this.nativeLib = cp.nativeLib;
// copy local data and clear caches
@ -117,11 +119,16 @@ public class RoutingContext {
}
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) {
List<RouteRegion> rr = mr.getRoutingIndexes();
List<RouteSubregion> subregions = new ArrayList<BinaryMapRouteReaderAdapter.RouteSubregion>();
for (RouteRegion r : rr) {
List<RouteSubregion> subregs = USE_BASEMAP ? r.getBaseSubregions() :
List<RouteSubregion> subregs = useBaseMap ? r.getBaseSubregions() :
r.getSubregions();
for (RouteSubregion rs : subregs) {
subregions.add(new RouteSubregion(rs));
@ -193,7 +200,7 @@ public class RoutingContext {
config.router = router;
}
public void setHeuristicCoefficient(double heuristicCoefficient) {
public void setHeuristicCoefficient(float heuristicCoefficient) {
config.heuristicCoefficient = heuristicCoefficient;
}

View file

@ -10,7 +10,7 @@
<attribute name="zoomToLoadTiles" value="16" />
<!-- by default it is 30. Value specified here overwrites all others
(don't specify here ! it is device dependent) -->
<attribute name="memoryLimitInMB" value="" />
<attribute name="memoryLimitInMB" value="450" />
<!-- 1.2 Dynamic road prioritizing (heuristic) -->
<attribute name="useDynamicRoadPrioritising" value="false" />

View file

@ -138,8 +138,9 @@ public class MapClusterLayer implements MapPanelLayer {
ctx.setVisitor(new RouteSegmentVisitor() {
private List<RouteSegment> cache = new ArrayList<RouteSegment>();
@Override
public void visitSegment(RouteSegment s, boolean poll) {
public void visitSegment(RouteSegment s, int endSegment, boolean poll) {
if(!ANIMATE_CLUSTERING){
return;
}
@ -269,7 +270,7 @@ public class MapClusterLayer implements MapPanelLayer {
if (!onTheMap.contains(toAdd.getRoad().getId())) {
onTheMap.add(toAdd.getRoad().getId());
// Visualization of steps !
ctx.getVisitor().visitSegment(toAdd, true);
ctx.getVisitor().visitSegment(toAdd, -1, true);
}
List<RouteSegment> nextSegments = new ArrayList<BinaryRoutePlanner.RouteSegment>();
boolean out = false;

View file

@ -617,8 +617,7 @@ public class MapRouterLayer implements MapPanelLayer {
RoutingConfiguration config = builder.build(props[0], RoutingConfiguration.DEFAULT_MEMORY_LIMIT / 2, props);
// config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 300;
// config.ZOOM_TO_LOAD_TILES = 14;
RoutingContext ctx = new RoutingContext(config, NativeSwingRendering.getDefaultFromSettings(), rs);
ctx.USE_BASEMAP = useBasemap;
RoutingContext ctx = new RoutingContext(config, NativeSwingRendering.getDefaultFromSettings(), rs, useBasemap);
ctx.previouslyCalculatedRoute = previousRoute;
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> pollCache = new ArrayList<RouteSegment>();
private List<Integer> cacheInt = new ArrayList<Integer>();
@Override
public void visitSegment(RouteSegment s, boolean poll) {
public void visitSegment(RouteSegment s, int endSegment, boolean poll) {
if(stop) {
throw new RuntimeException("Interrupted");
}
@ -670,32 +670,44 @@ public class MapRouterLayer implements MapPanelLayer {
}
cache.add(s);
cacheInt.add(endSegment);
if (cache.size() < steps) {
return;
}
if(pause) {
registerObjects(points, poll, pollCache);
registerObjects(points, poll, pollCache, null);
pollCache.clear();
}
registerObjects(points, !poll, cache);
registerObjects(points, !poll, cache, cacheInt);
cache.clear();
cacheInt.clear();
redraw();
if (pause) {
waitNextPress();
}
}
private void registerObjects(final DataTileManager<Entity> points, boolean white,
List<RouteSegment> registerCache) {
for (RouteSegment segment : registerCache) {
private void registerObjects(final DataTileManager<Entity> points, boolean white, List<RouteSegment> registerCache,
List<Integer> cacheInt) {
for (int l = 0; l < registerCache.size(); l++) {
RouteSegment segment = registerCache.get(l);
Way way = new Way(-1);
way.putTag(OSMTagKey.NAME.getValue(), segment.getTestName());
if(white) {
if (white) {
way.putTag("color", "white");
}
for (int i = 0; i < segment.getRoad().getPointsLength(); i++) {
net.osmand.osm.Node n = createNode(segment, i);
way.addNode(n);
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);
way.addNode(n);
}
}
LatLon n = way.getLatLon();
points.registerObject(n.getLatitude(), n.getLongitude(), way);