Exemple #1
0
 public boolean identifyUTurnIsNeeded(Location currentLocation, float posTolerance) {
   if (finalLocation == null || currentLocation == null || !route.isCalculated()) {
     this.makeUturnWhenPossible = false;
     return makeUturnWhenPossible;
   }
   boolean makeUturnWhenPossible = false;
   if (currentLocation.hasBearing()) {
     float bearingMotion = currentLocation.getBearing();
     Location nextRoutePosition = route.getNextRouteLocation();
     float bearingToRoute = currentLocation.bearingTo(nextRoutePosition);
     double diff = MapUtils.degreesDiff(bearingMotion, bearingToRoute);
     // 7. Check if you left the route and an unscheduled U-turn would bring you back (also Issue
     // 863)
     // This prompt is an interim advice and does only sound if a new route in forward direction
     // could not be found in x seconds
     if (Math.abs(diff) > 135f) {
       float d = currentLocation.distanceTo(nextRoutePosition);
       // 60m tolerance to allow for GPS inaccuracy
       if (d > posTolerance) {
         // require x sec continuous since first detection
         if (makeUTwpDetected == 0) {
           makeUTwpDetected = System.currentTimeMillis();
         } else if ((System.currentTimeMillis() - makeUTwpDetected > 10000)) {
           makeUturnWhenPossible = true;
           // log.info("bearingMotion is opposite to bearingRoute"); //$NON-NLS-1$
         }
       }
     } else {
       makeUTwpDetected = 0;
     }
   }
   this.makeUturnWhenPossible = makeUturnWhenPossible;
   return makeUturnWhenPossible;
 }
Exemple #2
0
 public synchronized AlarmInfo getMostImportantAlarm(MetricsConstants mc, boolean showCameras) {
   float mxspeed = route.getCurrentMaxSpeed();
   AlarmInfo speedAlarm = createSpeedAlarm(mc, mxspeed, lastProjection);
   AlarmInfo alarm = route.getMostImportantAlarm(lastProjection, speedAlarm, showCameras);
   if (alarm != null) {
     voiceRouter.announceAlarm(alarm);
   }
   return alarm;
 }
Exemple #3
0
    @Override
    public void run() {

      RouteCalculationResult res = provider.calculateRouteImpl(params);
      if (params.calculationProgress.isCancelled) {
        currentRunningJob = null;
        return;
      }
      final boolean onlineSourceWithoutInternet =
          !res.isCalculated()
              && params.type.isOnline()
              && !settings.isInternetConnectionAvailable();
      if (onlineSourceWithoutInternet && settings.GPX_ROUTE_CALC_OSMAND_PARTS.get()) {
        if (params.previousToRecalculate != null && params.previousToRecalculate.isCalculated()) {
          res = provider.recalculatePartOfflineRoute(res, params);
        }
      }

      synchronized (RoutingHelper.this) {
        if (res.isCalculated()) {
          setNewRoute(res, params.start);
        } else {
          evalWaitInterval = evalWaitInterval * 3 / 2;
          evalWaitInterval = Math.min(evalWaitInterval, 120000);
        }
        currentRunningJob = null;
      }

      if (res.isCalculated()) {
        String msg =
            app.getString(R.string.new_route_calculated_dist)
                + ": "
                + OsmAndFormatter.getFormattedDistance(res.getWholeDistance(), app);
        if (res.getRoutingTime() != 0f) {
          msg += " (" + Algorithms.formatDuration((int) res.getRoutingTime()) + ")";
        }
        showMessage(msg);
      } else if (onlineSourceWithoutInternet) {
        showMessage(
            app.getString(R.string.error_calculating_route)
                + ":\n"
                + app.getString(
                    R.string.internet_connection_required_for_online_route)); // $NON-NLS-1$
      } else {
        if (res.getErrorMessage() != null) {
          showMessage(
              app.getString(R.string.error_calculating_route)
                  + ":\n"
                  + res.getErrorMessage()); // $NON-NLS-1$
        } else {
          showMessage(app.getString(R.string.empty_route_calculated));
        }
      }
      lastTimeEvaluatedRoute = System.currentTimeMillis();
    }
Exemple #4
0
 public synchronized NextDirectionInfo getNextRouteDirectionInfo(
     NextDirectionInfo info, boolean toSpeak) {
   NextDirectionInfo i = route.getNextRouteDirectionInfo(info, lastProjection, toSpeak);
   if (i != null) {
     i.imminent = voiceRouter.calculateImminent(i.distanceTo, lastProjection);
   }
   return i;
 }
