private void visitAllStartSegments( final RoutingContext ctx, RouteSegment start, PriorityQueue<RouteSegment> graphDirectSegments, TLongObjectHashMap<RouteSegment> visitedSegments, int startX, int startY) throws IOException { // mark as visited code seems to be duplicated long nt = (start.road.getId() << 8l) + start.segmentStart; visitedSegments.put(nt, start); graphDirectSegments.add(start); loadRoutes( ctx, (startX >> (31 - ctx.getZoomToLoadTileWithRoads())), (startY >> (31 - ctx.getZoomToLoadTileWithRoads()))); long ls = (((long) startX) << 31) + (long) startY; RouteSegment startNbs = ctx.routes.get(ls); while (startNbs != null) { // startNbs.road.id >> 1, start.road.id >> 1 if (startNbs.road.getId() != start.road.getId()) { startNbs.parentRoute = start; startNbs.parentSegmentEnd = start.segmentStart; startNbs.distanceToEnd = start.distanceToEnd; // duplicated to be sure start is added nt = (startNbs.road.getId() << 8l) + startNbs.segmentStart; visitedSegments.put(nt, startNbs); graphDirectSegments.add(startNbs); } startNbs = startNbs.next; } }
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 inputNext, boolean reverseWay) { // This variables can be in routing context // initialize temporary lists to calculate not forbidden ways at way intersections ArrayList<RouteSegment> segmentsToVisitPrescripted = new ArrayList<RouteSegment>(5); ArrayList<RouteSegment> segmentsToVisitNotForbidden = new ArrayList<RouteSegment>(5); // collect time for obstacles double obstaclesTime = 0; boolean exclusiveRestriction = false; // 3.1 calculate time for obstacles (bumps, traffic_signals, level_crossing) if (firstOfSegment) { RouteSegment possibleObstacle = inputNext; while (possibleObstacle != null) { obstaclesTime += ctx.getRouter().defineObstacle(possibleObstacle.road, possibleObstacle.segmentStart); possibleObstacle = possibleObstacle.next; } } // 3.2 calculate possible ways to put into priority queue // for debug next.road.getId() >> 1 == 33911427 && road.getId() >> 1 == 33911442 RouteSegment next = inputNext; while (next != null) { long nts = (next.road.getId() << 8l) + next.segmentStart; boolean oppositeConnectionFound = oppositeSegments.containsKey(nts) && oppositeSegments.get(nts) != null; boolean processRoad = true; if (ctx.isUseStrategyOfIncreasingRoadPriorities()) { double roadPriority = ctx.getRouter().getRoadPriorityHeuristicToIncrease(segment.road); double nextRoadPriority = ctx.getRouter().getRoadPriorityHeuristicToIncrease(segment.road); if (nextRoadPriority < roadPriority) { processRoad = false; } } /* next.road.getId() >> 1 (3) != road.getId() >> 1 (3) - used that line for debug with osm map */ // road.id could be equal on roundabout, but we should accept them if ((!visitedSegments.contains(nts) && processRoad) || oppositeConnectionFound) { int type = -1; if (!reverseWay) { for (int i = 0; i < road.getRestrictionCount(); i++) { if (road.getRestriction(i) == next.road.getId()) { type = road.getRestrictionType(i); break; } } } else { for (int i = 0; i < next.road.getRestrictionCount(); i++) { if (next.road.getRestriction(i) == road.getId()) { type = next.road.getRestrictionType(i); break; } // Check if there is restriction only to the current road if (next.road.getRestrictionType(i) == MapRenderingTypes.RESTRICTION_ONLY_RIGHT_TURN || next.road.getRestrictionType(i) == MapRenderingTypes.RESTRICTION_ONLY_LEFT_TURN || next.road.getRestrictionType(i) == MapRenderingTypes.RESTRICTION_ONLY_STRAIGHT_ON) { // check if that restriction applies to considered junk RouteSegment foundNext = inputNext; while (foundNext != null && foundNext.getRoad().getId() != next.road.getRestriction(i)) { foundNext = foundNext.next; } if (foundNext != null) { type = REVERSE_WAY_RESTRICTION_ONLY; // special constant } } } } if (type == REVERSE_WAY_RESTRICTION_ONLY) { // next = next.next; continue; } else if (type == -1 && exclusiveRestriction) { // next = next.next; continue; } else if (type == MapRenderingTypes.RESTRICTION_NO_LEFT_TURN || type == MapRenderingTypes.RESTRICTION_NO_RIGHT_TURN || type == MapRenderingTypes.RESTRICTION_NO_STRAIGHT_ON || type == MapRenderingTypes.RESTRICTION_NO_U_TURN) { // next = next.next; continue; } else { // no restriction can go out if (oppositeConnectionFound) { RouteSegment oppSegment = oppositeSegments.get(nts); oppSegment.segmentEnd = next.segmentStart; return oppSegment; } double distanceToEnd = distToFinalPoint / ctx.getRouter().getMaxDefaultSpeed(); if (ctx.isUseDynamicRoadPrioritising()) { double priority = ctx.getRouter().getRoadPriorityToCalculateRoute(next.road); distanceToEnd /= priority; } // Using A* routing algorithm // g(x) - calculate distance to that point and calculate time double speed = ctx.getRouter().defineSpeed(road); if (speed == 0) { speed = ctx.getRouter().getMinDefaultSpeed(); } double distanceFromStart = segment.distanceFromStart + distOnRoadToPass / speed; // calculate turn time distanceFromStart += ctx.getRouter().calculateTurnTime(segment, next, segmentEnd); // add obstacles time distanceFromStart += obstaclesTime; // segment.getRoad().getId() >> 1 if (next.parentRoute == null || ctx.roadPriorityComparator( next.distanceFromStart, next.distanceToEnd, distanceFromStart, distanceToEnd) > 0) { next.distanceFromStart = distanceFromStart; next.distanceToEnd = distanceToEnd; if (next.parentRoute != null) { // already in queue remove it graphSegments.remove(next); } // put additional information to recover whole route after next.parentRoute = segment; next.parentSegmentEnd = segmentEnd; if (type == -1) { // case no restriction segmentsToVisitNotForbidden.add(next); } else { // case exclusive restriction (only_right, only_straight, ...) // 1. in case we are going backward we should not consider only_restriction // as exclusive because we have main "in" roads and one "out" // 2. in case we are going forward we have one "in" and many "out" if (!reverseWay) { exclusiveRestriction = true; segmentsToVisitNotForbidden.clear(); segmentsToVisitPrescripted.add(next); } else { segmentsToVisitNotForbidden.add(next); } } } } } next = next.next; } // add all allowed route segments to priority queue for (RouteSegment s : segmentsToVisitNotForbidden) { graphSegments.add(s); } for (RouteSegment s : segmentsToVisitPrescripted) { graphSegments.add(s); } return null; }