예제 #1
0
 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;
 }
예제 #2
0
  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;
    }
  }
예제 #3
0
 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;
   }
 }
예제 #4
0
 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;
 }
예제 #5
0
 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;
 }
예제 #6
0
 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);
           }
         }
       }
     }
   }
 }
예제 #7
0
  /**
   * 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);
    }
  }