Exemple #5
0
 public synchronized NextDirectionInfo getNextRouteDirectionInfoAfter(
     NextDirectionInfo previous, NextDirectionInfo to, boolean toSpeak) {
   NextDirectionInfo i = route.getNextRouteDirectionInfoAfter(previous, to, toSpeak);
   if (i != null) {
     i.imminent = voiceRouter.calculateImminent(i.distanceTo, null);
   }
   return i;
 }
Exemple #6
0
 private void announceGpxWaypoints(Location currentLocation) {
   if (currentLocation != null) {
     List<WptPt> wpt = route.getWaypointsToAnnounce(currentLocation);
     if (wpt.size() > 0) {
       String s = "";
       for (WptPt w : wpt) {
         if (!Algorithms.isEmpty(w.name)) {
           s = w.name + ",";
         }
       }
       if (!Algorithms.isEmpty(s)) {
         voiceRouter.announceWaypoint(s);
       }
     }
   }
 }
Exemple #7
0
  private synchronized void setNewRoute(RouteCalculationResult res, Location start) {
    final boolean newRoute = !this.route.isCalculated();
    route = res;
    if (isFollowingMode) {
      if (lastFixedLocation != null) {
        start = lastFixedLocation;
      }
      // try remove false route-recalculated prompts by checking direction to second route node
      boolean wrongMovementDirection = false;
      List<Location> routeNodes = res.getImmutableAllLocations();
      if (routeNodes != null && !routeNodes.isEmpty()) {
        int newCurrentRoute =
            lookAheadFindMinOrthogonalDistance(start, routeNodes, res.currentRoute, 15);
        if (newCurrentRoute + 1 < routeNodes.size()) {
          // This check is valid for Online/GPX services (offline routing is aware of route
          // direction)
          wrongMovementDirection =
              checkWrongMovementDirection(start, routeNodes.get(newCurrentRoute + 1));
          // set/reset evalWaitInterval only if new route is in forward direction
          if (!wrongMovementDirection) {
            evalWaitInterval = 3000;
          } else {
            evalWaitInterval = evalWaitInterval * 3 / 2;
            evalWaitInterval = Math.min(evalWaitInterval, 120000);
          }
        }
      }

      // trigger voice prompt only if new route is in forward direction
      // If route is in wrong direction after one more setLocation it will be recalculated
      if (!wrongMovementDirection || newRoute) {
        voiceRouter.newRouteIsCalculated(newRoute);
      }
    }

    app.runInUIThread(
        new Runnable() {
          @Override
          public void run() {
            for (IRouteInformationListener l : listeners) {
              l.newRouteIsCalculated(newRoute);
            }
          }
        });
  }
Exemple #8
0
 public List<RouteSegmentResult> getUpcomingTunnel(float distToStart) {
   return route.getUpcomingTunnel(distToStart);
 }
Exemple #9
0
 public RouteSegmentResult getCurrentSegmentResult() {
   return route.getCurrentSegmentResult();
 }
Exemple #10
0
 public synchronized float getCurrentMaxSpeed() {
   return route.getCurrentMaxSpeed();
 }
Exemple #11
0
 public boolean isRouteCalculated() {
   return route.isCalculated();
 }
Exemple #12
0
 public synchronized int getLeftDistanceNextIntermediate() {
   return route.getDistanceToNextIntermediate(lastFixedLocation);
 }
Exemple #13
0
 public synchronized int getLeftDistance() {
   return route.getDistanceToFinish(lastFixedLocation);
 }
