Search in sources :

Example 6 with TurnType

use of net.osmand.router.TurnType in project Osmand by osmandapp.

the class RouteCalculationResult method addMissingTurnsToRoute.

protected static void addMissingTurnsToRoute(List<Location> locations, List<RouteDirectionInfo> originalDirections, Location start, LatLon end, ApplicationMode mode, Context ctx, boolean leftSide) {
    if (locations.isEmpty()) {
        return;
    }
    // speed m/s
    float speed = mode.getDefaultSpeed();
    int minDistanceForTurn = mode.getMinDistanceForTurn();
    List<RouteDirectionInfo> computeDirections = new ArrayList<RouteDirectionInfo>();
    int[] listDistance = new int[locations.size()];
    listDistance[locations.size() - 1] = 0;
    for (int i = locations.size() - 1; i > 0; i--) {
        listDistance[i - 1] = (int) Math.round(locations.get(i - 1).distanceTo(locations.get(i)));
        listDistance[i - 1] += listDistance[i];
    }
    int previousLocation = 0;
    int prevBearingLocation = 0;
    RouteDirectionInfo previousInfo = new RouteDirectionInfo(speed, TurnType.straight());
    previousInfo.routePointOffset = 0;
    previousInfo.setDescriptionRoute(ctx.getString(R.string.route_head));
    computeDirections.add(previousInfo);
    int distForTurn = 0;
    float previousBearing = 0;
    int startTurnPoint = 0;
    for (int i = 1; i < locations.size() - 1; i++) {
        Location next = locations.get(i + 1);
        Location current = locations.get(i);
        float bearing = current.bearingTo(next);
        // try to get close to current location if possible
        while (prevBearingLocation < i - 1) {
            if (locations.get(prevBearingLocation + 1).distanceTo(current) > 70) {
                prevBearingLocation++;
            } else {
                break;
            }
        }
        if (distForTurn == 0) {
            // measure only after turn
            previousBearing = locations.get(prevBearingLocation).bearingTo(current);
            startTurnPoint = i;
        }
        TurnType type = null;
        String description = null;
        float delta = previousBearing - bearing;
        while (delta < 0) {
            delta += 360;
        }
        while (delta > 360) {
            delta -= 360;
        }
        distForTurn += locations.get(i).distanceTo(locations.get(i + 1));
        if (i < locations.size() - 1 && distForTurn < minDistanceForTurn) {
            // 2) if there is a small gap between roads (turn right and after 4m next turn left) - so the direction head
            continue;
        }
        if (delta > 45 && delta < 315) {
            if (delta < 60) {
                type = TurnType.valueOf(TurnType.TSLL, leftSide);
                description = ctx.getString(R.string.route_tsll);
            } else if (delta < 120) {
                type = TurnType.valueOf(TurnType.TL, leftSide);
                description = ctx.getString(R.string.route_tl);
            } else if (delta < 150) {
                type = TurnType.valueOf(TurnType.TSHL, leftSide);
                description = ctx.getString(R.string.route_tshl);
            } else if (delta < 210) {
                type = TurnType.valueOf(TurnType.TU, leftSide);
                description = ctx.getString(R.string.route_tu);
            } else if (delta < 240) {
                description = ctx.getString(R.string.route_tshr);
                type = TurnType.valueOf(TurnType.TSHR, leftSide);
            } else if (delta < 300) {
                description = ctx.getString(R.string.route_tr);
                type = TurnType.valueOf(TurnType.TR, leftSide);
            } else {
                description = ctx.getString(R.string.route_tslr);
                type = TurnType.valueOf(TurnType.TSLR, leftSide);
            }
            // calculate for previousRoute
            previousInfo.distance = listDistance[previousLocation] - listDistance[i];
            type.setTurnAngle(360 - delta);
            previousInfo = new RouteDirectionInfo(speed, type);
            previousInfo.setDescriptionRoute(description);
            previousInfo.routePointOffset = startTurnPoint;
            computeDirections.add(previousInfo);
            previousLocation = startTurnPoint;
            // for bearing using current location
            prevBearingLocation = i;
        }
        // clear dist for turn
        distForTurn = 0;
    }
    previousInfo.distance = listDistance[previousLocation];
    if (originalDirections.isEmpty()) {
        originalDirections.addAll(computeDirections);
    } else {
        int currentDirection = 0;
        // one more
        for (int i = 0; i <= originalDirections.size() && currentDirection < computeDirections.size(); i++) {
            while (currentDirection < computeDirections.size()) {
                int distanceAfter = 0;
                if (i < originalDirections.size()) {
                    RouteDirectionInfo resInfo = originalDirections.get(i);
                    int r1 = computeDirections.get(currentDirection).routePointOffset;
                    int r2 = resInfo.routePointOffset;
                    distanceAfter = listDistance[resInfo.routePointOffset];
                    float dist = locations.get(r1).distanceTo(locations.get(r2));
                    // take into account that move roundabout is special turn that could be very lengthy
                    if (dist < 100) {
                        // the same turn duplicate
                        currentDirection++;
                        // while cycle
                        continue;
                    } else if (computeDirections.get(currentDirection).routePointOffset > resInfo.routePointOffset) {
                        // check it at the next point
                        break;
                    }
                }
                // add turn because it was missed
                RouteDirectionInfo toAdd = computeDirections.get(currentDirection);
                if (i > 0) {
                    // update previous
                    RouteDirectionInfo previous = originalDirections.get(i - 1);
                    toAdd.setAverageSpeed(previous.getAverageSpeed());
                }
                toAdd.distance = listDistance[toAdd.routePointOffset] - distanceAfter;
                if (i < originalDirections.size()) {
                    originalDirections.add(i, toAdd);
                } else {
                    originalDirections.add(toAdd);
                }
                i++;
                currentDirection++;
            }
        }
    }
    int sum = 0;
    for (int i = originalDirections.size() - 1; i >= 0; i--) {
        originalDirections.get(i).afterLeftTime = sum;
        sum += originalDirections.get(i).getExpectedTime();
    }
}
Also used : ArrayList(java.util.ArrayList) TurnType(net.osmand.router.TurnType) LocationPoint(net.osmand.data.LocationPoint) Location(net.osmand.Location)

