/**
  * @param schedule
  * @return
  */
 public static TransitSchedule removeRoutesWithOnlyOneRouteStop(TransitSchedule schedule) {
   log.info("Removing transitRoutes with only one stop...");
   TransitSchedule tS = TransitScheduleCleaner.makeTransitScheduleModifiable(schedule);
   Set<Id> routeIds;
   for (TransitLine line : tS.getTransitLines().values()) {
     routeIds = new HashSet<Id>();
     for (TransitRoute route : line.getRoutes().values()) {
       // a transitRoute with only one stop makes no sense
       if (route.getStops().size() < 2) {
         routeIds.add(route.getId());
       }
     }
     // remove identified routes
     for (Id id : routeIds) {
       line.removeRoute(line.getRoutes().get(id));
     }
     // log only if something has been done
     if (routeIds.size() > 0) {
       log.info(
           "Following TransitRoutes are removed from TransitLine: "
               + line.getId()
               + ". "
               + routeIds.toString());
     }
   }
   return tS;
 }
 private void cleanSchedule() {
   for (TransitLine line : this.schedule.getTransitLines().values()) {
     Set<TransitRoute> toRemove = new HashSet<>();
     for (TransitRoute transitRoute : line.getRoutes().values()) {
       boolean removeRoute = false;
       NetworkRoute networkRoute = transitRoute.getRoute();
       if (networkRoute.getStartLinkId() == null || networkRoute.getEndLinkId() == null) {
         removeRoute = true;
       }
       for (Id<Link> linkId : transitRoute.getRoute().getLinkIds()) {
         if (linkId == null) {
           removeRoute = true;
         }
       }
       if (removeRoute) {
         log.error(
             "NetworkRoute for " + transitRoute.getId().toString() + " incomplete. Remove route.");
         toRemove.add(transitRoute);
       }
     }
     if (!toRemove.isEmpty()) {
       for (TransitRoute transitRoute : toRemove) {
         line.removeRoute(transitRoute);
       }
     }
   }
 }
  public static TransitSchedule removeRoutesWithoutDepartures(TransitSchedule transitSchedule) {

    log.info("Removing all routes without any departure");
    TransitSchedule tS = TransitScheduleCleaner.makeTransitScheduleModifiable(transitSchedule);
    printStatistic(tS);

    StringBuffer sB = new StringBuffer();
    int nOfRouteRemoved = 0;

    for (TransitLine line : tS.getTransitLines().values()) {
      List<TransitRoute> routesToRemove = new LinkedList<TransitRoute>();

      for (TransitRoute route : line.getRoutes().values()) {
        if (route.getDepartures().size() == 0) {
          routesToRemove.add(route);
        }
      }

      for (TransitRoute transitRoute : routesToRemove) {
        line.removeRoute(transitRoute);
        sB.append(line.getId() + "-" + transitRoute.getId());
        sB.append(", ");
        nOfRouteRemoved++;
      }
    }

    printStatistic(tS);
    log.info("Removed " + nOfRouteRemoved + " routes from transitSchedule: " + sB.toString());

    return tS;
  }
 private Set<Id> getStopsUsed(Collection<TransitRoute> routes) {
   Set<Id> stopsUsed = new TreeSet<Id>();
   for (TransitRoute route : routes) {
     for (TransitRouteStop stop : route.getStops()) {
       stopsUsed.add(stop.getStopFacility().getId());
     }
   }
   return stopsUsed;
 }
 public WaitTimeStuckCalculator(
     final Population population,
     final TransitSchedule transitSchedule,
     final int timeSlot,
     final int totalTime) {
   this.population = population;
   this.timeSlot = timeSlot;
   for (TransitLine line : transitSchedule.getTransitLines().values())
     for (TransitRoute route : line.getRoutes().values()) {
       double[] sortedDepartures = new double[route.getDepartures().size()];
       int d = 0;
       for (Departure departure : route.getDepartures().values())
         sortedDepartures[d++] = departure.getDepartureTime();
       Arrays.sort(sortedDepartures);
       Map<Id<TransitStopFacility>, WaitTimeData> stopsMap =
           new HashMap<Id<TransitStopFacility>, WaitTimeData>(100);
       Map<Id<TransitStopFacility>, double[]> stopsScheduledMap =
           new HashMap<Id<TransitStopFacility>, double[]>(100);
       for (TransitRouteStop stop : route.getStops()) {
         stopsMap.put(
             stop.getStopFacility().getId(), new WaitTimeDataArray(totalTime / timeSlot + 1));
         double[] cacheWaitTimes = new double[totalTime / timeSlot + 1];
         for (int i = 0; i < cacheWaitTimes.length; i++) {
           double endTime = timeSlot * (i + 1);
           if (endTime > 24 * 3600) endTime -= 24 * 3600;
           cacheWaitTimes[i] = Time.UNDEFINED_TIME;
           SORTED_DEPARTURES:
           for (double departure : sortedDepartures) {
             double arrivalTime =
                 departure
                     + (stop.getArrivalOffset() != Time.UNDEFINED_TIME
                         ? stop.getArrivalOffset()
                         : stop.getDepartureOffset());
             if (arrivalTime >= endTime) {
               cacheWaitTimes[i] = arrivalTime - endTime;
               break SORTED_DEPARTURES;
             }
           }
           if (cacheWaitTimes[i] == Time.UNDEFINED_TIME)
             cacheWaitTimes[i] =
                 sortedDepartures[0]
                     + 24 * 3600
                     + (stop.getArrivalOffset() != Time.UNDEFINED_TIME
                         ? stop.getArrivalOffset()
                         : stop.getDepartureOffset())
                     - endTime;
         }
         stopsScheduledMap.put(stop.getStopFacility().getId(), cacheWaitTimes);
       }
       Tuple<Id<TransitLine>, Id<TransitRoute>> key =
           new Tuple<Id<TransitLine>, Id<TransitRoute>>(line.getId(), route.getId());
       waitTimes.put(key, stopsMap);
       scheduledWaitTimes.put(key, stopsScheduledMap);
     }
 }
  public static TransitSchedule removeAllRoutesWithMissingLinksFromSchedule(
      TransitSchedule transitSchedule, Network network) {
    log.info("Removing stops and routes with missing links from the schedule");
    TransitSchedule tS = TransitScheduleCleaner.makeTransitScheduleModifiable(transitSchedule);
    printStatistic(tS);
    int removedRoutes = 0;

    // Remove routes with missing links
    for (TransitLine transitLine : tS.getTransitLines().values()) {

      Set<TransitRoute> transitRouteToBeRemoved = new HashSet<TransitRoute>();

      for (TransitRoute transitRoute : transitLine.getRoutes().values()) {

        // Remove Route, when links are missing in the network
        if (network.getLinks().get(transitRoute.getRoute().getStartLinkId()) == null) {
          transitRouteToBeRemoved.add(transitRoute);
          continue;
        }

        for (Id linkId : transitRoute.getRoute().getLinkIds()) {
          if (network.getLinks().get(linkId) == null) {
            transitRouteToBeRemoved.add(transitRoute);
            break;
          }
        }

        if (network.getLinks().get(transitRoute.getRoute().getEndLinkId()) == null) {
          transitRouteToBeRemoved.add(transitRoute);
          continue;
        }

        // Remove route, if one of its stops, has a missing link
        for (TransitRouteStop transitRouteStop : transitRoute.getStops()) {
          if (network.getLinks().get(transitRouteStop.getStopFacility().getLinkId()) == null) {
            transitRouteToBeRemoved.add(transitRoute);
            break;
          }
        }
      }

      for (TransitRoute transitRoute : transitRouteToBeRemoved) {
        if (transitLine.removeRoute(transitRoute) == true) {
          removedRoutes++;
        }
      }
    }

    log.info("Removed " + removedRoutes + " routes due to missing links or stops");
    printStatistic(tS);

    return tS;
  }
  /**
   * Adding TransportMode.pt flags to all links referred by transit schedule
   *
   * @param transitSchedule The transit schedule.
   * @param network The network to be tagged.
   * @return
   */
  public static Network tagTransitLinksInNetwork(TransitSchedule transitSchedule, Network network) {

    log.info("Tagging pt network links");

    if (transitSchedule == null) {
      log.info("No transit schedule given. Returning unmodified network...");
      return network;
    }

    for (TransitStopFacility stopFacitlity : transitSchedule.getFacilities().values()) {
      Set<String> allowedModes =
          new TreeSet<String>(network.getLinks().get(stopFacitlity.getLinkId()).getAllowedModes());
      allowedModes.add(TransportMode.pt);
      network.getLinks().get(stopFacitlity.getLinkId()).setAllowedModes(allowedModes);
    }

    for (TransitLine transitLine : transitSchedule.getTransitLines().values()) {
      for (TransitRoute transitRoute : transitLine.getRoutes().values()) {
        NetworkRoute route = transitRoute.getRoute();

        Set<String> allowedModes;

        allowedModes =
            new TreeSet<String>(network.getLinks().get(route.getStartLinkId()).getAllowedModes());
        allowedModes.add(TransportMode.pt);
        network.getLinks().get(route.getStartLinkId()).setAllowedModes(allowedModes);

        for (Id linkId : route.getLinkIds()) {
          allowedModes = new TreeSet<String>(network.getLinks().get(linkId).getAllowedModes());
          allowedModes.add(TransportMode.pt);
          network.getLinks().get(linkId).setAllowedModes(allowedModes);
        }

        allowedModes =
            new TreeSet<String>(network.getLinks().get(route.getEndLinkId()).getAllowedModes());
        allowedModes.add(TransportMode.pt);
        network.getLinks().get(route.getEndLinkId()).setAllowedModes(allowedModes);
      }
    }

    int taggedLinks = 0;
    for (Link link : network.getLinks().values()) {
      if (link.getAllowedModes().contains(TransportMode.pt)) {
        taggedLinks++;
      }
    }

    log.info("Finished - " + taggedLinks + " links were tagged");

    return network;
  }
  private void convertRoute(final BRoute route) {
    Map<Id<TransitRoute>, TransitRoute> transitRoutes = new HashMap<>();

    for (BFahrt fahrt : route.fahrten) {
      TransitRoute tRoute = transitRoutes.get(getTransitRouteId(route, fahrt.fahrzeitprofil));
      if (tRoute == null) {
        tRoute = convertFahrzeitprofil(route, fahrt.fahrzeitprofil);
        transitRoutes.put(tRoute.getId(), tRoute);
        this.currentTransitLine.addRoute(tRoute);
      }
      tRoute.addDeparture(
          this.builder.createDeparture(
              Id.create(this.departureCounter++, Departure.class), fahrt.departureTime));
    }
  }
 private static boolean isRelatedWithLine(Person person, TransitLine line) {
   ExperimentalTransitRouteFactory factory = new ExperimentalTransitRouteFactory();
   for (Plan plan : person.getPlans())
     for (PlanElement planElement : plan.getPlanElements())
       if (planElement instanceof Leg && ((Leg) planElement).getRoute() instanceof Route) {
         Route origRoute = ((Leg) planElement).getRoute();
         ExperimentalTransitRoute route =
             (ExperimentalTransitRoute)
                 factory.createRoute(origRoute.getStartLinkId(), origRoute.getEndLinkId());
         route.setStartLinkId(origRoute.getStartLinkId());
         route.setEndLinkId(origRoute.getEndLinkId());
         route.setRouteDescription(origRoute.getRouteDescription());
         for (TransitRoute transitRoute : line.getRoutes().values())
           for (TransitRouteStop stop : transitRoute.getStops())
             if (stop.getStopFacility().getId().equals(route.getAccessStopId())
                 || stop.getStopFacility().getId().equals(route.getEgressStopId())) return true;
       }
   return false;
 }
  private final void createVehicleLinkSpeedAttributes() {
    for (TransitLine transitLine : scenario.getTransitSchedule().getTransitLines().values()) {
      for (TransitRoute transitRoute : transitLine.getRoutes().values()) {
        Set<Id> vehIds = new HashSet<Id>();
        for (Departure departure : transitRoute.getDepartures().values()) {
          vehIds.add(departure.getVehicleId());
        }

        Iterator<TransitRouteStop> iterator = transitRoute.getStops().iterator();
        double departure = iterator.next().getDepartureOffset();
        while (iterator.hasNext()) {
          TransitRouteStop routeStop = iterator.next();
          double arrival = routeStop.getArrivalOffset();
          Link link = scenario.getNetwork().getLinks().get(routeStop.getStopFacility().getLinkId());
          double speed = link.getLength() / (arrival - departure);
          if (speed >= 200.0) {
            System.out.println(
                "line="
                    + transitLine.getId()
                    + ";route="
                    + transitRoute.getId()
                    + "stop="
                    + routeStop.getStopFacility().getId()
                    + ": lLenth="
                    + link.getLength()
                    + ";arr="
                    + arrival
                    + ";dep="
                    + departure
                    + "");
          }

          for (Id vehId : vehIds) {
            this.vehicleAttributes.putAttribute(vehId.toString(), link.getId().toString(), speed);
          }

          departure = routeStop.getDepartureOffset();
        }
      }
    }
  }
  public TransitLine createSingleTransitLine(Id<Vehicle> driverId) {
    // initialize
    TransitLine line =
        this.tS.getFactory().createTransitLine(Id.create(driverId, TransitLine.class));
    TransitStopFacility startStop = getRandomTransitStop();
    TransitStopFacility endStop = getRandomTransitStop();

    TransitRoute transitRoute_H =
        createRoute(Id.create(driverId + "_H", TransitRoute.class), startStop, endStop);
    TransitRoute transitRoute_R =
        createRoute(Id.create(driverId + "_R", TransitRoute.class), endStop, startStop);

    // register route
    line.addRoute(transitRoute_H);
    line.addRoute(transitRoute_R);

    // add departures
    int n = 0;
    for (double j = 0.0; j < 24 * 3600; ) {
      Departure departure = this.tS.getFactory().createDeparture(Id.create(n, Departure.class), j);
      departure.setVehicleId(driverId);
      transitRoute_H.addDeparture(departure);
      j += transitRoute_H.getStop(endStop).getDepartureOffset() + 5 * 60;
      n++;

      departure = this.tS.getFactory().createDeparture(Id.create(n, Departure.class), j);
      departure.setVehicleId(driverId);
      transitRoute_R.addDeparture(departure);
      j += transitRoute_R.getStop(startStop).getDepartureOffset() + 5 * 60;
      n++;
    }

    return line;
  }
  private void writeVehicles(String vehiclesOutFile) {
    VehiclesFactory vehFactory = this.veh.getFactory();
    VehicleType vehType =
        vehFactory.createVehicleType(Id.create("defaultTransitVehicleType", VehicleType.class));
    VehicleCapacity capacity = new VehicleCapacityImpl();
    capacity.setSeats(Integer.valueOf(8));
    capacity.setStandingRoom(Integer.valueOf(0));
    vehType.setCapacity(capacity);
    this.veh.addVehicleType(vehType);

    for (TransitLine line : this.tS.getTransitLines().values()) {
      for (TransitRoute route : line.getRoutes().values()) {
        for (Departure departure : route.getDepartures().values()) {
          Vehicle vehicle = vehFactory.createVehicle(departure.getVehicleId(), vehType);
          this.veh.addVehicle(vehicle);
        }
      }
    }

    VehicleWriterV1 writer = new VehicleWriterV1(this.veh);
    writer.writeFile(vehiclesOutFile);
  }
 private void removeNonUsedStopFacilities() {
   // Collect all used stop facilities:
   Set<Id<TransitStopFacility>> usedStopFacilities = new HashSet<>();
   for (TransitLine line : this.schedule.getTransitLines().values()) {
     for (TransitRoute route : line.getRoutes().values()) {
       for (TransitRouteStop stop : route.getStops()) {
         usedStopFacilities.add(stop.getStopFacility().getId());
       }
     }
   }
   // Check all stop facilities if not used:
   Set<TransitStopFacility> unusedStopFacilites = new HashSet<>();
   for (Id<TransitStopFacility> facilityId : this.schedule.getFacilities().keySet()) {
     if (!usedStopFacilities.contains(facilityId)) {
       unusedStopFacilites.add(this.schedule.getFacilities().get(facilityId));
     }
   }
   // Remove all stop facilities not used:
   for (TransitStopFacility facility : unusedStopFacilites) {
     this.schedule.removeStopFacility(facility);
   }
 }
 /**
  * Add to any link that is passed by any route a "pt" in the modes, if it hasn't already one...
  */
 private void prepareNetwork() {
   Map<Id<Link>, ? extends Link> networkLinks = network.getLinks();
   Set<Id<Link>> transitLinks = new HashSet<>();
   for (TransitLine line : this.schedule.getTransitLines().values()) {
     for (TransitRoute transitRoute : line.getRoutes().values()) {
       NetworkRoute networkRoute = transitRoute.getRoute();
       transitLinks.add(networkRoute.getStartLinkId());
       for (Id<Link> linkId : transitRoute.getRoute().getLinkIds()) {
         transitLinks.add(linkId);
       }
       transitLinks.add(networkRoute.getEndLinkId());
     }
   }
   for (Id<Link> transitLinkId : transitLinks) {
     Link transitLink = networkLinks.get(transitLinkId);
     if (!transitLink.getAllowedModes().contains(TransportMode.pt)) {
       Set<String> modes = new HashSet<>();
       modes.addAll(transitLink.getAllowedModes());
       modes.add(TransportMode.pt);
       transitLink.setAllowedModes(modes);
     }
   }
 }
  private TransitRoute convertFahrzeitprofil(
      final BRoute route, final BFahrzeitprofil fahrzeitprofil) {
    List<TransitRouteStop> stops = new ArrayList<TransitRouteStop>();

    double timeOffset = 0;
    for (BFahrzeitprofilpunkt profilpunkt : fahrzeitprofil.profilpunkte) {
      timeOffset += profilpunkt.fahrzeit;
      if (profilpunkt.routenpunkt.realStop) {
        stops.add(
            this.builder.createTransitRouteStop(
                getStopFacility(profilpunkt.routenpunkt.haltepunkt),
                timeOffset,
                timeOffset + profilpunkt.wartezeit));
      }
      timeOffset += profilpunkt.wartezeit;
    }
    Id<TransitRoute> routeId = getTransitRouteId(route, fahrzeitprofil);
    TransitRoute transitRoute =
        this.builder.createTransitRoute(
            routeId, null, stops, "bus"); // TODO find correct transport mode
    transitRoute.setDescription("Linie " + this.tmpLinie.publicId);
    return transitRoute;
  }
  public static TransitSchedule removeStopsNotUsed(TransitSchedule transitSchedule) {

    log.info("Removing stops not used");
    TransitSchedule tS = TransitScheduleCleaner.makeTransitScheduleModifiable(transitSchedule);
    printStatistic(tS);

    Set<Id> stopsInUse = new TreeSet<Id>();
    Set<Id> stopsToBeRemoved = new TreeSet<Id>();

    for (TransitLine transitLine : tS.getTransitLines().values()) {
      for (TransitRoute transitRoute : transitLine.getRoutes().values()) {
        for (TransitRouteStop stop : transitRoute.getStops()) {
          stopsInUse.add(stop.getStopFacility().getId());
        }
      }
    }

    for (TransitStopFacility transitStopFacility : tS.getFacilities().values()) {
      if (!stopsInUse.contains(transitStopFacility.getId())) {
        stopsToBeRemoved.add(transitStopFacility.getId());
      }
    }

    StringBuffer sB = new StringBuffer();

    for (Id transitStopFacilityId : stopsToBeRemoved) {
      tS.getFacilities().remove(transitStopFacilityId);
      sB.append(transitStopFacilityId.toString() + ", ");
    }

    printStatistic(tS);
    log.info(
        "Removed " + stopsToBeRemoved.size() + " stops from transitSchedule: " + sB.toString());

    return tS;
  }