Exemple #14
0
  private boolean updateCurrentRouteStatus(Location currentLocation, float posTolerance) {
    List<Location> routeNodes = route.getImmutableAllLocations();
    int currentRoute = route.currentRoute;
    // 1. Try to proceed to next point using orthogonal distance (finding minimum orthogonal dist)
    while (currentRoute + 1 < routeNodes.size()) {
      double dist = currentLocation.distanceTo(routeNodes.get(currentRoute));
      if (currentRoute > 0) {
        dist =
            getOrthogonalDistance(
                currentLocation, routeNodes.get(currentRoute - 1), routeNodes.get(currentRoute));
      }
      boolean processed = false;
      // if we are still too far try to proceed many points
      // if not then look ahead only 3 in order to catch sharp turns
      boolean longDistance = dist >= 250;
      int newCurrentRoute =
          lookAheadFindMinOrthogonalDistance(
              currentLocation, routeNodes, currentRoute, longDistance ? 15 : 8);
      double newDist =
          getOrthogonalDistance(
              currentLocation,
              routeNodes.get(newCurrentRoute),
              routeNodes.get(newCurrentRoute + 1));
      if (longDistance) {
        if (newDist < dist) {
          if (log.isDebugEnabled()) {
            log.debug(
                "Processed by distance : (new) "
                    + newDist
                    + " (old) "
                    + dist); //$NON-NLS-1$//$NON-NLS-2$
          }
          processed = true;
        }
      } else if (newDist < dist || newDist < 10) {
        // newDist < 10 (avoid distance 0 till next turn)
        if (dist > posTolerance) {
          processed = true;
          if (log.isDebugEnabled()) {
            log.debug(
                "Processed by distance : " + newDist + " " + dist); // $NON-NLS-1$//$NON-NLS-2$
          }
        } else {
          // case if you are getting close to the next point after turn
          // but you have not yet turned (could be checked bearing)
          if (currentLocation.hasBearing() || lastFixedLocation != null) {
            float bearingToRoute = currentLocation.bearingTo(routeNodes.get(currentRoute));
            float bearingRouteNext =
                routeNodes.get(newCurrentRoute).bearingTo(routeNodes.get(newCurrentRoute + 1));
            float bearingMotion =
                currentLocation.hasBearing()
                    ? currentLocation.getBearing()
                    : lastFixedLocation.bearingTo(currentLocation);
            double diff = Math.abs(MapUtils.degreesDiff(bearingMotion, bearingToRoute));
            double diffToNext = Math.abs(MapUtils.degreesDiff(bearingMotion, bearingRouteNext));
            if (diff > diffToNext) {
              if (log.isDebugEnabled()) {
                log.debug("Processed point bearing deltas : " + diff + " " + diffToNext);
              }
              processed = true;
            }
          }
        }
      }
      if (processed) {
        // that node already passed
        route.updateCurrentRoute(newCurrentRoute + 1);
        currentRoute = newCurrentRoute + 1;
      } else {
        break;
      }
    }

    // 2. check if intermediate found
    if (route.getIntermediatePointsToPass() > 0
        && route.getDistanceToNextIntermediate(lastFixedLocation) < POSITION_TOLERANCE * 2) {
      showMessage(app.getString(R.string.arrived_at_intermediate_point));
      route.passIntermediatePoint();

      TargetPointsHelper targets = app.getTargetPointsHelper();
      List<String> ns = targets.getIntermediatePointNames();
      int toDel = targets.getIntermediatePoints().size() - route.getIntermediatePointsToPass();
      int currentIndex = toDel - 1;
      String name =
          currentIndex < 0 || currentIndex >= ns.size() || ns.get(currentIndex) == null
              ? ""
              : ns.get(currentIndex);
      if (isFollowingMode) {
        voiceRouter.arrivedIntermediatePoint(name);
      }
      while (toDel > 0) {
        targets.removeWayPoint(false, 0);
        toDel--;
      }

      while (intermediatePoints != null
          && route.getIntermediatePointsToPass() < intermediatePoints.size()) {
        intermediatePoints.remove(0);
      }
    }

    // 3. check if destination found
    Location lastPoint = routeNodes.get(routeNodes.size() - 1);
    if (currentRoute > routeNodes.size() - 3
        && currentLocation.distanceTo(lastPoint)
            < (((float) settings.getApplicationMode().getArrivalDistance())
                * settings.ARRIVAL_DISTANCE_FACTOR.get())) {
      showMessage(app.getString(R.string.arrived_at_destination));
      TargetPointsHelper targets = app.getTargetPointsHelper();
      String description = targets.getPointNavigateDescription();
      if (isFollowingMode) {
        voiceRouter.arrivedDestinationPoint(description);
      }
      if (OsmandPlugin.onDestinationReached()) {
        clearCurrentRoute(null, null);
        setRoutePlanningMode(false);
        app.runInUIThread(
            new Runnable() {
              @Override
              public void run() {
                settings.APPLICATION_MODE.set(settings.DEFAULT_APPLICATION_MODE.get());
              }
            });
        // targets.clearPointToNavigate(false);
        return true;
      }
    }
    return false;
  }