Example 7 with TurnType

use of net.osmand.router.TurnType in project Osmand by osmandapp.

the class RouteProvider method parseOsmAndGPXRoute.

private static List<RouteDirectionInfo> parseOsmAndGPXRoute(List<Location> res, GPXFile gpxFile, boolean osmandRouter, boolean leftSide, float defSpeed) {
    List<RouteDirectionInfo> directions = null;
    if (!osmandRouter) {
        for (WptPt pt : gpxFile.getPoints()) {
            res.add(createLocation(pt));
        }
    } else {
        for (Track tr : gpxFile.tracks) {
            for (TrkSegment ts : tr.segments) {
                for (WptPt p : ts.points) {
                    res.add(createLocation(p));
                }
            }
        }
    }
    float[] distanceToEnd = new float[res.size()];
    for (int i = res.size() - 2; i >= 0; i--) {
        distanceToEnd[i] = distanceToEnd[i + 1] + res.get(i).distanceTo(res.get(i + 1));
    }
    Route route = null;
    if (gpxFile.routes.size() > 0) {
        route = gpxFile.routes.get(0);
    }
    RouteDirectionInfo previous = null;
    if (route != null && route.points.size() > 0) {
        directions = new ArrayList<RouteDirectionInfo>();
        Iterator<WptPt> iterator = route.points.iterator();
        while (iterator.hasNext()) {
            WptPt item = iterator.next();
            try {
                String stime = item.getExtensionsToRead().get("time");
                int time = 0;
                if (stime != null) {
                    time = Integer.parseInt(stime);
                }
                // $NON-NLS-1$
                int offset = Integer.parseInt(item.getExtensionsToRead().get("offset"));
                if (directions.size() > 0) {
                    RouteDirectionInfo last = directions.get(directions.size() - 1);
                    // update speed using time and idstance
                    last.setAverageSpeed((distanceToEnd[last.routePointOffset] - distanceToEnd[offset]) / last.getAverageSpeed());
                    last.distance = (int) Math.round(distanceToEnd[last.routePointOffset] - distanceToEnd[offset]);
                }
                // save time as a speed because we don't know distance of the route segment
                float avgSpeed = time;
                if (!iterator.hasNext() && time > 0) {
                    avgSpeed = distanceToEnd[offset] / time;
                }
                // $NON-NLS-1$
                String stype = item.getExtensionsToRead().get("turn");
                TurnType turnType;
                if (stype != null) {
                    turnType = TurnType.fromString(stype.toUpperCase(), leftSide);
                } else {
                    turnType = TurnType.straight();
                }
                // $NON-NLS-1$
                String sturn = item.getExtensionsToRead().get("turn-angle");
                if (sturn != null) {
                    turnType.setTurnAngle((float) Double.parseDouble(sturn));
                }
                RouteDirectionInfo dirInfo = new RouteDirectionInfo(avgSpeed, turnType);
                // $NON-NLS-1$
                dirInfo.setDescriptionRoute(item.desc);
                dirInfo.routePointOffset = offset;
                // Issue #2894
                // $NON-NLS-1$
                String sref = item.getExtensionsToRead().get("ref");
                if (sref != null && !"null".equals(sref)) {
                    // $NON-NLS-1$
                    dirInfo.setRef(sref);
                }
                // $NON-NLS-1$
                String sstreetname = item.getExtensionsToRead().get("street-name");
                if (sstreetname != null && !"null".equals(sstreetname)) {
                    // $NON-NLS-1$
                    dirInfo.setStreetName(sstreetname);
                }
                // $NON-NLS-1$
                String sdest = item.getExtensionsToRead().get("dest");
                if (sdest != null && !"null".equals(sdest)) {
                    // $NON-NLS-1$
                    dirInfo.setDestinationName(sdest);
                }
                if (previous != null && TurnType.C != previous.getTurnType().getValue() && !osmandRouter) {
                    // calculate angle
                    if (previous.routePointOffset > 0) {
                        float paz = res.get(previous.routePointOffset - 1).bearingTo(res.get(previous.routePointOffset));
                        float caz;
                        if (previous.getTurnType().isRoundAbout() && dirInfo.routePointOffset < res.size() - 1) {
                            caz = res.get(dirInfo.routePointOffset).bearingTo(res.get(dirInfo.routePointOffset + 1));
                        } else {
                            caz = res.get(dirInfo.routePointOffset - 1).bearingTo(res.get(dirInfo.routePointOffset));
                        }
                        float angle = caz - paz;
                        if (angle < 0) {
                            angle += 360;
                        } else if (angle > 360) {
                            angle -= 360;
                        }
                        // that magic number helps to fix some errors for turn
                        angle += 75;
                        if (previous.getTurnType().getTurnAngle() < 0.5f) {
                            previous.getTurnType().setTurnAngle(angle);
                        }
                    }
                }
                directions.add(dirInfo);
                previous = dirInfo;
            } catch (NumberFormatException e) {
                // $NON-NLS-1$
                log.info("Exception", e);
            } catch (IllegalArgumentException e) {
                // $NON-NLS-1$
                log.info("Exception", e);
            }
        }
    }
    if (previous != null && TurnType.C != previous.getTurnType().getValue()) {
        // calculate angle
        if (previous.routePointOffset > 0 && previous.routePointOffset < res.size() - 1) {
            float paz = res.get(previous.routePointOffset - 1).bearingTo(res.get(previous.routePointOffset));
            float caz = res.get(previous.routePointOffset).bearingTo(res.get(res.size() - 1));
            float angle = caz - paz;
            if (angle < 0) {
                angle += 360;
            }
            if (previous.getTurnType().getTurnAngle() < 0.5f) {
                previous.getTurnType().setTurnAngle(angle);
            }
        }
    }
    return directions;
}
Also used : WptPt(net.osmand.plus.GPXUtilities.WptPt) TrkSegment(net.osmand.plus.GPXUtilities.TrkSegment) TurnType(net.osmand.router.TurnType) TargetPoint(net.osmand.plus.TargetPointsHelper.TargetPoint) LocationPoint(net.osmand.data.LocationPoint) Track(net.osmand.plus.GPXUtilities.Track) Route(net.osmand.plus.GPXUtilities.Route)

