private void startAct(final Attributes atts) {
    ActivityImpl act = null;
    if (atts.getValue("link") != null) {
      final Id<Link> linkId = Id.create(atts.getValue("link"), Link.class);
      act = this.currplan.createAndAddActivity(atts.getValue("type"), linkId);
      if (atts.getValue(ATTR_X100) != null && atts.getValue(ATTR_Y100) != null) {
        final Coord coord = parseCoord(atts);
        act.setCoord(coord);
      }
    } else if (atts.getValue(ATTR_X100) != null && atts.getValue(ATTR_Y100) != null) {
      final Coord coord = parseCoord(atts);
      act = this.currplan.createAndAddActivity(atts.getValue("type"), coord);
    } else {
      throw new IllegalArgumentException(
          "Either the coords or the link must be specified for an Act.");
    }
    act.setStartTime(Time.parseTime(atts.getValue("start_time")));
    act.setMaximumDuration(Time.parseTime(atts.getValue("dur")));
    act.setEndTime(Time.parseTime(atts.getValue("end_time")));

    if (this.routeNodes != null) {
      this.currroute.setLinkIds(
          this.prevAct.getLinkId(),
          NetworkUtils.getLinkIds(
              RouteUtils.getLinksFromNodes(NetworkUtils.getNodes(this.network, this.routeNodes))),
          act.getLinkId());
      this.routeNodes = null;
      this.currroute = null;
    }
    this.prevAct = act;
  }
 private void startAct(final Attributes atts) {
   Coord coord = null;
   if (atts.getValue("link") != null) {
     Id<Link> linkId = Id.create(atts.getValue("link"), Link.class);
     this.curract = this.currplan.createAndAddActivity(atts.getValue(ATTR_TYPE), linkId);
     if ((atts.getValue("x") != null) && (atts.getValue("y") != null)) {
       coord =
           new Coord(
               Double.parseDouble(atts.getValue("x")), Double.parseDouble(atts.getValue("y")));
       this.curract.setCoord(coord);
     }
   } else if ((atts.getValue("x") != null) && (atts.getValue("y") != null)) {
     coord =
         new Coord(Double.parseDouble(atts.getValue("x")), Double.parseDouble(atts.getValue("y")));
     this.curract = this.currplan.createAndAddActivity(atts.getValue(ATTR_TYPE), coord);
   } else {
     throw new IllegalArgumentException(
         "In this version of MATSim either the coords or the link must be specified for an Act.");
   }
   this.curract.setStartTime(Time.parseTime(atts.getValue("start_time")));
   this.curract.setMaximumDuration(Time.parseTime(atts.getValue("dur")));
   this.curract.setEndTime(Time.parseTime(atts.getValue("end_time")));
   String fId = atts.getValue("facility");
   if (fId != null) {
     this.curract.setFacilityId(Id.create(fId, ActivityFacility.class));
   }
   if (this.routeDescription != null) {
     Id<Link> startLinkId = null;
     if (this.prevAct.getLinkId() != null) {
       startLinkId = this.prevAct.getLinkId();
     }
     Id<Link> endLinkId = null;
     if (this.curract.getLinkId() != null) {
       endLinkId = this.curract.getLinkId();
     }
     this.currRoute.setStartLinkId(startLinkId);
     this.currRoute.setEndLinkId(endLinkId);
     if (this.currRoute instanceof NetworkRoute) {
       ((NetworkRoute) this.currRoute)
           .setLinkIds(
               startLinkId,
               NetworkUtils.getLinkIds(
                   RouteUtils.getLinksFromNodes(
                       NetworkUtils.getNodes(this.network, this.routeDescription))),
               endLinkId);
     } else {
       this.currRoute.setRouteDescription(this.routeDescription.trim());
     }
     this.routeDescription = null;
     this.currRoute = null;
   }
 }
    public Fixture() {
      firstLegStartTime = 7 * 3600;
      firstLegTravelTime = 30 * 60;
      thirdLegTravelTime = 30 * 60;
      secondLegStartTime = 10 * 3600;
      secondLegTravelTime = 15 * 60;
      thirdLegStartTime = 13 * 3600;
      fourthLegStartTime = 16 * 3600;
      fourthLegTravelTime = 15 * 60;
      // home act end 7am
      // work 7:30 to 10:00
      // work 10:15 to 13:00
      // work 13:30 to 16:00
      // home 15:15 to ...

      this.config = ConfigUtils.createConfig();
      PlanCalcScoreConfigGroup scoring = this.config.planCalcScore();
      scoring.setBrainExpBeta(2.0);

      scoring.setConstantCar(0.0);
      scoring.setConstantPt(0.0);
      scoring.setConstantWalk(0.0);
      scoring.setConstantBike(0.0);

      scoring.setEarlyDeparture_utils_hr(0.0);
      scoring.setLateArrival_utils_hr(0.0);
      scoring.setMarginalUtlOfWaiting_utils_hr(0.0);
      scoring.setPerforming_utils_hr(0.0);
      scoring.setTraveling_utils_hr(0.0);
      scoring.setTravelingPt_utils_hr(0.0);
      scoring.setTravelingWalk_utils_hr(0.0);
      scoring.setTravelingBike_utils_hr(0.0);

      scoring.setMarginalUtilityOfMoney(1.);
      scoring.setMonetaryDistanceCostRateCar(0.0);
      scoring.setMonetaryDistanceCostRatePt(0.0);

      // setup activity types h and w for scoring
      PlanCalcScoreConfigGroup.ActivityParams params =
          new PlanCalcScoreConfigGroup.ActivityParams("h");
      params.setTypicalDuration(15 * 3600);
      scoring.addActivityParams(params);

      params = new PlanCalcScoreConfigGroup.ActivityParams("w");
      params.setTypicalDuration(3 * 3600);
      scoring.addActivityParams(params);

      this.scenario = ScenarioUtils.createScenario(config);
      this.network = (NetworkImpl) this.scenario.getNetwork();
      Node node1 =
          this.network.createAndAddNode(Id.create("1", Node.class), new CoordImpl(0.0, 0.0));
      Node node2 =
          this.network.createAndAddNode(Id.create("2", Node.class), new CoordImpl(500.0, 0.0));
      Node node3 =
          this.network.createAndAddNode(Id.create("3", Node.class), new CoordImpl(5500.0, 0.0));
      Node node4 =
          this.network.createAndAddNode(Id.create("4", Node.class), new CoordImpl(6000.0, 0.0));
      Node node5 =
          this.network.createAndAddNode(Id.create("5", Node.class), new CoordImpl(11000.0, 0.0));
      Node node6 =
          this.network.createAndAddNode(Id.create("6", Node.class), new CoordImpl(11500.0, 0.0));
      Node node7 =
          this.network.createAndAddNode(Id.create("7", Node.class), new CoordImpl(16500.0, 0.0));
      Node node8 =
          this.network.createAndAddNode(Id.create("8", Node.class), new CoordImpl(17000.0, 0.0));
      Node node9 =
          this.network.createAndAddNode(Id.create("9", Node.class), new CoordImpl(22000.0, 0.0));
      Node node10 =
          this.network.createAndAddNode(Id.create("10", Node.class), new CoordImpl(22500.0, 0.0));

      Link link1 =
          this.network.createAndAddLink(Id.create("1", Link.class), node1, node2, 500, 25, 3600, 1);
      Link link2 =
          this.network.createAndAddLink(
              Id.create("2", Link.class), node2, node3, 25000, 50, 3600, 1);
      Link link3 =
          this.network.createAndAddLink(Id.create("3", Link.class), node3, node4, 500, 25, 3600, 1);
      this.network.createAndAddLink(Id.create("4", Link.class), node4, node5, 5000, 50, 3600, 1);
      Link link5 =
          this.network.createAndAddLink(Id.create("5", Link.class), node5, node6, 500, 25, 3600, 1);
      this.network.createAndAddLink(Id.create("6", Link.class), node6, node7, 5000, 50, 3600, 1);
      Link link7 =
          this.network.createAndAddLink(Id.create("7", Link.class), node7, node8, 500, 25, 3600, 1);
      this.network.createAndAddLink(Id.create("8", Link.class), node8, node9, 5000, 50, 3600, 1);
      Link link9 =
          this.network.createAndAddLink(
              Id.create("9", Link.class), node9, node10, 500, 25, 3600, 1);

      this.person = new PersonImpl(Id.create("1", Person.class));
      this.plan = this.person.createAndAddPlan(true);

      ActivityImpl firstActivity = this.plan.createAndAddActivity("h", link1.getId());
      firstActivity.setEndTime(firstLegStartTime);

      Leg leg = this.plan.createAndAddLeg(TransportMode.car);
      leg.setDepartureTime(firstLegStartTime);
      leg.setTravelTime(firstLegTravelTime);
      NetworkRoute route1 = new LinkNetworkRouteImpl(link1.getId(), link3.getId());
      route1.setLinkIds(link1.getId(), Arrays.asList(link2.getId()), link3.getId());
      route1.setTravelTime(firstLegTravelTime);
      route1.setDistance(RouteUtils.calcDistance(route1, this.network));
      leg.setRoute(route1);

      ActivityImpl secondActivity = this.plan.createAndAddActivity("w", link3.getId());
      secondActivity.setStartTime(firstLegStartTime + firstLegTravelTime);
      secondActivity.setEndTime(secondLegStartTime);
      leg = this.plan.createAndAddLeg(TransportMode.pt);
      leg.setDepartureTime(secondLegStartTime);
      leg.setTravelTime(secondLegTravelTime);
      Route route2 = new GenericRouteImpl(link3.getId(), link5.getId());
      route2.setTravelTime(secondLegTravelTime);
      route2.setDistance(20000.0);
      leg.setRoute(route2);

      ActivityImpl thirdActivity = this.plan.createAndAddActivity("w", link5.getId());
      thirdActivity.setStartTime(secondLegStartTime + secondLegTravelTime);
      thirdActivity.setEndTime(thirdLegStartTime);
      leg = this.plan.createAndAddLeg(TransportMode.walk);
      leg.setDepartureTime(thirdLegStartTime);
      leg.setTravelTime(thirdLegTravelTime);
      Route route3 = new GenericRouteImpl(link5.getId(), link7.getId());
      route3.setTravelTime(thirdLegTravelTime);
      route3.setDistance(CoordUtils.calcDistance(link5.getCoord(), link7.getCoord()));
      leg.setRoute(route3);

      ActivityImpl fourthActivity = this.plan.createAndAddActivity("w", link7.getId());
      fourthActivity.setStartTime(thirdLegStartTime + thirdLegTravelTime);
      fourthActivity.setEndTime(fourthLegStartTime);
      leg = this.plan.createAndAddLeg(TransportMode.bike);
      leg.setDepartureTime(fourthLegStartTime);
      leg.setTravelTime(fourthLegTravelTime);
      Route route4 = new GenericRouteImpl(link7.getId(), link9.getId());
      route4.setTravelTime(fourthLegTravelTime);
      route4.setDistance(CoordUtils.calcDistance(link7.getCoord(), link9.getCoord()));
      leg.setRoute(route4);

      ActivityImpl fifthActivity = this.plan.createAndAddActivity("h", link9.getId());
      fifthActivity.setStartTime(fourthLegStartTime + fourthLegTravelTime);
      this.scenario.getPopulation().addPerson(this.person);
    }
  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.");
    }
  }
  private void analyzeResults(List<Leg> toLegs, List<Leg> fromLegs, String activityType) {

    List<Leg> toLegsPt = new ArrayList<Leg>();
    List<Leg> toLegsCar = new ArrayList<Leg>();
    List<Leg> toLegsUndefined = new ArrayList<Leg>();
    List<Leg> fromLegsPt = new ArrayList<Leg>();
    List<Leg> fromLegsCar = new ArrayList<Leg>();
    List<Leg> fromLegsUndefined = new ArrayList<Leg>();

    for (Leg leg : toLegs) {
      if (leg.getMode().equals(TransportMode.car)) toLegsCar.add(leg);
      else if (leg.getMode().equals(TransportMode.pt)) toLegsPt.add(leg);
      else toLegsUndefined.add(leg);
    }
    for (Leg leg : fromLegs) {
      if (leg.getMode().equals(TransportMode.car)) fromLegsCar.add(leg);
      else if (leg.getMode().equals(TransportMode.pt)) fromLegsPt.add(leg);
      else fromLegsUndefined.add(leg);
    }

    //		double toTravelTimesPt = 0.0;
    double toTravelTimesCar = 0.0;
    //		double toTravelTimesUndefined = 0.0;

    //		double toDistancesPt = 0.0;
    double toDistancesCar = 0.0;
    //		double toDistancesUndefined = 0.0;

    //		double fromTravelTimesPt = 0.0;
    double fromTravelTimesCar = 0.0;
    //		double fromTravelTimesUndefined = 0.0;

    //		double fromDistancesPt = 0.0;
    double fromDistancesCar = 0.0;
    //		double fromDistancesUndefined = 0.0;

    //		for (Leg leg : toLegsPt) {
    //			toTravelTimesPt = toTravelTimesPt + leg.getTravelTime();
    //			toDistancesPt = toDistancesPt + RouteUtils.calcDistance((NetworkRoute)leg.getRoute(),
    // scenario.getNetwork());
    //		}
    log.info("number of " + activityType + "-to-legsPt = " + toLegsPt.size());
    //		log.info("mean " + activityType + "-to-traveltimesPt = " + toTravelTimesPt /
    // toLegsPt.size());
    //		log.info("mean " + activityType + "-to-distancesPt = " + toDistancesPt / toLegsPt.size());
    log.info("");

    for (Leg leg : toLegsCar) {
      toTravelTimesCar = toTravelTimesCar + leg.getTravelTime();
      toDistancesCar =
          toDistancesCar
              + RouteUtils.calcDistanceExcludingStartEndLink(
                  (NetworkRoute) leg.getRoute(), scenario.getNetwork());
    }
    log.info("number of " + activityType + "-to-legsCar = " + toLegsCar.size());
    log.info(
        "mean " + activityType + "-to-traveltimesCar = " + toTravelTimesCar / toLegsCar.size());
    log.info("mean " + activityType + "-to-distancesCar = " + toDistancesCar / toLegsCar.size());
    log.info("");

    //		for (Leg leg : toLegsUndefined) {
    //			toTravelTimesUndefined = toTravelTimesUndefined + leg.getTravelTime();
    //			toDistancesUndefined = toDistancesUndefined +
    // RouteUtils.calcDistance((NetworkRoute)leg.getRoute(), scenario.getNetwork());
    //		}
    log.info("number of " + activityType + "-to-legsUndefined = " + toLegsUndefined.size());
    //		log.info("mean " + activityType + "-to-traveltimesUndefined = " + toTravelTimesUndefined /
    // toLegsUndefined.size());
    //		log.info("mean " + activityType + "-to-distancesUndefined = " + toDistancesUndefined /
    // toLegsUndefined.size());
    log.info("");

    //		for (Leg leg : fromLegsPt) {
    //			fromTravelTimesPt = fromTravelTimesPt + leg.getTravelTime();
    //			fromDistancesPt = fromDistancesPt + RouteUtils.calcDistance((NetworkRoute)leg.getRoute(),
    // scenario.getNetwork());
    //		}
    log.info("number of " + activityType + "-from-legsPt = " + fromLegsPt.size());
    //		log.info("mean " + activityType + "-from-traveltimesPt = " + fromTravelTimesPt /
    // fromLegsPt.size());
    //		log.info("mean " + activityType + "-from-distancesPt = " + fromDistancesPt /
    // fromLegsPt.size());
    log.info("");

    for (Leg leg : fromLegsCar) {
      fromTravelTimesCar = fromTravelTimesCar + leg.getTravelTime();
      fromDistancesCar =
          fromDistancesCar
              + RouteUtils.calcDistanceExcludingStartEndLink(
                  (NetworkRoute) leg.getRoute(), scenario.getNetwork());
    }

    log.info("number of " + activityType + "-from-legsCar = " + fromLegsCar.size());
    log.info(
        "mean "
            + activityType
            + "-from-traveltimesCar = "
            + fromTravelTimesCar / fromLegsCar.size());
    log.info(
        "mean " + activityType + "-from-distancesCar = " + fromDistancesCar / fromLegsCar.size());
    log.info("");

    //		for (Leg leg : fromLegsUndefined) {
    //			fromTravelTimesUndefined = fromTravelTimesUndefined + leg.getTravelTime();
    //			fromDistancesUndefined = fromDistancesUndefined +
    // RouteUtils.calcDistance((NetworkRoute)leg.getRoute(), scenario.getNetwork());
    //		}
    log.info("number of " + activityType + "-from-legsUndefined = " + fromLegsUndefined.size());
    //		log.info("mean " + activityType + "-from-traveltimesUndefined = " + fromTravelTimesUndefined
    // / fromLegsUndefined.size());
    //		log.info("mean " + activityType + "-from-distancesUndefined = " + fromDistancesUndefined /
    // fromLegsUndefined.size());
    log.info("");
  }