Exemple #15
0
  private Location setCurrentLocation(
      Location currentLocation,
      boolean returnUpdatedLocation,
      RouteCalculationResult previousRoute) {
    Location locationProjection = currentLocation;
    if (finalLocation == null || currentLocation == null) {
      makeUturnWhenPossible = false;
      return locationProjection;
    }
    float posTolerance = POSITION_TOLERANCE;
    if (currentLocation.hasAccuracy()) {
      posTolerance = POSITION_TOLERANCE / 2 + currentLocation.getAccuracy();
    }
    boolean calculateRoute = false;
    synchronized (this) {
      // 0. Route empty or needs to be extended? Then re-calculate route.
      if (route.isEmpty()) {
        calculateRoute = true;
      } else {
        // 1. Update current route position status according to latest received location
        boolean finished = updateCurrentRouteStatus(currentLocation, posTolerance);
        if (finished) {
          return null;
        }
        List<Location> routeNodes = route.getImmutableAllLocations();
        int currentRoute = route.currentRoute;

        // 2. Analyze if we need to recalculate route
        // >100m off current route (sideways)
        if (currentRoute > 0) {
          double dist =
              getOrthogonalDistance(
                  currentLocation, routeNodes.get(currentRoute - 1), routeNodes.get(currentRoute));
          if (dist > 1.7 * posTolerance) {
            log.info("Recalculate route, because correlation  : " + dist); // $NON-NLS-1$
            calculateRoute = true;
          }
          if (dist > 350) {
            voiceRouter.announceOffRoute(dist);
          }
        }
        // 3. Identify wrong movement direction
        Location next = route.getNextRouteLocation();
        boolean wrongMovementDirection = checkWrongMovementDirection(currentLocation, next);
        if (wrongMovementDirection
            && currentLocation.distanceTo(routeNodes.get(currentRoute)) > 2 * posTolerance) {
          log.info(
              "Recalculate route, because wrong movement direction: "
                  + currentLocation.distanceTo(routeNodes.get(currentRoute))); // $NON-NLS-1$
          calculateRoute = true;
        }
        // 4. Identify if UTurn is needed
        boolean uTurnIsNeeded = identifyUTurnIsNeeded(currentLocation, posTolerance);
        // 5. Update Voice router
        if (isFollowingMode) {
          // don't update in route planing mode
          announceGpxWaypoints(currentLocation);
          boolean inRecalc = calculateRoute || isRouteBeingCalculated();
          if (!inRecalc && !uTurnIsNeeded && !wrongMovementDirection) {
            voiceRouter.updateStatus(currentLocation, false);
          } else if (uTurnIsNeeded) {
            voiceRouter.makeUTStatus();
          }
        }

        // calculate projection of current location
        if (currentRoute > 0) {
          locationProjection = new Location(currentLocation);
          Location nextLocation = routeNodes.get(currentRoute);
          LatLon project =
              getProject(
                  currentLocation, routeNodes.get(currentRoute - 1), routeNodes.get(currentRoute));

          locationProjection.setLatitude(project.getLatitude());
          locationProjection.setLongitude(project.getLongitude());
          // we need to update bearing too
          float bearingTo = locationProjection.bearingTo(nextLocation);
          locationProjection.setBearing(bearingTo);
        }
      }
      lastFixedLocation = currentLocation;
      lastProjection = locationProjection;
    }

    if (calculateRoute) {
      recalculateRouteInBackground(
          false,
          currentLocation,
          finalLocation,
          intermediatePoints,
          currentGPXRoute,
          previousRoute.isCalculated() ? previousRoute : null);
    } else if (currentRunningJob != null && currentRunningJob instanceof RouteRecalculationThread) {
      RouteRecalculationThread thread = (RouteRecalculationThread) currentRunningJob;
      thread.stopCalculation();
    }

    double projectDist = mode != null && mode.hasFastSpeed() ? posTolerance : posTolerance / 2;
    if (returnUpdatedLocation
        && locationProjection != null
        && currentLocation.distanceTo(locationProjection) < projectDist) {
      return locationProjection;
    } else {
      return currentLocation;
    }
  }
Exemple #16
0
 public synchronized int getLeftTime() {
   return route.getLeftTime(lastFixedLocation);
 }
Exemple #17
0
 public List<RouteDirectionInfo> getRouteDirections() {
   return route.getRouteDirections();
 }
Exemple #18
0
 public Location getLocationFromRouteDirection(RouteDirectionInfo i) {
   return route.getLocationFromRouteDirection(i);
 }
Exemple #19
0
 public void notifyIfRouteIsCalculated() {
   if (route.isCalculated()) {
     voiceRouter.newRouteIsCalculated(true);
   }
 }
Exemple #20
0
 public List<Location> getCurrentCalculatedRoute() {
   return route.getImmutableAllLocations();
 }