Example 8 with TurnType

use of net.osmand.router.TurnType in project Osmand by osmandapp.

the class NextTurnInfoWidget method updateDistance.

private void updateDistance() {
    int deviatePath = turnDrawable.deviatedFromRoute ? deviatedPath : nextTurnDistance;
    String ds = OsmAndFormatter.getFormattedDistance(deviatePath, app);
    if (ds != null) {
        TurnType turnType = getTurnType();
        RoutingHelper routingHelper = app.getRoutingHelper();
        if ((turnType != null) && (routingHelper != null)) {
            setContentDescription(ds + " " + routingHelper.getRoute().toString(turnType, app, false));
        } else {
            setContentDescription(ds);
        }
    }
    int ls = ds.lastIndexOf(' ');
    if (ls == -1) {
        setTextNoUpdateVisibility(ds, null);
    } else {
        setTextNoUpdateVisibility(ds.substring(0, ls), ds.substring(ls + 1));
    }
}
Also used : RoutingHelper(net.osmand.plus.routing.RoutingHelper) TurnType(net.osmand.router.TurnType) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint)

Example 9 with TurnType

use of net.osmand.router.TurnType in project Osmand by osmandapp.

the class RouteInfoWidgetsFactory method createNextNextInfoControl.

public NextTurnInfoWidget createNextNextInfoControl(final Activity activity, final OsmandApplication app, boolean horisontalMini) {
    final RoutingHelper routingHelper = app.getRoutingHelper();
    final NextTurnInfoWidget nextTurnInfo = new NextTurnInfoWidget(activity, app, horisontalMini) {

        NextDirectionInfo calc1 = new NextDirectionInfo();

        @Override
        public boolean updateInfo(DrawSettings drawSettings) {
            boolean followingMode = routingHelper.isFollowingMode() || app.getLocationProvider().getLocationSimulation().isRouteAnimating();
            TurnType turnType = null;
            boolean deviatedFromRoute = false;
            int turnImminent = 0;
            int nextTurnDistance = 0;
            if (routingHelper != null && routingHelper.isRouteCalculated() && followingMode) {
                deviatedFromRoute = routingHelper.isDeviatedFromRoute();
                NextDirectionInfo r = routingHelper.getNextRouteDirectionInfo(calc1, true);
                if (!deviatedFromRoute) {
                    if (r != null) {
                        r = routingHelper.getNextRouteDirectionInfoAfter(r, calc1, true);
                    }
                }
                if (r != null && r.distanceTo > 0 && r.directionInfo != null) {
                    turnType = r.directionInfo.getTurnType();
                    turnImminent = r.imminent;
                    nextTurnDistance = r.distanceTo;
                }
            }
            setTurnType(turnType);
            setTurnImminent(turnImminent, deviatedFromRoute);
            setTurnDistance(nextTurnDistance);
            return true;
        }
    };
    nextTurnInfo.setOnClickListener(new View.OnClickListener() {

        // int i = 0;
        @Override
        public void onClick(View v) {
        // uncomment to test turn info rendering
        // final int l = TurnType.predefinedTypes.length;
        // final int exits = 5;
        // i++;
        // if (i % (l + exits) >= l ) {
        // nextTurnInfo.turnType = TurnType.valueOf("EXIT" + (i % (l + exits) - l + 1), true);
        // nextTurnInfo.exitOut = (i % (l + exits) - l + 1)+"";
        // float a = 180 - (i % (l + exits) - l + 1) * 50;
        // nextTurnInfo.turnType.setTurnAngle(a < 0 ? a + 360 : a);
        // } else {
        // nextTurnInfo.turnType = TurnType.valueOf(TurnType.predefinedTypes[i % (TurnType.predefinedTypes.length + exits)], true);
        // nextTurnInfo.exitOut = "";
        // }
        // nextTurnInfo.turnImminent = (nextTurnInfo.turnImminent + 1) % 3;
        // nextTurnInfo.nextTurnDirection = 580;
        // TurnPathHelper.calcTurnPath(nextTurnInfo.pathForTurn, nexsweepAngletTurnInfo.turnType,nextTurnInfo.pathTransform);
        // showMiniMap = true;
        }
    });
    // initial state
    return nextTurnInfo;
}
Also used : NextDirectionInfo(net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo) RoutingHelper(net.osmand.plus.routing.RoutingHelper) TurnType(net.osmand.router.TurnType) ImageView(android.widget.ImageView) View(android.view.View) TextView(android.widget.TextView) OsmandMapTileView(net.osmand.plus.views.OsmandMapTileView) TargetPoint(net.osmand.plus.TargetPointsHelper.TargetPoint) Paint(android.graphics.Paint) DrawSettings(net.osmand.plus.views.OsmandMapLayer.DrawSettings)

Aggregations

TurnType (net.osmand.router.TurnType)9 TargetPoint (net.osmand.plus.TargetPointsHelper.TargetPoint)4 RoutingHelper (net.osmand.plus.routing.RoutingHelper)4 Paint (android.graphics.Paint)3 LocationPoint (net.osmand.data.LocationPoint)3 NextDirectionInfo (net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo)3 View (android.view.View)2 ImageView (android.widget.ImageView)2 TextView (android.widget.TextView)2 ArrayList (java.util.ArrayList)2 Location (net.osmand.Location)2 RouteDirectionInfo (net.osmand.plus.routing.RouteDirectionInfo)2 DrawSettings (net.osmand.plus.views.OsmandMapLayer.DrawSettings)2 OsmandMapTileView (net.osmand.plus.views.OsmandMapTileView)2 PendingIntent (android.app.PendingIntent)1 Intent (android.content.Intent)1 BigTextStyle (android.support.v4.app.NotificationCompat.BigTextStyle)1 Builder (android.support.v4.app.NotificationCompat.Builder)1 TextPaint (android.text.TextPaint)1 Date (java.util.Date)1