Search in sources :

Example 21 with RouteDataObject

use of net.osmand.binary.RouteDataObject in project Osmand by osmandapp.

the class RoutingContext method loadTileData.

public void loadTileData(int x31, int y31, int zoomAround, final List<RouteDataObject> toFillIn) {
    int t = config.ZOOM_TO_LOAD_TILES - zoomAround;
    int coordinatesShift = (1 << (31 - config.ZOOM_TO_LOAD_TILES));
    if (t <= 0) {
        t = 1;
        coordinatesShift = (1 << (31 - zoomAround));
    } else {
        t = 1 << t;
    }
    TLongHashSet ts = new TLongHashSet();
    long now = System.nanoTime();
    for (int i = -t; i <= t; i++) {
        for (int j = -t; j <= t; j++) {
            ts.add(getRoutingTile(x31 + i * coordinatesShift, y31 + j * coordinatesShift, 0, OPTION_IN_MEMORY_LOAD));
        }
    }
    TLongIterator it = ts.iterator();
    TLongObjectHashMap<RouteDataObject> excludeDuplications = new TLongObjectHashMap<RouteDataObject>();
    while (it.hasNext()) {
        getAllObjects(it.next(), toFillIn, excludeDuplications);
    }
    timeToFindInitialSegments += (System.nanoTime() - now);
}
Also used : TLongHashSet(gnu.trove.set.hash.TLongHashSet) TLongObjectHashMap(gnu.trove.map.hash.TLongObjectHashMap) RouteDataObject(net.osmand.binary.RouteDataObject) TLongIterator(gnu.trove.iterator.TLongIterator)

Example 22 with RouteDataObject

use of net.osmand.binary.RouteDataObject in project Osmand by osmandapp.

the class BinaryRoutePlanner method checkIfOppositeSegmentWasVisited.

private boolean checkIfOppositeSegmentWasVisited(final RoutingContext ctx, boolean reverseWaySearch, PriorityQueue<RouteSegment> graphSegments, RouteSegment segment, TLongObjectHashMap<RouteSegment> oppositeSegments, int segmentPoint, float segmentDist, float obstaclesTime) {
    RouteDataObject road = segment.getRoad();
    long opp = calculateRoutePointId(road, segment.isPositive() ? segmentPoint - 1 : segmentPoint, !segment.isPositive());
    if (oppositeSegments.containsKey(opp)) {
        RouteSegment opposite = oppositeSegments.get(opp);
        RouteSegment to = reverseWaySearch ? getParentDiffId(segment) : getParentDiffId(opposite);
        RouteSegment from = !reverseWaySearch ? getParentDiffId(segment) : getParentDiffId(opposite);
        if (checkViaRestrictions(from, to)) {
            FinalRouteSegment frs = new FinalRouteSegment(road, segmentPoint);
            float distStartObstacles = segment.distanceFromStart + calculateTimeWithObstacles(ctx, road, segmentDist, obstaclesTime);
            frs.setParentRoute(segment);
            frs.setParentSegmentEnd(segmentPoint);
            frs.reverseWaySearch = reverseWaySearch;
            frs.distanceFromStart = opposite.distanceFromStart + distStartObstacles;
            frs.distanceToEnd = 0;
            frs.opposite = opposite;
            graphSegments.add(frs);
            if (TRACE_ROUTING) {
                printRoad("  >> Final segment : ", frs, reverseWaySearch);
            }
            return true;
        }
    }
    return false;
}
Also used : RouteDataObject(net.osmand.binary.RouteDataObject)

Example 23 with RouteDataObject

use of net.osmand.binary.RouteDataObject in project Osmand by osmandapp.

the class BinaryRoutePlanner method processRouteSegment.

