/** * Makes a new empty leg from a starting edge * * @param itinerary */ private Leg makeLeg(Itinerary itinerary, State s) { Leg leg = new Leg(); itinerary.addLeg(leg); leg.startTime = makeCalendar(s.getBackState()); EdgeNarrative en = s.getBackEdgeNarrative(); leg.distance = 0.0; leg.from = makePlace(s.getBackState(), false); leg.mode = en.getMode().toString(); return leg; }
private void finalizeLeg( Leg leg, State state, List<State> states, int start, int end, CoordinateArrayListSequence coordinates) { if (start != -1) { leg.walkSteps = getWalkSteps(states.subList(start, end + 1)); } leg.endTime = makeCalendar(state.getBackState()); Geometry geometry = GeometryUtils.getGeometryFactory().createLineString(coordinates); leg.legGeometry = PolylineEncoder.createEncodings(geometry); leg.to = makePlace(state, true); coordinates.clear(); }
private Set<Alert> addNotesToLeg(Leg leg, Set<Alert> notes) { if (notes != null) { for (Alert note : notes) { leg.addAlert(note); } } return notes; }
private Set<Alert> addNotesToLeg(Leg leg, EdgeNarrative edgeNarrative) { Set<Alert> notes = edgeNarrative.getNotes(); if (notes != null) { for (Alert note : notes) { leg.addAlert(note); } } return notes; }
private void finalizeLeg( Leg leg, State state, List<State> states, int start, int end, CoordinateArrayListSequence coordinates, Itinerary itinerary) { // this leg has already been added to the itinerary, so we actually want the penultimate leg, if // any if (states != null) { int extra = 0; WalkStep continuation = null; if (itinerary.legs.size() >= 2) { Leg previousLeg = itinerary.legs.get(itinerary.legs.size() - 2); if (previousLeg.walkSteps != null) { continuation = previousLeg.walkSteps.get(previousLeg.walkSteps.size() - 1); extra = 1; } } if (end == states.size() - 1) { extra = 1; } leg.walkSteps = getWalkSteps(states.subList(start, end + extra), continuation); } leg.endTime = makeCalendar(state.getBackState()); Geometry geometry = GeometryUtils.getGeometryFactory().createLineString(coordinates); leg.legGeometry = PolylineEncoder.createEncodings(geometry); Edge backEdge = state.getBackEdge(); String name; if (backEdge instanceof StreetEdge) { name = backEdge.getName(); } else { name = state.getVertex().getName(); } leg.to = makePlace(state, name, true); coordinates.clear(); }
/** * Makes a new empty leg from a starting edge * * @param itinerary */ private Leg makeLeg(Itinerary itinerary, State s) { Leg leg = new Leg(); itinerary.addLeg(leg); leg.startTime = makeCalendar(s.getBackState()); leg.distance = 0.0; String name; Edge backEdge = s.getBackEdge(); if (backEdge instanceof StreetEdge) { name = backEdge.getName(); } else { name = s.getVertex().getName(); } leg.from = makePlace(s.getBackState(), name, false); leg.mode = s.getBackMode().toString(); if (s.isBikeRenting()) { leg.rentedBike = true; } return leg; }
private Direction decryptNonTransit(Leg leg) { Direction direction = new Direction(); // // http://opentripplanner.usf.edu/opentripplanner-api-webapp/ws/plan?optimize=QUICK&time=09:24pm&arriveBy=false&wheelchair=false&maxWalkDistance=7600.0&fromPlace=28.033389%2C+-82.521034&toPlace=28.064709%2C+-82.471618&date=03/07/12&mode=WALK,TRAM,SUBWAY,RAIL,BUS,FERRY,CABLE_CAR,GONDOLA,FUNICULAR,TRANSIT,TRAINISH,BUSISH // Get appropriate action and icon String action = "Walk"; int icon = R.drawable.mode_walk; TraverseMode mode = TraverseMode.valueOf((String) leg.mode); if (mode.compareTo(TraverseMode.BICYCLE) == 0) { action = "Bike"; icon = R.drawable.mode_bicycle; } else if (mode.compareTo(TraverseMode.CAR) == 0) { action = "Drive"; icon = R.drawable.icon; } direction.setIcon(icon); // Main direction Place fromPlace = leg.from; Place toPlace = leg.to; String mainDirectionText = action; mainDirectionText += fromPlace.name == null ? "" : " from " + fromPlace.name; mainDirectionText += toPlace.name == null ? "" : " to " + toPlace.name; mainDirectionText += toPlace.stopId == null ? "" : " (" + toPlace.stopId.getAgencyId() + " " + toPlace.stopId.getId() + ")"; // double duration = DateTimeConversion.getDuration(leg.startTime, leg.endTime); double totalDistance = leg.distance; DecimalFormat twoDForm = new DecimalFormat("#.##"); totalDistance = Double.valueOf(twoDForm.format(totalDistance)); mainDirectionText += "\n[" + totalDistance + "meters ]"; // Double.toString(duration); direction.setDirectionText(mainDirectionText); // Sub-direction List<WalkStep> walkSteps = leg.getSteps(); if (walkSteps == null) return direction; ArrayList<Direction> subDirections = new ArrayList<Direction>(walkSteps.size()); for (WalkStep step : walkSteps) { Direction dir = new Direction(); String subDirectionText = ""; double distance = step.distance; // Distance traveled [distance] distance = Double.valueOf(twoDForm.format(distance)); dir.setDistanceTraveled(distance); RelativeDirection relativeDir = step.relativeDirection; String streetName = step.streetName; AbsoluteDirection absoluteDir = step.absoluteDirection; String exit = step.exit; boolean isStayOn = (step.stayOn == null ? false : step.stayOn); boolean isBogusName = (step.bogusName == null ? false : step.bogusName); double lon = step.lon; double lat = step.lat; String elevation = step.elevation; List<Alerts> alert = step.alerts; // Walk East if (relativeDir == null) { subDirectionText += action + " "; subDirectionText += absoluteDir.name() + " "; } // (Turn left)/(Continue) else { if (!isStayOn) { RelativeDirection rDir = RelativeDirection.valueOf(relativeDir.name()); // Do not need TURN Continue if (rDir.compareTo(RelativeDirection.CONTINUE) != 0 && rDir.compareTo(RelativeDirection.CIRCLE_CLOCKWISE) != 0 && rDir.compareTo(RelativeDirection.CIRCLE_COUNTERCLOCKWISE) != 0) { subDirectionText += "Turn "; } subDirectionText += relativeDir.name() + " "; } else { subDirectionText += relativeDir.name() + " "; } } // (on ABC) // if(!isBogusName) { // subDirectionText += "on "+ streetName + " "; // } subDirectionText += "on " + streetName + " "; subDirectionText += "\n[" + Double.toString(distance) + "meters ]"; dir.setDirectionText(subDirectionText); dir.setIcon(icon); // Add new sub-direction subDirections.add(dir); } direction.setSubDirections(subDirections); return direction; }
private ArrayList<Direction> decryptTransit(Leg leg) { ArrayList<Direction> directions = new ArrayList<Direction>(2); Direction onDirection = new Direction(); Direction offDirection = new Direction(); // set icon TraverseMode mode = TraverseMode.valueOf((String) leg.mode); int icon = R.drawable.mode_bus; if (mode.compareTo(TraverseMode.RAIL) == 0) { icon = R.drawable.mode_rail; } else if (mode.compareTo(TraverseMode.FERRY) == 0) { icon = R.drawable.mode_ferry; } else if (mode.compareTo(TraverseMode.GONDOLA) == 0) { icon = R.drawable.mode_gondola; } else if (mode.compareTo(TraverseMode.SUBWAY) == 0) { icon = R.drawable.mode_subway; } else if (mode.compareTo(TraverseMode.TRAM) == 0) { icon = R.drawable.mode_tram; } onDirection.setIcon(icon); // set direction text String onDirectionText = ""; String offDirectionText = ""; String route = leg.route; String agencyName = leg.agencyName; String agencyUrl = leg.agencyId; String routeColor = leg.routeColor; String routeTextColor = leg.routeTextColor; boolean isInterlineWithPreviousLeg = (leg.interlineWithPreviousLeg == null ? false : leg.interlineWithPreviousLeg); String tripShortName = leg.tripShortName; String headsign = leg.headsign; String agencyId = leg.agencyId; String routeShortName = leg.routeShortName; String routeLongName = leg.routeLongName; String boardRule = leg.boardRule; String alignRule = leg.alightRule; ArrayList<Place> stopsInBetween = new ArrayList<Place>(); if (leg.getIntermediateStops() != null) stopsInBetween.addAll(leg.getIntermediateStops()); double distance = leg.distance; Place from = leg.from; AgencyAndId agencyAndIdFrom = from.stopId; Place to = leg.to; AgencyAndId agencyAndIdTo = to.stopId; long duration = leg.duration; // Get on HART BUS 6 String serviceName = agencyName; if (serviceName == null) serviceName = agencyId; offDirectionText += "Get off " + serviceName + " " + mode + " " + route + "\n"; offDirectionText += "At " + to.name + " (" + agencyAndIdTo.getAgencyId() + " " + agencyAndIdTo.getId() + ")"; offDirection.setDirectionText(offDirectionText); offDirection.setIcon(icon); // Only onDirection has subdirection (list of stops in between) onDirectionText += "Get on " + serviceName + " " + mode + " " + route + "\n"; onDirectionText += "At " + from.name + " (" + agencyAndIdFrom.getAgencyId() + " " + agencyAndIdFrom.getId() + ")\n"; onDirectionText += stopsInBetween.size() + " stops in between"; onDirection.setDirectionText(onDirectionText); onDirection.setIcon(icon); // sub-direction ArrayList<Direction> subDirections = new ArrayList<Direction>(); for (int i = 0; i < stopsInBetween.size(); i++) { Direction subDirection = new Direction(); Place stop = stopsInBetween.get(i); AgencyAndId agencyAndIdStop = stop.stopId; String subDirectionText = Integer.toString(i) + ". " + stop.name + " (" + agencyAndIdStop.getAgencyId() + " " + agencyAndIdStop.getId() + ")"; subDirection.setDirectionText(subDirectionText); subDirection.setIcon(icon); subDirections.add(subDirection); } onDirection.setSubDirections(subDirections); // Distance traveled [distance] DecimalFormat twoDForm = new DecimalFormat("#.##"); distance = Double.valueOf(twoDForm.format(distance)); onDirection.setDistanceTraveled(distance); directions.add(onDirection); directions.add(offDirection); return directions; }
private void fixupTransitLeg(Leg leg, State state, TransitIndexService transitIndex) { EdgeNarrative en = state.getBackEdgeNarrative(); leg.route = en.getName(); Trip trip = en.getTrip(); if (trip != null) { leg.headsign = trip.getTripHeadsign(); leg.tripId = trip.getId().getId(); leg.agencyId = trip.getId().getAgencyId(); leg.tripShortName = trip.getTripShortName(); leg.routeShortName = trip.getRoute().getShortName(); leg.routeLongName = trip.getRoute().getLongName(); leg.routeColor = trip.getRoute().getColor(); leg.routeTextColor = trip.getRoute().getTextColor(); if (transitIndex != null) { Agency agency = transitIndex.getAgency(leg.agencyId); leg.agencyName = agency.getName(); leg.agencyUrl = agency.getUrl(); } } leg.mode = en.getMode().toString(); leg.startTime = makeCalendar(state.getBackState()); }
/** * Generate an itinerary from a @{link GraphPath}. The algorithm here is to walk over each state * in the graph path, accumulating geometry, time, and length data from the incoming edge. When * the incoming edge and outgoing edge have different modes (or when a vehicle changes names due * to interlining) a new leg is generated. Street legs undergo an additional processing step to * generate turn-by-turn directions. * * @param path * @param showIntermediateStops whether intermediate stops are included in the generated itinerary * @return itinerary */ private Itinerary generateItinerary(GraphPath path, boolean showIntermediateStops) { Graph graph = path.getRoutingContext().graph; TransitIndexService transitIndex = graph.getService(TransitIndexService.class); Itinerary itinerary = makeEmptyItinerary(path); EdgeNarrative postponedAlerts = null; Leg leg = null; CoordinateArrayListSequence coordinates = new CoordinateArrayListSequence(); double previousElevation = Double.MAX_VALUE; int startWalk = -1; int i = -1; PlanGenState pgstate = PlanGenState.START; String nextName = null; for (State state : path.states) { i += 1; Edge backEdge = state.getBackEdge(); EdgeNarrative backEdgeNarrative = state.getBackEdgeNarrative(); if (backEdge == null) { continue; } TraverseMode mode = backEdgeNarrative.getMode(); if (mode != null) { long dt = state.getAbsTimeDeltaSec(); if (mode == TraverseMode.BOARDING || mode == TraverseMode.ALIGHTING || mode == TraverseMode.STL) { itinerary.waitingTime += dt; } else if (mode.isOnStreetNonTransit()) { itinerary.walkDistance += backEdgeNarrative.getDistance(); itinerary.walkTime += dt; } else if (mode.isTransit()) { itinerary.transitTime += dt; } } if (backEdge instanceof FreeEdge) { if (backEdge instanceof PreBoardEdge) { // Add boarding alerts to the next leg postponedAlerts = backEdgeNarrative; } else if (backEdge instanceof PreAlightEdge) { // Add alighting alerts to the previous leg addNotesToLeg(itinerary.legs.get(itinerary.legs.size() - 1), backEdgeNarrative); } continue; } if (backEdge instanceof EdgeWithElevation) { PackedCoordinateSequence profile = ((EdgeWithElevation) backEdge).getElevationProfile(); previousElevation = applyElevation(profile, itinerary, previousElevation); } switch (pgstate) { case START: if (mode == TraverseMode.WALK) { pgstate = PlanGenState.WALK; leg = makeLeg(itinerary, state); leg.from.orig = nextName; startWalk = i; } else if (mode == TraverseMode.BICYCLE) { pgstate = PlanGenState.BICYCLE; leg = makeLeg(itinerary, state); leg.from.orig = nextName; startWalk = i; } else if (mode == TraverseMode.CAR) { pgstate = PlanGenState.CAR; leg = makeLeg(itinerary, state); leg.from.orig = nextName; startWalk = i; } else if (mode == TraverseMode.BOARDING) { // this itinerary starts with transit pgstate = PlanGenState.PRETRANSIT; leg = makeLeg(itinerary, state); leg.from.orig = nextName; startWalk = -1; } else if (mode == TraverseMode.STL) { // this comes after an alight; do nothing } else if (mode == TraverseMode.TRANSFER) { // handle the whole thing in one step leg = makeLeg(itinerary, state); coordinates = new CoordinateArrayListSequence(); coordinates.add(state.getBackState().getVertex().getCoordinate()); coordinates.add(state.getVertex().getCoordinate()); finalizeLeg(leg, state, path.states, i, i, coordinates); coordinates.clear(); } else { LOG.error("Unexpected state (in START): " + mode); } break; case WALK: if (leg == null) { leg = makeLeg(itinerary, state); } if (mode == TraverseMode.WALK) { // do nothing } else if (mode == TraverseMode.BICYCLE) { finalizeLeg(leg, state, path.states, startWalk, i, coordinates); startWalk = i; leg = makeLeg(itinerary, state); if (backEdge instanceof RentABikeOnEdge) { leg.rentedBike = true; } pgstate = PlanGenState.BICYCLE; } else if (mode == TraverseMode.STL) { finalizeLeg(leg, state, path.states, startWalk, i, coordinates); leg = null; pgstate = PlanGenState.PRETRANSIT; } else if (mode == TraverseMode.BOARDING) { // this only happens in case of a timed transfer. pgstate = PlanGenState.PRETRANSIT; finalizeLeg(leg, state, path.states, startWalk, i, coordinates); leg = makeLeg(itinerary, state); itinerary.transfers++; } else if (backEdgeNarrative instanceof LegSwitchingEdge) { nextName = state.getBackState().getBackState().getBackState().getVertex().getName(); finalizeLeg(leg, state, path.states, startWalk, i - 1, coordinates); leg = null; pgstate = PlanGenState.START; } else { LOG.error("Unexpected state (in WALK): " + mode); } break; case BICYCLE: if (leg == null) { leg = makeLeg(itinerary, state); } if (mode == TraverseMode.BICYCLE) { // do nothing } else if (mode == TraverseMode.WALK) { finalizeLeg(leg, state, path.states, startWalk, i, coordinates); leg = makeLeg(itinerary, state); startWalk = i; pgstate = PlanGenState.WALK; } else if (mode == TraverseMode.STL) { finalizeLeg(leg, state, path.states, startWalk, i, coordinates); leg = null; pgstate = PlanGenState.PRETRANSIT; } else if (backEdgeNarrative instanceof LegSwitchingEdge) { finalizeLeg(leg, state, path.states, startWalk, i - 1, coordinates); leg = null; pgstate = PlanGenState.START; } else { LOG.error("Unexpected state (in BICYCLE): " + mode); } break; case CAR: if (leg == null) { leg = makeLeg(itinerary, state); } if (mode == TraverseMode.CAR) { // do nothing } else if (mode == TraverseMode.STL) { finalizeLeg(leg, state, path.states, startWalk, i, coordinates); leg = null; pgstate = PlanGenState.PRETRANSIT; } else if (backEdgeNarrative instanceof LegSwitchingEdge) { finalizeLeg(leg, state, path.states, startWalk, i - 1, coordinates); leg = null; pgstate = PlanGenState.START; } else { LOG.error("Unexpected state (in CAR): " + mode); } break; case PRETRANSIT: if (mode == TraverseMode.BOARDING) { if (leg != null) { LOG.error("leg unexpectedly not null (boarding loop)"); } else { leg = makeLeg(itinerary, state); leg.stop = new ArrayList<Place>(); itinerary.transfers++; leg.boardRule = (String) state.getExtension("boardAlightRule"); } } else if (backEdge instanceof HopEdge) { pgstate = PlanGenState.TRANSIT; fixupTransitLeg(leg, state, transitIndex); leg.stop = new ArrayList<Place>(); } else { LOG.error("Unexpected state (in PRETRANSIT): " + mode); } break; case TRANSIT: String route = backEdgeNarrative.getName(); if (mode == TraverseMode.ALIGHTING) { if (showIntermediateStops && leg.stop != null && leg.stop.size() > 0) { if (leg.stop.isEmpty()) { leg.stop = null; } } leg.alightRule = (String) state.getExtension("boardAlightRule"); finalizeLeg(leg, state, null, -1, -1, coordinates); leg = null; pgstate = PlanGenState.START; } else if (mode.toString().equals(leg.mode)) { // no mode change, handle intermediate stops if (showIntermediateStops) { /* * any further transit edge, add "from" vertex to intermediate stops */ if (!(backEdge instanceof DwellEdge)) { Place stop = makePlace(state.getBackState(), true); leg.stop.add(stop); } else if (leg.stop.size() > 0) { leg.stop.get(leg.stop.size() - 1).departure = makeCalendar(state); } } if (!route.equals(leg.route)) { // interline dwell finalizeLeg(leg, state, null, -1, -1, coordinates); leg = makeLeg(itinerary, state); leg.stop = new ArrayList<Place>(); fixupTransitLeg(leg, state, transitIndex); leg.startTime = makeCalendar(state); leg.interlineWithPreviousLeg = true; } } else { LOG.error("Unexpected state (in TRANSIT): " + mode); } break; } if (leg != null) { leg.distance += backEdgeNarrative.getDistance(); Geometry edgeGeometry = backEdgeNarrative.getGeometry(); if (edgeGeometry != null) { Coordinate[] edgeCoordinates = edgeGeometry.getCoordinates(); if (coordinates.size() > 0 && coordinates.getCoordinate(coordinates.size() - 1).equals(edgeCoordinates[0])) { coordinates.extend(edgeCoordinates, 1); } else { coordinates.extend(edgeCoordinates); } } if (postponedAlerts != null) { addNotesToLeg(leg, postponedAlerts); postponedAlerts = null; } addNotesToLeg(leg, backEdgeNarrative); } } /* end loop over graphPath edge list */ if (leg != null) { finalizeLeg(leg, path.states.getLast(), path.states, startWalk, i, coordinates); } itinerary.removeBogusLegs(); itinerary.fixupDates(graph.getService(CalendarServiceData.class)); if (itinerary.legs.size() == 0) throw new TrivialPathException(); return itinerary; }
private void fixupTransitLeg(Leg leg, State state, TransitIndexService transitIndex) { Edge en = state.getBackEdge(); leg.route = en.getName(); Trip trip = state.getBackTrip(); leg.headsign = state.getBackDirection(); if (trip != null) { // this is the stop headsign // leg.headsign = "This is the headsign"; // handle no stop headsign if (leg.headsign == null) leg.headsign = trip.getTripHeadsign(); leg.tripId = trip.getId().getId(); leg.agencyId = trip.getId().getAgencyId(); leg.tripShortName = trip.getTripShortName(); leg.routeShortName = trip.getRoute().getShortName(); leg.routeLongName = trip.getRoute().getLongName(); leg.routeColor = trip.getRoute().getColor(); leg.routeTextColor = trip.getRoute().getTextColor(); leg.routeId = trip.getRoute().getId().getId(); if (transitIndex != null) { Agency agency = transitIndex.getAgency(leg.agencyId); leg.agencyName = agency.getName(); leg.agencyUrl = agency.getUrl(); } } leg.mode = state.getBackMode().toString(); leg.startTime = makeCalendar(state.getBackState()); }
/** * Generate an itinerary from a @{link GraphPath}. The algorithm here is to walk over each state * in the graph path, accumulating geometry, time, and length data from the incoming edge. When * the incoming edge and outgoing edge have different modes (or when a vehicle changes names due * to interlining) a new leg is generated. Street legs undergo an additional processing step to * generate turn-by-turn directions. * * @param path * @param showIntermediateStops whether intermediate stops are included in the generated itinerary * @return itinerary */ private Itinerary generateItinerary(GraphPath path, boolean showIntermediateStops) { Graph graph = path.getRoutingContext().graph; TransitIndexService transitIndex = graph.getService(TransitIndexService.class); Itinerary itinerary = makeEmptyItinerary(path); Set<Alert> postponedAlerts = null; Leg leg = null; CoordinateArrayListSequence coordinates = new CoordinateArrayListSequence(); double previousElevation = Double.MAX_VALUE; int startWalk = -1; int i = -1; boolean foldingElevatorLegIntoCycleLeg = false; PlanGenState pgstate = PlanGenState.START; String nextName = null; for (State state : path.states) { i += 1; Edge backEdge = state.getBackEdge(); if (backEdge == null) { continue; } // debug: push vehicle late status out to UI // if (backEdge instanceof PatternHop) { // TripTimes tt = state.getTripTimes(); // int hop = ((PatternHop)backEdge).stopIndex; // LOG.info("{} {}", tt.getTrip().toString(), hop); // if ( ! tt.isScheduled()) { // int delay = tt.getDepartureDelay(hop); // String d = "on time"; // if (Math.abs(delay) > 10) { // d = String.format("%2.1f min %s", delay / 60.0, // (delay < 0) ? "early" : "late"); // } // d = "Using real-time delay information: ".concat(d); // leg.addAlert(Alert.createSimpleAlerts(d)); // LOG.info(d); // } // else { // leg.addAlert(Alert.createSimpleAlerts("Using published timetables.")); // LOG.info("sched"); // } // } TraverseMode mode = state.getBackMode(); if (mode != null) { long dt = state.getAbsTimeDeltaSec(); if (mode == TraverseMode.BOARDING || mode == TraverseMode.ALIGHTING || mode == TraverseMode.STL) { itinerary.waitingTime += dt; } else if (mode.isOnStreetNonTransit()) { itinerary.walkDistance += backEdge.getDistance(); itinerary.walkTime += dt; } else if (mode.isTransit()) { itinerary.transitTime += dt; } } if (backEdge instanceof FreeEdge) { if (backEdge instanceof PreBoardEdge) { // Add boarding alerts to the next leg postponedAlerts = state.getBackAlerts(); } else if (backEdge instanceof PreAlightEdge) { // Add alighting alerts to the previous leg addNotesToLeg(itinerary.legs.get(itinerary.legs.size() - 1), state.getBackAlerts()); } continue; } if (backEdge instanceof EdgeWithElevation) { PackedCoordinateSequence profile = ((EdgeWithElevation) backEdge).getElevationProfile(); previousElevation = applyElevation(profile, itinerary, previousElevation); } switch (pgstate) { case START: if (mode == TraverseMode.WALK) { pgstate = PlanGenState.WALK; leg = makeLeg(itinerary, state); leg.from.orig = nextName; startWalk = i; } else if (mode == TraverseMode.BICYCLE) { pgstate = PlanGenState.BICYCLE; leg = makeLeg(itinerary, state); leg.from.orig = nextName; startWalk = i; } else if (mode == TraverseMode.CAR) { pgstate = PlanGenState.CAR; leg = makeLeg(itinerary, state); leg.from.orig = nextName; startWalk = i; } else if (mode == TraverseMode.BOARDING) { // this itinerary starts with transit pgstate = PlanGenState.PRETRANSIT; leg = makeLeg(itinerary, state); leg.from.orig = nextName; itinerary.transfers++; startWalk = -1; } else if (mode == TraverseMode.STL) { // this comes after an alight; do nothing } else if (mode == TraverseMode.TRANSFER) { // handle the whole thing in one step leg = makeLeg(itinerary, state); coordinates = new CoordinateArrayListSequence(); coordinates.add(state.getBackState().getVertex().getCoordinate()); coordinates.add(state.getVertex().getCoordinate()); finalizeLeg(leg, state, path.states, i, i, coordinates, itinerary); coordinates.clear(); } else { LOG.error("Unexpected state (in START): " + mode); } break; case WALK: if (leg == null) { leg = makeLeg(itinerary, state); } if (mode == TraverseMode.WALK) { // do nothing } else if (mode == TraverseMode.BICYCLE) { finalizeLeg(leg, state, path.states, startWalk, i, coordinates, itinerary); startWalk = i; leg = makeLeg(itinerary, state); pgstate = PlanGenState.BICYCLE; } else if (mode == TraverseMode.STL) { finalizeLeg(leg, state, path.states, startWalk, i, coordinates, itinerary); leg = null; pgstate = PlanGenState.PRETRANSIT; } else if (mode == TraverseMode.BOARDING) { // this only happens in case of a timed transfer. pgstate = PlanGenState.PRETRANSIT; finalizeLeg(leg, state, path.states, startWalk, i, coordinates, itinerary); leg = makeLeg(itinerary, state); itinerary.transfers++; } else if (backEdge instanceof LegSwitchingEdge) { nextName = state.getBackState().getBackState().getBackState().getVertex().getName(); finalizeLeg(leg, state, path.states, startWalk, i - 1, coordinates, itinerary); leg = null; pgstate = PlanGenState.START; } else { LOG.error("Unexpected state (in WALK): " + mode); } break; case BICYCLE: if (leg == null) { leg = makeLeg(itinerary, state); } // If there are elevator edges that have mode == BICYCLE on both sides, they should // be folded into the bicycle leg. But ones with walk on one side or the other should // not if (state.getBackEdge() instanceof ElevatorBoardEdge) { int j = i + 1; // proceed forward from the current state until we find one that isn't on an // elevator, and check the traverse mode while (path.states.get(j).getBackEdge() instanceof ElevatorEdge) j++; // path.states[j] is not an elevator edge if (path.states.get(j).getBackMode() == TraverseMode.BICYCLE) foldingElevatorLegIntoCycleLeg = true; } if (foldingElevatorLegIntoCycleLeg) { if (state.getBackEdge() instanceof ElevatorEdge) { break; // from the case } else { foldingElevatorLegIntoCycleLeg = false; // do not break but allow it to be processed below (which will do nothing) } } if (mode == TraverseMode.BICYCLE) { // do nothing } else if (mode == TraverseMode.WALK) { finalizeLeg(leg, state, path.states, startWalk, i, coordinates, itinerary); leg = makeLeg(itinerary, state); startWalk = i; pgstate = PlanGenState.WALK; } else if (mode == TraverseMode.STL) { finalizeLeg(leg, state, path.states, startWalk, i, coordinates, itinerary); startWalk = i; leg = null; pgstate = PlanGenState.PRETRANSIT; } else if (backEdge instanceof LegSwitchingEdge) { finalizeLeg(leg, state, path.states, startWalk, i - 1, coordinates, itinerary); leg = null; pgstate = PlanGenState.START; } else { LOG.error("Unexpected state (in BICYCLE): " + mode); } break; case CAR: if (leg == null) { leg = makeLeg(itinerary, state); } if (mode == TraverseMode.CAR) { // do nothing } else if (mode == TraverseMode.STL) { finalizeLeg(leg, state, path.states, startWalk, i, coordinates, itinerary); leg = null; pgstate = PlanGenState.PRETRANSIT; } else if (backEdge instanceof LegSwitchingEdge) { finalizeLeg(leg, state, path.states, startWalk, i - 1, coordinates, itinerary); leg = null; pgstate = PlanGenState.START; } else { LOG.error("Unexpected state (in CAR): " + mode); } break; case PRETRANSIT: if (mode == TraverseMode.BOARDING) { if (leg != null) { LOG.error("leg unexpectedly not null (boarding loop)"); } else { leg = makeLeg(itinerary, state); leg.from.stopIndex = ((OnBoardForwardEdge) backEdge).getStopIndex(); leg.stop = new ArrayList<Place>(); itinerary.transfers++; leg.boardRule = (String) state.getExtension("boardAlightRule"); } } else if (backEdge instanceof HopEdge) { pgstate = PlanGenState.TRANSIT; fixupTransitLeg(leg, state, transitIndex); leg.stop = new ArrayList<Place>(); } else { LOG.error("Unexpected state (in PRETRANSIT): " + mode); } break; case TRANSIT: String route = backEdge.getName(); if (mode == TraverseMode.ALIGHTING) { if (showIntermediateStops && leg.stop != null && leg.stop.size() > 0) { if (leg.stop.isEmpty()) { leg.stop = null; } } leg.alightRule = (String) state.getExtension("boardAlightRule"); finalizeLeg(leg, state, null, -1, -1, coordinates, itinerary); leg = null; pgstate = PlanGenState.START; } else if (mode.toString().equals(leg.mode)) { // no mode change, handle intermediate stops if (showIntermediateStops) { /* * any further transit edge, add "from" vertex to intermediate stops */ if (!(backEdge instanceof DwellEdge)) { Place stop = makePlace( state.getBackState(), state.getBackState().getVertex().getName(), true); leg.stop.add(stop); } else if (leg.stop.size() > 0) { leg.stop.get(leg.stop.size() - 1).departure = makeCalendar(state); } } if (!route.equals(leg.route)) { // interline dwell finalizeLeg(leg, state, null, -1, -1, coordinates, itinerary); leg = makeLeg(itinerary, state); leg.stop = new ArrayList<Place>(); fixupTransitLeg(leg, state, transitIndex); leg.startTime = makeCalendar(state); leg.interlineWithPreviousLeg = true; } } else { LOG.error("Unexpected state (in TRANSIT): " + mode); } break; } if (leg != null) { leg.distance += backEdge.getDistance(); Geometry edgeGeometry = backEdge.getGeometry(); if (edgeGeometry != null) { Coordinate[] edgeCoordinates = edgeGeometry.getCoordinates(); if (coordinates.size() > 0 && coordinates.getCoordinate(coordinates.size() - 1).equals(edgeCoordinates[0])) { coordinates.extend(edgeCoordinates, 1); } else { coordinates.extend(edgeCoordinates); } } if (postponedAlerts != null) { addNotesToLeg(leg, postponedAlerts); postponedAlerts = null; } addNotesToLeg(leg, state.getBackAlerts()); } } /* end loop over graphPath edge list */ if (leg != null) { finalizeLeg(leg, path.states.getLast(), path.states, startWalk, i, coordinates, itinerary); } itinerary.removeBogusLegs(); itinerary.fixupDates(graph.getService(CalendarServiceData.class)); if (itinerary.legs.size() == 0) throw new TrivialPathException(); return itinerary; }
public Direction generateTransitSubdirection(Leg leg, boolean isOnDirection) { Direction direction = new Direction(); direction.setRealTimeInfo(leg.realTime); // Set icon String mode = getLocalizedMode(TraverseMode.valueOf(leg.mode), applicationContext.getResources()); int modeIcon; String route; String agencyName = leg.agencyName; Place from = leg.from; Place to = leg.to; Calendar newTime = Calendar.getInstance(); Calendar oldTime = Calendar.getInstance(); String shortName; // As a work-around for #662, we always use routeShortName and not tripShortName shortName = leg.routeShortName; route = ConversionUtils.getRouteLongNameSafe(leg.routeLongName, shortName, true); direction.setTransit(true); String action, placeAndHeadsign, extra = ""; if (isOnDirection) { action = applicationContext.getResources().getString(R.string.step_by_step_transit_get_on); placeAndHeadsign = from.name; TraverseModeSet modeSet = new TraverseModeSet(leg.mode); modeIcon = getModeIcon(modeSet); newTime.setTime(new Date(Long.parseLong(leg.startTime))); oldTime.setTime(new Date(newTime.getTimeInMillis())); oldTime.add(Calendar.SECOND, -leg.departureDelay); // Only onDirection has subdirection (list of stops in between) ArrayList<Place> stopsInBetween = new ArrayList<Place>(); if ((leg.getIntermediateStops() != null) && !leg.getIntermediateStops().isEmpty()) { stopsInBetween.addAll(leg.getIntermediateStops()); } else if ((leg.stop != null) && !leg.stop.isEmpty()) { stopsInBetween.addAll(leg.stop); } // sub-direction ArrayList<Direction> subDirections = new ArrayList<Direction>(); for (int i = 0; i < stopsInBetween.size(); i++) { Direction subDirection = new Direction(); Place stop = stopsInBetween.get(i); String extraStopInformation = stop.stopCode; String subDirectionText = Integer.toString(i + 1) + ". " + stop.name; if (!TextUtils.isEmpty(extraStopInformation)) { subDirectionText += " (" + extraStopInformation + ")"; } subDirection.setDirectionText(subDirectionText); subDirection.setIcon(DirectionsGenerator.getStopIcon(modeSet)); subDirections.add(subDirection); } direction.setSubDirections(subDirections); if (stopsInBetween.size() > 0) { String connector = applicationContext .getResources() .getString(R.string.step_by_step_transit_stops_in_between); if (stopsInBetween.size() == 1) { connector = applicationContext .getResources() .getString(R.string.step_by_step_transit_stops_in_between_singular); } extra = stopsInBetween.size() + " " + connector; } if (!TextUtils.isEmpty(leg.headsign)) { placeAndHeadsign += " " + applicationContext .getResources() .getString(R.string.step_by_step_transit_connector_headsign) + " " + leg.headsign; } } else { action = applicationContext.getResources().getString(R.string.step_by_step_transit_get_off); placeAndHeadsign = to.name; modeIcon = -1; newTime.setTime(new Date(Long.parseLong(leg.endTime))); oldTime.setTime(new Date(newTime.getTimeInMillis())); oldTime.add(Calendar.SECOND, -leg.arrivalDelay); } direction.setIcon(modeIcon); direction.setPlaceAndHeadsign( applicationContext .getResources() .getString(R.string.step_by_step_transit_connector_stop_name) + " " + placeAndHeadsign); direction.setService(action + " " + mode + " " + route); direction.setAgency(agencyName); direction.setExtra(extra); SpannableString oldTimeString; if (leg.realTime) { CharSequence newTimeString; newTimeString = ConversionUtils.getTimeUpdated( applicationContext, leg.agencyTimeZoneOffset, oldTime.getTimeInMillis(), newTime.getTimeInMillis()); direction.setNewTime(newTimeString); } oldTimeString = new SpannableString( ConversionUtils.getTimeWithContext( applicationContext, leg.agencyTimeZoneOffset, oldTime.getTimeInMillis(), true)); direction.setOldTime(oldTimeString); return direction; }
private Direction generateNonTransitDirections(Leg leg) { Direction direction = new Direction(); // http://opentripplanner.usf.edu/opentripplanner-api-webapp/ws/plan?optimize=QUICK&time=09:24pm&arriveBy=false&wheelchair=false&maxWalkDistance=7600.0&fromPlace=28.033389%2C+-82.521034&toPlace=28.064709%2C+-82.471618&date=03/07/12&mode=WALK,TRAM,SUBWAY,RAIL,BUS,FERRY,CABLE_CAR,GONDOLA,FUNICULAR,TRANSIT,TRAINISH,BUSISH // Get appropriate action and icon String action = applicationContext .getResources() .getString(R.string.step_by_step_non_transit_mode_walk_action); TraverseMode mode = TraverseMode.valueOf((String) leg.mode); int icon = getModeIcon(new TraverseModeSet(mode)); if (mode.compareTo(TraverseMode.BICYCLE) == 0) { action = applicationContext .getResources() .getString(R.string.step_by_step_non_transit_mode_bicycle_action); } else if (mode.compareTo(TraverseMode.CAR) == 0) { action = applicationContext .getResources() .getString(R.string.step_by_step_non_transit_mode_car_action); } direction.setIcon(icon); // Main direction Place fromPlace = leg.from; Place toPlace = leg.to; String mainDirectionText = action; mainDirectionText += fromPlace.name == null ? "" : " " + applicationContext .getResources() .getString(R.string.step_by_step_non_transit_from) + " " + getLocalizedStreetName(fromPlace.name, applicationContext.getResources()); mainDirectionText += toPlace.name == null ? "" : " " + applicationContext.getResources().getString(R.string.step_by_step_non_transit_to) + " " + getLocalizedStreetName(toPlace.name, applicationContext.getResources()); String extraStopInformation = toPlace.stopCode; long legDuration; SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext); if (prefs.getInt(OTPConstants.PREFERENCE_KEY_API_VERSION, OTPConstants.API_VERSION_V1) == OTPConstants.API_VERSION_V1) { legDuration = leg.duration; } else { legDuration = leg.duration / 1000; } if (!TextUtils.isEmpty(extraStopInformation)) { mainDirectionText += " (" + extraStopInformation + ")"; } mainDirectionText += "\n[" + ConversionUtils.getFormattedDistance(leg.distance, applicationContext) + " - " + ConversionUtils.getFormattedDurationTextNoSeconds( legDuration, false, applicationContext) + " ]"; direction.setDirectionText(mainDirectionText); // Sub-direction List<WalkStep> walkSteps = leg.getSteps(); if (walkSteps == null) { return direction; } ArrayList<Direction> subDirections = new ArrayList<Direction>(walkSteps.size()); for (WalkStep step : walkSteps) { int subdirection_icon = -1; Direction dir = new Direction(); String subDirectionText = ""; double distance = step.distance; RelativeDirection relativeDir = step.relativeDirection; String relativeDirString = getLocalizedRelativeDir(relativeDir, applicationContext.getResources()); String streetName = step.streetName; AbsoluteDirection absoluteDir = step.absoluteDirection; String absoluteDirString = getLocalizedAbsoluteDir(absoluteDir, applicationContext.getResources()); String exit = step.exit; boolean isStayOn = (step.stayOn == null ? false : step.stayOn); boolean isBogusName = (step.bogusName == null ? false : step.bogusName); double lon = step.lon; double lat = step.lat; String streetConnector = applicationContext .getResources() .getString(R.string.step_by_step_non_transit_connector_street_name); // Elevation[] elevation = step.getElevation(); //Removed elevation for now, since we're not // doing anything with it and it causes version issues between OTP server APIs v0.9.1-SNAPSHOT // and v0.9.2-SNAPSHOT List<Alerts> alert = step.alerts; // Walk East if (relativeDir == null) { subDirectionText += action + " " + applicationContext .getResources() .getString(R.string.step_by_step_non_transit_heading) + " "; subDirectionText += absoluteDirString + " "; } // (Turn left)/(Continue) else { RelativeDirection rDir = RelativeDirection.valueOf(relativeDir.name()); subdirection_icon = getRelativeDirectionIcon(rDir, applicationContext.getResources()); // Do not need TURN Continue if (rDir.compareTo(RelativeDirection.RIGHT) == 0 || rDir.compareTo(RelativeDirection.LEFT) == 0) { subDirectionText += applicationContext.getResources().getString(R.string.step_by_step_non_transit_turn) + " "; } subDirectionText += relativeDirString + " "; if (rDir.compareTo(RelativeDirection.CIRCLE_CLOCKWISE) == 0 || rDir.compareTo(RelativeDirection.CIRCLE_COUNTERCLOCKWISE) == 0) { if (step.exit != null) { try { String ordinal = getOrdinal(Integer.parseInt(step.exit), applicationContext.getResources()); if (ordinal != null) { subDirectionText += ordinal + " "; } else { subDirectionText += applicationContext .getResources() .getString(R.string.step_by_step_non_transit_roundabout_number) + " " + ordinal + " "; } } catch (NumberFormatException e) { // If is not a step_by_step_non_transit_roundabout_number and is not null is better to // try to display it subDirectionText += step.exit + " "; } subDirectionText += applicationContext .getResources() .getString(R.string.step_by_step_non_transit_roundabout_exit) + " "; streetConnector = applicationContext .getResources() .getString(R.string.step_by_step_non_transit_connector_street_name_roundabout); } } } subDirectionText += streetConnector + " " + getLocalizedStreetName(streetName, applicationContext.getResources()) + " "; subDirectionText += "\n[" + ConversionUtils.getFormattedDistance(distance, applicationContext) + " ]"; dir.setDirectionText(subDirectionText); dir.setIcon(subdirection_icon); // Add new sub-direction subDirections.add(dir); } direction.setSubDirections(subDirections); return direction; }