Example #17
0
  public void createGraph(final String filename, final TransitRoute route) {

    HashMap<Id, Integer> stopIndex = new HashMap<Id, Integer>();
    int idx = 0;
    for (TransitRouteStop stop : route.getStops()) {
      stopIndex.put(stop.getStopFacility().getId(), idx);
      idx++;
    }

    HashSet<Id> vehicles = new HashSet<Id>();
    for (Departure dep : route.getDepartures().values()) {
      vehicles.add(dep.getVehicleId());
    }

    XYSeriesCollection dataset = new XYSeriesCollection();
    int numSeries = 0;
    double earliestTime = Double.POSITIVE_INFINITY;
    double latestTime = Double.NEGATIVE_INFINITY;

    for (Map.Entry<Id, List<Tuple<Id, Double>>> entry : this.positions.entrySet()) {
      if (vehicles.contains(entry.getKey())) {
        XYSeries series = new XYSeries("t", false, true);
        for (Tuple<Id, Double> pos : entry.getValue()) {
          Integer stopIdx = stopIndex.get(pos.getFirst());
          if (stopIdx != null) {
            double time = pos.getSecond().doubleValue();
            series.add(stopIdx.intValue(), time);
            if (time < earliestTime) {
              earliestTime = time;
            }
            if (time > latestTime) {
              latestTime = time;
            }
          }
        }
        dataset.addSeries(series);
        numSeries++;
      }
    }

    JFreeChart c =
        ChartFactory.createXYLineChart(
            "Route-Time Diagram, Route = " + route.getId(),
            "stops",
            "time",
            dataset,
            PlotOrientation.VERTICAL,
            false, // legend?
            false, // tooltips?
            false // URLs?
            );
    c.setBackgroundPaint(new Color(1.0f, 1.0f, 1.0f, 1.0f));

    XYPlot p = (XYPlot) c.getPlot();

    p.getRangeAxis().setInverted(true);
    p.getRangeAxis().setRange(earliestTime, latestTime);
    XYItemRenderer renderer = p.getRenderer();
    for (int i = 0; i < numSeries; i++) {
      renderer.setSeriesPaint(i, Color.black);
    }

    try {
      ChartUtilities.saveChartAsPNG(new File(filename), c, 1024, 768, null, true, 9);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
Example #18
0
  public TransitRouteData(Network network, TransitRoute transitRoute) {

    this.transportMode = transitRoute.getTransportMode();

    this.firstDeparture = Double.MAX_VALUE;
    this.lastDeparture = -Double.MAX_VALUE;
    this.vehIds = new TreeSet<String>();
    this.numberOfDepartures = 0;

    for (Departure departure : transitRoute.getDepartures().values()) {
      this.firstDeparture = Math.min(this.firstDeparture, departure.getDepartureTime());
      this.lastDeparture = Math.max(this.lastDeparture, departure.getDepartureTime());
      this.vehIds.add(departure.getVehicleId().toString());
      this.numberOfDepartures++;
    }

    this.firstStop = transitRoute.getStops().get(0).getStopFacility();
    this.lastStop =
        transitRoute.getStops().get(transitRoute.getStops().size() - 1).getStopFacility();

    if (this.firstStop == this.lastStop) {
      // get the stop location of stop with the largest distance between first and last stop
      TransitStopFacility currentViaStop = null;
      double currentViaDistance = Double.NEGATIVE_INFINITY;
      for (TransitRouteStop stop : transitRoute.getStops()) {
        double distanceFirstPotentialVia =
            CoordUtils.calcDistance(this.firstStop.getCoord(), stop.getStopFacility().getCoord());
        double distanceLastProtenialVia =
            CoordUtils.calcDistance(this.lastStop.getCoord(), stop.getStopFacility().getCoord());
        double newDistance =
            Math.sqrt(
                Math.pow(distanceFirstPotentialVia, 2) + Math.pow(distanceLastProtenialVia, 2));

        if (newDistance > currentViaDistance) {
          // this one is farther away - keep it
          currentViaStop = stop.getStopFacility();
          currentViaDistance = newDistance;
        }
      }
      this.viaStop = currentViaStop;
    } else {
      // get the stop in the middle of the line
      this.viaStop =
          transitRoute.getStops().get((int) (transitRoute.getStops().size() / 2)).getStopFacility();
    }

    // calculate the length of the route
    double distance = 0.0;
    double freeSpeedTravelTime = 0.0;
    for (Id<Link> linkId : transitRoute.getRoute().getLinkIds()) {
      Link link = network.getLinks().get(linkId);
      distance += link.getLength();
      freeSpeedTravelTime += link.getLength() / link.getFreespeed();
    }
    // add last link but not the first link
    Link link = network.getLinks().get(transitRoute.getRoute().getEndLinkId());
    distance += link.getLength();
    freeSpeedTravelTime += link.getLength() / link.getFreespeed();

    this.distance = distance;
    this.freeSpeedTravelTime = freeSpeedTravelTime;

    this.travelTime =
        transitRoute.getStops().get(transitRoute.getStops().size() - 1).getArrivalOffset();

    this.avgSpeed = this.distance / this.travelTime;
  }
  private void assignRoute(TransitRoute route) {

    List<Id<Link>> links = new ArrayList<>();
    int i = 0;
    while (i < (route.getStops().size())) {
      TransitRouteStop presentStop = route.getStops().get(i);
      TransitRouteStop nextStop =
          (i < route.getStops().size() - 1) ? route.getStops().get(i + 1) : null;

      if (nextStop != null) {

        // 	Case 1: For both stops a link assigned, then just route between the two.
        if (linkedStopFacilities.contains(presentStop.getStopFacility().getId())
            && linkedStopFacilities.contains(nextStop.getStopFacility().getId())) {
          links.add(presentStop.getStopFacility().getLinkId());

          Node startNode =
              this.network.getLinks().get(presentStop.getStopFacility().getLinkId()).getToNode();
          LeastCostPathCalculator.Path path = getShortestPath(startNode, nextStop);
          if (path != null) {
            for (Link link : path.links) {
              links.add(link.getId());
            }
          } else {
            Node fromNode =
                network.getLinks().get(presentStop.getStopFacility().getLinkId()).getToNode();
            Node toNode =
                network.getLinks().get(nextStop.getStopFacility().getLinkId()).getFromNode();
            Link artificialLink =
                (artificiallyAddedLinks.containsKey(new Tuple<>(fromNode, toNode)))
                    ? artificiallyAddedLinks.get(new Tuple<>(fromNode, toNode))
                    : getNewLink(fromNode, toNode);
            links.add(artificialLink.getId());
            artificiallyAddedLinks.put(new Tuple<>(fromNode, toNode), artificialLink);
          }

          // Case 2: PresentStop has no link, but NextStop has link then create link to closest
          // network node and route between that node and link of follow-stop.
        } else if (!linkedStopFacilities.contains(presentStop.getStopFacility().getId())
            && linkedStopFacilities.contains(nextStop.getStopFacility().getId())) {

          ArtificiallyConnectedStopFacility thisStopFacility =
              getArtificiallyConnectedStopFacility(presentStop.getStopFacility());
          Node toNode =
              network.getLinks().get(nextStop.getStopFacility().getLinkId()).getFromNode();

          links.add(thisStopFacility.myLink.getId());
          links.add(thisStopFacility.getLinkToNode(toNode).getId());

          // Case 3: PresentStop has link, but NextStop has no link then create link to closest
          // network node for follow stop and then route between the two.
        } else if (linkedStopFacilities.contains(presentStop.getStopFacility().getId())
            && !linkedStopFacilities.contains(nextStop.getStopFacility().getId())) {

          ArtificiallyConnectedStopFacility nextStopFacility =
              getArtificiallyConnectedStopFacility(nextStop.getStopFacility());
          Node fromNode =
              network.getLinks().get(presentStop.getStopFacility().getLinkId()).getToNode();

          links.add(presentStop.getStopFacility().getLinkId());
          links.add(nextStopFacility.getLinkFromNode(fromNode).getId());

          // Case 4: Neither PresentStop nor NextStop has link then standard link creation as with
          // Marcel's network creator.
        } else {
          ArtificiallyConnectedStopFacility thisStopFacility =
              getArtificiallyConnectedStopFacility(presentStop.getStopFacility());
          ArtificiallyConnectedStopFacility nextStopFacility =
              getArtificiallyConnectedStopFacility(nextStop.getStopFacility());

          links.add(thisStopFacility.myLink.getId());
          links.add(nextStopFacility.getLinkFromNode(thisStopFacility.myNode).getId());
        }

        // If nextStop was null, this means we have reached the end of the route and just add the
        // final link.
      } else {
        if (linkedStopFacilities.contains(presentStop.getStopFacility().getId())) {
          links.add(presentStop.getStopFacility().getLinkId());
        } else {
          ArtificiallyConnectedStopFacility thisStopFacility =
              getArtificiallyConnectedStopFacility(presentStop.getStopFacility());
          links.add(thisStopFacility.myLink.getId());
        }
      }

      i++;
    }
    if (links.size() > 0) {
      route.setRoute(RouteUtils.createNetworkRoute(links, this.network));
    } else {
      log.warn("No route found for transit route " + route.toString() + ". No route assigned.");
    }
  }
  public void testTransitRouteCopy() {
    Config config = super.loadConfig(null);
    config.scenario().setUseTransit(true);
    config.scenario().setUseVehicles(true);
    ScenarioImpl scenario = (ScenarioImpl) ScenarioUtils.createScenario(config);

    Id<Node> nodeId1 = Id.create("1", Node.class);
    Id<Node> nodeId2 = Id.create("2", Node.class);
    Id<Node> nodeId3 = Id.create("3", Node.class);
    Id<Link> linkId1 = Id.create("1", Link.class);
    Id<Link> linkId2 = Id.create("2", Link.class);

    // build network
    Network network = scenario.getNetwork();
    NetworkFactory nBuilder = network.getFactory();
    Node node1 = nBuilder.createNode(nodeId1, scenario.createCoord(0, 0));
    Node node2 = nBuilder.createNode(nodeId2, scenario.createCoord(1000, 0));
    Node node3 = nBuilder.createNode(nodeId3, scenario.createCoord(2000, 0));
    network.addNode(node1);
    network.addNode(node2);
    network.addNode(node3);
    Link link1 = nBuilder.createLink(linkId1, node1, node2);
    Link link2 = nBuilder.createLink(linkId2, node2, node3);
    network.addLink(link1);
    network.addLink(link2);

    // build schedule
    TransitSchedule schedule = scenario.getTransitSchedule();
    TransitScheduleFactory sBuilder = schedule.getFactory();

    TransitStopFacility stopF1 =
        sBuilder.createTransitStopFacility(
            Id.create("1", TransitStopFacility.class), scenario.createCoord(1000.0, 0), false);
    TransitStopFacility stopF2 =
        sBuilder.createTransitStopFacility(
            Id.create("2", TransitStopFacility.class), scenario.createCoord(2000.0, 0), false);
    stopF1.setLinkId(link1.getId());
    stopF2.setLinkId(link2.getId());
    schedule.addStopFacility(stopF1);
    schedule.addStopFacility(stopF2);

    TransitLine tLine1 = sBuilder.createTransitLine(Id.create("1", TransitLine.class));

    TransitRouteStop stop1 = sBuilder.createTransitRouteStop(stopF1, 0, 0);
    TransitRouteStop stop2 = sBuilder.createTransitRouteStop(stopF2, 100, 100);
    ArrayList<TransitRouteStop> stops = new ArrayList<TransitRouteStop>();
    stops.add(stop1);
    stops.add(stop2);

    NetworkRoute netRoute = new LinkNetworkRouteImpl(link1.getId(), link2.getId());
    netRoute.setLinkIds(link1.getId(), Collections.<Id<Link>>emptyList(), link2.getId());
    TransitRoute tRoute1 =
        sBuilder.createTransitRoute(Id.create("1", TransitRoute.class), netRoute, stops, "bus");

    tRoute1.addDeparture(sBuilder.createDeparture(Id.create("1", Departure.class), 7.0 * 3600));
    tLine1.addRoute(tRoute1);
    schedule.addTransitLine(tLine1);

    // build vehicles
    new CreateVehiclesForSchedule(schedule, scenario.getVehicles()).run();

    // build population
    Population population = scenario.getPopulation();
    PopulationFactory pBuilder = population.getFactory();
    Person person1 = pBuilder.createPerson(Id.create("1", Person.class));
    Plan plan = pBuilder.createPlan();
    Activity homeAct = pBuilder.createActivityFromLinkId("h", linkId1);
    homeAct.setEndTime(7.0 * 3600);
    plan.addActivity(homeAct);
    Leg leg = pBuilder.createLeg(TransportMode.pt);
    ExperimentalTransitRoute tRoute = new ExperimentalTransitRoute(stopF1, tLine1, tRoute1, stopF2);
    leg.setRoute(tRoute);
    plan.addLeg(leg);
    plan.addActivity(pBuilder.createActivityFromLinkId("w", linkId2));
    person1.addPlan(plan);
    population.addPerson(person1);

    // prepare config
    config.controler().setFirstIteration(0);
    config.controler().setLastIteration(1);

    ActivityParams params = new ActivityParams("h");
    params.setTypicalDuration(16.0 * 3600);
    config.planCalcScore().addActivityParams(params);
    params = new ActivityParams("w");
    params.setTypicalDuration(8.0 * 3600);
    config.planCalcScore().addActivityParams(params);

    StrategySettings tam = new StrategySettings(Id.create(1, StrategySettings.class));
    tam.setStrategyName("TimeAllocationMutator");
    tam.setWeight(1.0);
    config.strategy().addStrategySettings(tam);

    // run
    Controler controler = new Controler(scenario);
    controler.getConfig().controler().setWriteEventsInterval(0);
    controler.setCreateGraphs(false);
    controler.run();

    // checks
    assertEquals(1, population.getPersons().size());
    assertEquals(2, person1.getPlans().size());
    assertEquals(
        ExperimentalTransitRoute.class,
        ((Leg) person1.getPlans().get(0).getPlanElements().get(1)).getRoute().getClass());
    assertEquals(
        ExperimentalTransitRoute.class,
        ((Leg) person1.getPlans().get(1).getPlanElements().get(1)).getRoute().getClass());
  }
  public void testAcceptLineRoute() {
    ScenarioImpl scenario = (ScenarioImpl) ScenarioUtils.createScenario(ConfigUtils.createConfig());

    NetworkImpl network = (NetworkImpl) scenario.getNetwork();
    Node node1 = network.createAndAddNode(Id.create("1", Node.class), new CoordImpl(0, 0));
    Node node2 = network.createAndAddNode(Id.create("2", Node.class), new CoordImpl(1000, 0));
    Node node3 = network.createAndAddNode(Id.create("3", Node.class), new CoordImpl(2000, 0));
    network.createAndAddLink(Id.create("1", Link.class), node1, node2, 1000.0, 10.0, 3600.0, 1);
    network.createAndAddLink(Id.create("2", Link.class), node2, node3, 1000.0, 10.0, 3600.0, 1);

    TransitScheduleFactory builder = new TransitScheduleFactoryImpl();
    PopulationFactory pb = scenario.getPopulation().getFactory();
    Person person = pb.createPerson(Id.create("1", Person.class));
    Plan plan = pb.createPlan();
    person.addPlan(plan);
    Activity homeAct = pb.createActivityFromLinkId("home", Id.create("1", Link.class));
    Leg leg = pb.createLeg(TransportMode.pt);
    TransitStopFacility stopFacility1 =
        builder.createTransitStopFacility(
            Id.create("1", TransitStopFacility.class), scenario.createCoord(100, 100), false);
    TransitStopFacility stopFacility2 =
        builder.createTransitStopFacility(
            Id.create("2", TransitStopFacility.class), scenario.createCoord(900, 100), false);
    TransitRouteStop stop1 = builder.createTransitRouteStop(stopFacility1, 50, 60);
    TransitRouteStop stop2 = builder.createTransitRouteStop(stopFacility2, 100, 110);
    TransitLine line1 = builder.createTransitLine(Id.create("L1", TransitLine.class));
    TransitLine line2 = builder.createTransitLine(Id.create("L2", TransitLine.class));
    TransitRoute route1a =
        builder.createTransitRoute(
            Id.create("1a", TransitRoute.class),
            null,
            Arrays.asList(stop1, stop2),
            TransportMode.pt);
    TransitRoute route1b =
        builder.createTransitRoute(
            Id.create("1b", TransitRoute.class),
            null,
            Collections.<TransitRouteStop>emptyList(),
            TransportMode.pt);
    TransitRoute route2a =
        builder.createTransitRoute(
            Id.create("2a", TransitRoute.class),
            null,
            Collections.<TransitRouteStop>emptyList(),
            TransportMode.pt);
    leg.setRoute(new ExperimentalTransitRoute(stopFacility1, line1, route1a, stopFacility2));
    Activity workAct = pb.createActivityFromLinkId("work", Id.create("2", Link.class));
    plan.addActivity(homeAct);
    plan.addLeg(leg);
    plan.addActivity(workAct);

    QSim sim = (QSim) new QSimFactory().createMobsim(scenario, EventsUtils.createEventsManager());
    TransitAgent agent = TransitAgent.createTransitAgent(person, sim);
    sim.insertAgentIntoMobsim(agent);
    agent.endActivityAndComputeNextState(10);

    assertTrue(agent.getEnterTransitRoute(line1, route1a, route1a.getStops(), null));
    assertFalse(agent.getEnterTransitRoute(line1, route1b, route1b.getStops(), null));
    assertFalse(agent.getEnterTransitRoute(line2, route2a, route2a.getStops(), null));
    assertTrue(
        agent.getEnterTransitRoute(
            line1,
            route1a,
            route1a.getStops(),
            null)); // offering the same line again should yield "true"
  }
  private final void convertSchedules(
      OTTDataContainer dataContainer, ObjectAttributes trainTypes, boolean isPerformance) {
    TransitScheduleFactory scheduleFactory = scenario.getTransitSchedule().getFactory();
    VehiclesFactory vehiclesFactory = ((ScenarioImpl) scenario).getVehicles().getFactory();

    VehicleType vehicleType =
        vehiclesFactory.createVehicleType(new IdImpl(WagonSimConstants.DEFAULT_VEHICLE_TYPE));
    VehicleCapacity vehicleCapacity = vehiclesFactory.createVehicleCapacity();
    // we do not use this capacity. Therefore it should infinite, otherwise this capacity may exceed
    // before ``our'' capacities are exceeded // dr, oct'13
    vehicleCapacity.setSeats(999999);
    vehicleCapacity.setStandingRoom(999999);
    // we defined the vehicle-enter/leave-time is implicit included in transfer-times which
    // are defined in the transitrouterconfig (for handling see
    // WagonSimTripRouterFactoryImpl#WagonSimRouterWrapper)
    // dr, oct'13
    vehicleType.setAccessTime(0);
    vehicleType.setEgressTime(0);
    vehicleType.setCapacity(vehicleCapacity);
    ((ScenarioImpl) scenario).getVehicles().addVehicleType(vehicleType);

    Date startDate = extractStartDate(dataContainer, isPerformance);
    System.out.println("startDate=" + startDate.toString());

    for (Locomotive locomotive : dataContainer.locomotives.values()) {

      Departure departure = null;
      List<TransitRouteStop> transitRouteStops = new ArrayList<TransitRouteStop>();
      for (StationData stationData : locomotive.trips.values()) {

        TransitStopFacility stopFacility =
            scenario.getTransitSchedule().getFacilities().get(stationData.stationId);
        if (stopFacility == null) {
          throw new RuntimeException(
              "locomotive id="
                  + locomotive.id
                  + ": station id="
                  + stationData.stationId
                  + " not found. Bailing out.");
        }

        double arrivalDelay = Double.NaN;
        double departureDelay = Double.NaN;
        if (departure == null) {
          double lineDepartureOffset =
              (stationData.departure.getTime() - startDate.getTime()) / 1000.0;
          if (!isPerformance) {
            lineDepartureOffset -= stationData.delayDeparture;
          }
          departure = scheduleFactory.createDeparture(locomotive.id, lineDepartureOffset);
          arrivalDelay = 0.0;
        } else {
          arrivalDelay =
              (stationData.arrival.getTime() - startDate.getTime()) / 1000.0
                  - departure.getDepartureTime();
          if (!isPerformance) {
            arrivalDelay -= stationData.delayArrival;
          }
        }
        departureDelay =
            (stationData.departure.getTime() - startDate.getTime()) / 1000.0
                - departure.getDepartureTime();
        if (!isPerformance) {
          departureDelay -= stationData.delayDeparture;
        }

        if (departureDelay < arrivalDelay) {
          throw new RuntimeException(
              "locomotive id="
                  + locomotive.id
                  + ": arrival="
                  + stationData.arrival.toString()
                  + " does not fit with departure="
                  + stationData.departure.toString()
                  + ". ("
                  + departureDelay
                  + "<"
                  + arrivalDelay
                  + ") Bailing out.");
        }

        TransitRouteStop stop =
            scheduleFactory.createTransitRouteStop(stopFacility, arrivalDelay, departureDelay);
        stop.setAwaitDepartureTime(true);
        transitRouteStops.add(stop);
      }

      if (transitRouteStops.size() > 1) {

        // check if train type is given
        if (trainTypes.getAttribute(locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_SPEED)
            == null) {
          throw new RuntimeException(
              "locomotive id="
                  + locomotive.id
                  + ": type="
                  + locomotive.type
                  + " is not defined by the train type table. Bailing out.");
        }

        TransitLine line = scheduleFactory.createTransitLine(locomotive.id);
        scenario.getTransitSchedule().addTransitLine(line);
        TransitRoute route =
            scheduleFactory.createTransitRoute(
                line.getId(), null, transitRouteStops, TransportMode.pt);
        line.addRoute(route);

        Vehicle vehicle = vehiclesFactory.createVehicle(route.getId(), vehicleType);
        ((ScenarioImpl) scenario).getVehicles().addVehicle(vehicle);
        departure.setVehicleId(vehicle.getId());
        route.addDeparture(departure);
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(), WagonSimConstants.TRAIN_TYPE, locomotive.type);
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_SPEED,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_SPEED));
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_WEIGHT,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_WEIGHT));
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_LENGTH,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_LENGTH));

        // the next day
        vehicle = vehiclesFactory.createVehicle(new IdImpl(route.getId() + ".1"), vehicleType);
        ((ScenarioImpl) scenario).getVehicles().addVehicle(vehicle);
        departure =
            scheduleFactory.createDeparture(
                vehicle.getId(), departure.getDepartureTime() + 24 * 3600);
        departure.setVehicleId(vehicle.getId());
        route.addDeparture(departure);
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(), WagonSimConstants.TRAIN_TYPE, locomotive.type);
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_SPEED,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_SPEED));
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_WEIGHT,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_WEIGHT));
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_LENGTH,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_LENGTH));

        // the day after the next day
        vehicle = vehiclesFactory.createVehicle(new IdImpl(route.getId() + ".2"), vehicleType);
        ((ScenarioImpl) scenario).getVehicles().addVehicle(vehicle);
        departure =
            scheduleFactory.createDeparture(
                vehicle.getId(), departure.getDepartureTime() + 24 * 3600);
        departure.setVehicleId(vehicle.getId());
        route.addDeparture(departure);
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(), WagonSimConstants.TRAIN_TYPE, locomotive.type);
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_SPEED,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_SPEED));
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_WEIGHT,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_WEIGHT));
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_LENGTH,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_LENGTH));
      } else if (transitRouteStops.size() == 1) {
        System.out.println(
            "locomotive id="
                + locomotive.id
                + ": only one station given. Therefore, no transitLine created.");
      } else {
        System.out.println(
            "locomotive id="
                + locomotive.id
                + ": no station is given. Therefore, no transitLine created.");
      }
    }
  }