@SuppressWarnings("unused")
private void processRouteSegment(final RoutingContext ctx, boolean reverseWaySearch, PriorityQueue<RouteSegment> graphSegments, TLongObjectHashMap<RouteSegment> visitedSegments, RouteSegment segment, TLongObjectHashMap<RouteSegment> oppositeSegments, boolean doNotAddIntersections) throws IOException {
    final RouteDataObject road = segment.road;
    boolean initDirectionAllowed = checkIfInitialMovementAllowedOnSegment(ctx, reverseWaySearch, visitedSegments, segment, road);
    if (TEST_SPECIFIC && road.getId() >> 6 == TEST_ID) {
        printRoad(" ! " + +segment.distanceFromStart + " ", segment, reverseWaySearch);
    }
    boolean directionAllowed = initDirectionAllowed;
    if (!directionAllowed) {
        if (TRACE_ROUTING) {
            println("  >> Already visited");
        }
        return;
    }
    // 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;
    float segmentDist = 0;
    // +/- diff from middle point
    short segmentPoint = segment.getSegmentStart();
    boolean[] processFurther = new boolean[1];
    RouteSegment previous = segment;
    boolean dir = segment.isPositive();
    while (directionAllowed) {
        // mark previous interval as visited and move to next intersection
        short prevInd = segmentPoint;
        if (dir) {
            segmentPoint++;
        } else {
            segmentPoint--;
        }
        if (segmentPoint < 0 || segmentPoint >= road.getPointsLength()) {
            directionAllowed = false;
            continue;
        }
        // store <segment> in order to not have unique <segment, direction> in visitedSegments
        visitedSegments.put(calculateRoutePointId(segment.getRoad(), segment.isPositive() ? segmentPoint - 1 : segmentPoint, segment.isPositive()), previous != null ? previous : segment);
        final int x = road.getPoint31XTile(segmentPoint);
        final int y = road.getPoint31YTile(segmentPoint);
        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, segmentPoint);
        if (obstacle < 0) {
            directionAllowed = false;
            continue;
        }
        double heightObstacle = ctx.getRouter().defineHeightObstacle(road, !reverseWaySearch ? prevInd : segmentPoint, !reverseWaySearch ? segmentPoint : prevInd);
        if (heightObstacle < 0) {
            directionAllowed = false;
            continue;
        }
        boolean alreadyVisited = checkIfOppositeSegmentWasVisited(ctx, reverseWaySearch, graphSegments, segment, oppositeSegments, segmentPoint, segmentDist, obstaclesTime);
        obstaclesTime += obstacle;
        obstaclesTime += heightObstacle;
        if (alreadyVisited) {
            directionAllowed = false;
            continue;
        }
        // correct way of handling precalculatedRouteDirection
        if (ctx.precalculatedRouteDirection != null) {
        // long nt = System.nanoTime();
        // float devDistance = ctx.precalculatedRouteDirection.getDeviationDistance(x, y);
        // // 1. linear method
        // segmentDist = segmentDist * (1 + devDistance / ctx.config.DEVIATION_RADIUS);
        // // 2. exponential method
        // segmentDist = segmentDist * (float) Math.pow(1.5, devDistance / 500);
        // 3. next by method
        // segmentDist = devDistance ;
        // ctx.timeNanoToCalcDeviation += (System.nanoTime() - nt);
        }
        // could be expensive calculation
        // 3. get intersected ways
        final RouteSegment roadNext = ctx.loadRouteSegment(x, y, ctx.config.memoryLimitation - ctx.memoryOverhead);
        float distStartObstacles = segment.distanceFromStart + calculateTimeWithObstacles(ctx, road, segmentDist, obstaclesTime);
        if (ctx.precalculatedRouteDirection != null && ctx.precalculatedRouteDirection.isFollowNext()) {
            // reset to f
            // distStartObstacles = 0;
            // more precise but slower
            distStartObstacles = ctx.precalculatedRouteDirection.getDeviationDistance(x, y) / ctx.getRouter().getMaxDefaultSpeed();
        }
        // We don't check if there are outgoing connections
        previous = processIntersections(ctx, graphSegments, visitedSegments, distStartObstacles, segment, segmentPoint, roadNext, reverseWaySearch, doNotAddIntersections, processFurther);
        if (!processFurther[0]) {
            directionAllowed = false;
            continue;
        }
    }
    if (initDirectionAllowed && ctx.visitor != null) {
        ctx.visitor.visitSegment(segment, segmentPoint, true);
    }
}
Also used : RouteDataObject(net.osmand.binary.RouteDataObject)

Example 24 with RouteDataObject

use of net.osmand.binary.RouteDataObject in project Osmand by osmandapp.

the class RouteResultPreparation method calculateTimeSpeed.

private void calculateTimeSpeed(RoutingContext ctx, List<RouteSegmentResult> result) throws IOException {
    // for Naismith
    boolean usePedestrianHeight = ((((GeneralRouter) ctx.getRouter()).getProfile() == GeneralRouterProfile.PEDESTRIAN) && ((GeneralRouter) ctx.getRouter()).getHeightObstacles());
    for (int i = 0; i < result.size(); i++) {
        RouteSegmentResult rr = result.get(i);
        RouteDataObject road = rr.getObject();
        double distOnRoadToPass = 0;
        double speed = ctx.getRouter().defineVehicleSpeed(road);
        if (speed == 0) {
            speed = ctx.getRouter().getMinDefaultSpeed();
        } else {
            if (speed > 15) {
                // decrease speed proportionally from 15ms=50kmh -
                // reference speed 30ms=108kmh - 7kmh
                speed = speed - ((speed - 15f) / (30f - 15f) * 2f);
            }
        }
        boolean plus = rr.getStartPointIndex() < rr.getEndPointIndex();
        int next;
        double distance = 0;
        // for Naismith
        float prevHeight = -99999.0f;
        float[] heightDistanceArray = null;
        if (usePedestrianHeight) {
            road.calculateHeightArray();
            heightDistanceArray = road.heightDistanceArray;
        }
        for (int j = rr.getStartPointIndex(); j != rr.getEndPointIndex(); j = next) {
            next = plus ? j + 1 : j - 1;
            double d = measuredDist(road.getPoint31XTile(j), road.getPoint31YTile(j), road.getPoint31XTile(next), road.getPoint31YTile(next));
            distance += d;
            double obstacle = ctx.getRouter().defineObstacle(road, j);
            if (obstacle < 0) {
                obstacle = 0;
            }
            // this is time in seconds
            distOnRoadToPass += d / speed + obstacle;
            // for Naismith
            if (usePedestrianHeight) {
                int heightIndex = 2 * j + 1;
                if (heightDistanceArray != null && heightIndex < heightDistanceArray.length) {
                    float height = heightDistanceArray[heightIndex];
                    if (prevHeight != -99999.0f) {
                        float heightDiff = height - prevHeight;
                        if (heightDiff > 0) {
                            // ascent only
                            // Naismith's rule: add 1 hour per every 600m of ascent
                            distOnRoadToPass += heightDiff * 6.0f;
                        }
                    }
                    prevHeight = height;
                }
            }
        }
        // last point turn time can be added
        // if(i + 1 < result.size()) { distOnRoadToPass += ctx.getRouter().calculateTurnTime(); }
        rr.setSegmentTime((float) distOnRoadToPass);
        rr.setSegmentSpeed((float) speed);
        rr.setDistance((float) distance);
    }
}
Also used : RouteDataObject(net.osmand.binary.RouteDataObject)

