public synchronized String getCurrentName() { NextDirectionInfo n = getNextRouteDirectionInfo(new NextDirectionInfo(), false); Location l = lastFixedLocation; float speed = 0; if (l != null && l.hasSpeed()) { speed = l.getSpeed(); } if (n.distanceTo > 0 && n.directionInfo != null && !n.directionInfo.getTurnType().isSkipToSpeak() && voiceRouter.isDistanceLess(speed, n.distanceTo, voiceRouter.PREPARE_DISTANCE * 0.75f)) { String nm = n.directionInfo.getStreetName(); String rf = n.directionInfo.getRef(); String dn = n.directionInfo.getDestinationName(); return "\u2566 " + formatStreetName(nm, rf, dn); } RouteSegmentResult rs = getCurrentSegmentResult(); if (rs != null) { String nm = rs.getObject().getName(); String rf = rs.getObject().getRef(); String dn = rs.getObject().getDestinationName(); return "\u21E7 " + formatStreetName(nm, rf, dn); } return null; }
public void announceCurrentDirection(Location currentLocation) { NextDirectionInfo nextInfo = router.getNextRouteDirectionInfo(new NextDirectionInfo(), true); if (nextInfo == null) { playGoAheadToDestination(); return; } NextDirectionInfo nextNextInfo = router.getNextRouteDirectionInfoAfter(nextInfo, new NextDirectionInfo(), false); float speed = DEFAULT_SPEED; RouteDirectionInfo next = nextInfo.directionInfo; int dist = nextInfo.distanceTo; if (currentLocation != null && currentLocation.hasSpeed()) { speed = Math.max(currentLocation.getSpeed(), speed); } switch (currentStatus) { case STATUS_UTWP_TOLD: playMakeUTwp(); break; case STATUS_UNKNOWN: if (nextRouteDirection != null && ((next == null) || (next.distance == 0))) { playGoAheadToDestination(); } else { playGoAhead(dist); } break; case STATUS_TOLD: if (nextRouteDirection != null) { playGoAheadToDestination(); } break; case STATUS_TURN: if (next.distance < TURN_IN_DISTANCE_END && nextNextInfo != null) { playMakeTurn(next, nextNextInfo.directionInfo); } else { playMakeTurn(next, null); } break; case STATUS_TURN_IN: if ((isDistanceLess(speed, next.distance, TURN_DISTANCE) || next.distance < TURN_IN_DISTANCE_END) && nextNextInfo != null) { playMakeTurnIn(next, dist, nextNextInfo.directionInfo); } else { playMakeTurnIn(next, dist, null); } break; case STATUS_PREPARE: playPrepareTurn(next, dist); break; case STATUS_LONG_PREPARE: playPrepareTurn(next, dist); break; default: break; } }
public int calculateImminent(float dist, Location loc) { float speed = DEFAULT_SPEED; if (loc != null && loc.hasSpeed()) { speed = loc.getSpeed(); } if (isDistanceLess(speed, dist, TURN_IN_DISTANCE_END)) { return 0; } else if (dist <= PREPARE_DISTANCE) { return 1; } else if (dist <= PREPARE_LONG_DISTANCE) { return 2; } else { return -1; } }
private static AlarmInfo createSpeedAlarm( MetricsConstants mc, float mxspeed, Location loc, float delta) { AlarmInfo speedAlarm = null; if (mxspeed != 0 && loc != null && loc.hasSpeed() && mxspeed != RouteDataObject.NONE_MAX_SPEED) { if (loc.getSpeed() > mxspeed + delta) { int speed; if (mc == MetricsConstants.KILOMETERS_AND_METERS) { speed = Math.round(mxspeed * 3.6f); } else { speed = Math.round(mxspeed * 3.6f / 1.6f); } speedAlarm = AlarmInfo.createSpeedLimit(speed, loc); } } return speedAlarm; }
public AlarmInfo getMostImportantAlarm(MetricsConstants mc, boolean showCameras) { Location lastProjection = app.getRoutingHelper().getLastProjection(); float mxspeed = route.getCurrentMaxSpeed(); float delta = app.getSettings().SPEED_LIMIT_EXCEED.get() / 3.6f; AlarmInfo speedAlarm = createSpeedAlarm(mc, mxspeed, lastProjection, delta); if (speedAlarm != null) { getVoiceRouter().announceSpeedAlarm(); } AlarmInfo mostImportant = speedAlarm; int value = speedAlarm != null ? speedAlarm.updateDistanceAndGetPriority(0, 0) : Integer.MAX_VALUE; if (ALARMS < pointsProgress.size()) { int kIterator = pointsProgress.get(ALARMS); List<LocationPointWrapper> lp = locationPoints.get(ALARMS); while (kIterator < lp.size()) { LocationPointWrapper lwp = lp.get(kIterator); if (lp.get(kIterator).routeIndex < route.getCurrentRoute()) { // skip } else { int d = route.getDistanceToPoint(lwp.routeIndex); if (d > LONG_ANNOUNCE_RADIUS) { break; } AlarmInfo inf = (AlarmInfo) lwp.point; float speed = lastProjection != null && lastProjection.hasSpeed() ? lastProjection.getSpeed() : 0; float time = speed > 0 ? d / speed : Integer.MAX_VALUE; int vl = inf.updateDistanceAndGetPriority(time, d); if (vl < value && (showCameras || inf.getType() != AlarmInfoType.SPEED_CAMERA)) { mostImportant = inf; value = vl; } } kIterator++; } } return mostImportant; }
public void announceVisibleLocations() { Location lastKnownLocation = app.getRoutingHelper().getLastProjection(); if (lastKnownLocation != null && app.getRoutingHelper().isFollowingMode()) { for (int type = 0; type < locationPoints.size(); type++) { int currentRoute = route.getCurrentRoute(); List<LocationPointWrapper> approachPoints = new ArrayList<LocationPointWrapper>(); List<LocationPointWrapper> announcePoints = new ArrayList<LocationPointWrapper>(); List<LocationPointWrapper> lp = locationPoints.get(type); if (lp != null) { int kIterator = pointsProgress.get(type); while (kIterator < lp.size() && lp.get(kIterator).routeIndex < currentRoute) { kIterator++; } pointsProgress.set(type, kIterator); while (kIterator < lp.size()) { LocationPointWrapper lwp = lp.get(kIterator); if (route.getDistanceToPoint(lwp.routeIndex) > LONG_ANNOUNCE_RADIUS * 2) { break; } LocationPoint point = lwp.point; double d1 = Math.max( 0.0, MapUtils.getDistance( lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude(), point.getLatitude(), point.getLongitude()) - lwp.getDeviationDistance()); Integer state = locationPointsStates.get(point); if (state != null && state.intValue() == ANNOUNCED_ONCE && getVoiceRouter() .isDistanceLess(lastKnownLocation.getSpeed(), d1, SHORT_ANNOUNCE_RADIUS, 0f)) { locationPointsStates.put(point, ANNOUNCED_DONE); announcePoints.add(lwp); } else if (type != ALARMS && (state == null || state == NOT_ANNOUNCED) && getVoiceRouter() .isDistanceLess(lastKnownLocation.getSpeed(), d1, LONG_ANNOUNCE_RADIUS, 0f)) { locationPointsStates.put(point, ANNOUNCED_ONCE); approachPoints.add(lwp); } else if (type == ALARMS && (state == null || state == NOT_ANNOUNCED) && getVoiceRouter() .isDistanceLess(lastKnownLocation.getSpeed(), d1, ALARMS_ANNOUNCE_RADIUS, 0f)) { locationPointsStates.put(point, ANNOUNCED_ONCE); approachPoints.add(lwp); } kIterator++; } if (!announcePoints.isEmpty()) { if (announcePoints.size() > ANNOUNCE_POI_LIMIT) { announcePoints = announcePoints.subList(0, ANNOUNCE_POI_LIMIT); } if (type == WAYPOINTS) { getVoiceRouter().announceWaypoint(announcePoints); } else if (type == POI) { getVoiceRouter().announcePoi(announcePoints); } else if (type == ALARMS) { // nothing to announce } else if (type == FAVORITES) { getVoiceRouter().announceFavorite(announcePoints); } } if (!approachPoints.isEmpty()) { if (approachPoints.size() > APPROACH_POI_LIMIT) { approachPoints = approachPoints.subList(0, APPROACH_POI_LIMIT); } if (type == WAYPOINTS) { getVoiceRouter().approachWaypoint(lastKnownLocation, approachPoints); } else if (type == POI) { getVoiceRouter().approachPoi(lastKnownLocation, approachPoints); } else if (type == ALARMS) { EnumSet<AlarmInfoType> ait = EnumSet.noneOf(AlarmInfoType.class); for (LocationPointWrapper pw : approachPoints) { ait.add(((AlarmInfo) pw.point).getType()); } for (AlarmInfoType t : ait) { app.getRoutingHelper().getVoiceRouter().announceAlarm(t); } } else if (type == FAVORITES) { getVoiceRouter().approachFavorite(lastKnownLocation, approachPoints); } } } } } }
/** * Updates status of voice guidance * * @param currentLocation */ protected void updateStatus(Location currentLocation) { // Directly after turn: goAhead (dist), unless: // < PREPARE_LONG_DISTANCE (3000m): playPrepareTurn // < PREPARE_DISTANCE (1500m): playPrepareTurn // < TURN_IN_DISTANCE (300m or 25sec): playMakeTurnIn // < TURN_DISTANCE (60m or 5sec): playMakeTurn float speed = DEFAULT_SPEED; if (currentLocation != null && currentLocation.hasSpeed()) { speed = Math.max(currentLocation.getSpeed(), speed); } NextDirectionInfo nextInfo = router.getNextRouteDirectionInfo(new NextDirectionInfo(), true); // after last turn say: if (nextInfo == null || nextInfo.directionInfo == null || nextInfo.directionInfo.distance == 0) { // if(currentStatus <= STATUS_UNKNOWN && currentDirection > 0){ This caused this prompt to be // suppressed when coming back from a if (currentStatus <= STATUS_UNKNOWN) { if (playGoAheadToDestination()) { currentStatus = STATUS_TOLD; playGoAheadDist = 0; } } return; } if (nextInfo.intermediatePoint) { if (currentStatus <= STATUS_UNKNOWN) { if (playGoAheadToIntermediate()) { currentStatus = STATUS_TOLD; playGoAheadDist = 0; } } return; } int dist = nextInfo.distanceTo; RouteDirectionInfo next = nextInfo.directionInfo; // if routing is changed update status to unknown if (next != nextRouteDirection) { nextRouteDirection = next; currentStatus = STATUS_UNKNOWN; playGoAheadDist = 0; } if (dist == 0 || currentStatus == STATUS_TOLD) { // nothing said possibly that's wrong case we should say before that // however it should be checked manually ? return; } // say how much to go if there is next turn is a bit far if (currentStatus == STATUS_UNKNOWN) { if (!isDistanceLess(speed, dist, TURN_IN_DISTANCE * 1.3)) { playGoAheadDist = dist - 80; } // say long distance message only for long distances > 10 km // if (dist >= PREPARE_LONG_DISTANCE && !isDistanceLess(speed, dist, PREPARE_LONG_DISTANCE)) { if (dist > PREPARE_LONG_DISTANCE + 300) { nextStatusAfter(STATUS_UNKNOWN); } else if (dist > PREPARE_DISTANCE + 300) { // say prepare message if it is far enough and don't say preare long distance nextStatusAfter(STATUS_LONG_PREPARE); } else { // don't say even prepare message nextStatusAfter(STATUS_PREPARE); } } NextDirectionInfo nextNextInfo = router.getNextRouteDirectionInfoAfter(nextInfo, new NextDirectionInfo(), true); if (statusNotPassed(STATUS_TURN) && isDistanceLess(speed, dist, TURN_DISTANCE, TURN_DEFAULT_SPEED)) { if (next.distance < TURN_IN_DISTANCE_END && nextNextInfo != null) { playMakeTurn(next, nextNextInfo.directionInfo); } else { playMakeTurn(next, null); } nextStatusAfter(STATUS_TURN); } else if (statusNotPassed(STATUS_TURN_IN) && isDistanceLess(speed, dist, TURN_IN_DISTANCE)) { if (dist >= TURN_IN_DISTANCE_END) { if ((isDistanceLess(speed, next.distance, TURN_DISTANCE) || next.distance < TURN_IN_DISTANCE_END) && nextNextInfo != null) { playMakeTurnIn(next, dist, nextNextInfo.directionInfo); } else { playMakeTurnIn(next, dist, null); } } nextStatusAfter(STATUS_TURN_IN); // } else if (statusNotPassed(STATUS_PREPARE) && isDistanceLess(speed, dist, // PREPARE_DISTANCE)) { } else if (statusNotPassed(STATUS_PREPARE) && (dist <= PREPARE_DISTANCE)) { if (dist >= PREPARE_DISTANCE_END) { if (next.getTurnType().keepLeft() || next.getTurnType().keepRight()) { // do not play prepare for keep left/right } else { playPrepareTurn(next, dist); } } nextStatusAfter(STATUS_PREPARE); // } else if (statusNotPassed(STATUS_LONG_PREPARE) && isDistanceLess(speed, dist, // PREPARE_LONG_DISTANCE)){ } else if (statusNotPassed(STATUS_LONG_PREPARE) && (dist <= PREPARE_LONG_DISTANCE)) { if (dist >= PREPARE_LONG_DISTANCE_END) { playPrepareTurn(next, dist); } nextStatusAfter(STATUS_LONG_PREPARE); } else if (statusNotPassed(STATUS_UNKNOWN)) { // strange how we get here but nextStatusAfter(STATUS_UNKNOWN); } else if (statusNotPassed(STATUS_TURN_IN) && dist < playGoAheadDist) { playGoAheadDist = 0; playGoAhead(dist); } }