Example 25 with RouteDataObject

use of net.osmand.binary.RouteDataObject in project Osmand by osmandapp.

the class RouteResultPreparation method splitRoadsAndAttachRoadSegments.

private void splitRoadsAndAttachRoadSegments(RoutingContext ctx, List<RouteSegmentResult> result) throws IOException {
    for (int i = 0; i < result.size(); i++) {
        if (ctx.checkIfMemoryLimitCritical(ctx.config.memoryLimitation)) {
            ctx.unloadUnusedTiles(ctx.config.memoryLimitation);
        }
        RouteSegmentResult rr = result.get(i);
        RouteDataObject road = rr.getObject();
        checkAndInitRouteRegion(ctx, road);
        boolean plus = rr.getStartPointIndex() < rr.getEndPointIndex();
        int next;
        for (int j = rr.getStartPointIndex(); j != rr.getEndPointIndex(); j = next) {
            next = plus ? j + 1 : j - 1;
            if (j == rr.getStartPointIndex()) {
                attachRoadSegments(ctx, result, i, j, plus);
            }
            if (next != rr.getEndPointIndex()) {
                attachRoadSegments(ctx, result, i, next, plus);
            }
            List<RouteSegmentResult> attachedRoutes = rr.getAttachedRoutes(next);
            boolean tryToSplit = next != rr.getEndPointIndex() && !rr.getObject().roundabout() && attachedRoutes != null;
            if (rr.getDistance(next, plus) == 0) {
                // same point will be processed next step
                tryToSplit = false;
            }
            if (tryToSplit) {
                // avoid small zigzags
                float before = rr.getBearing(next, !plus);
                float after = rr.getBearing(next, plus);
                if (rr.getDistance(next, plus) < 5) {
                    after = before + 180;
                } else if (rr.getDistance(next, !plus) < 5) {
                    before = after - 180;
                }
                boolean straight = Math.abs(MapUtils.degreesDiff(before + 180, after)) < TURN_DEGREE_MIN;
                boolean isSplit = false;
                // split if needed
                for (RouteSegmentResult rs : attachedRoutes) {
                    double diff = MapUtils.degreesDiff(before + 180, rs.getBearingBegin());
                    if (Math.abs(diff) <= TURN_DEGREE_MIN) {
                        isSplit = true;
                    } else if (!straight && Math.abs(diff) < 100) {
                        isSplit = true;
                    }
                }
                if (isSplit) {
                    int endPointIndex = rr.getEndPointIndex();
                    RouteSegmentResult split = new RouteSegmentResult(rr.getObject(), next, endPointIndex);
                    split.copyPreattachedRoutes(rr, Math.abs(next - rr.getStartPointIndex()));
                    rr.setEndPointIndex(next);
                    result.add(i + 1, split);
                    i++;
                    // switch current segment to the splitted
                    rr = split;
                }
            }
        }
    }
}
Also used : RouteDataObject(net.osmand.binary.RouteDataObject)

Aggregations

RouteDataObject (net.osmand.binary.RouteDataObject)49 ArrayList (java.util.ArrayList)13 TLongObjectHashMap (gnu.trove.map.hash.TLongObjectHashMap)9 Location (net.osmand.Location)9 RouteSegment (net.osmand.router.BinaryRoutePlanner.RouteSegment)8 TLongHashSet (gnu.trove.set.hash.TLongHashSet)7 LatLon (net.osmand.data.LatLon)6 IOException (java.io.IOException)5 RouteSubregion (net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion)4 QuadPoint (net.osmand.data.QuadPoint)4 File (java.io.File)3 LinkedHashMap (java.util.LinkedHashMap)3 List (java.util.List)3 BinaryMapDataObject (net.osmand.binary.BinaryMapDataObject)3 RouteRegion (net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion)3 RoutePlannerFrontEnd (net.osmand.router.RoutePlannerFrontEnd)3 RoutingConfiguration (net.osmand.router.RoutingConfiguration)3 RoutingContext (net.osmand.router.RoutingContext)3 TLongArrayList (gnu.trove.list.array.TLongArrayList)2 Point (java.awt.Point)2