public static int getDepartureParkingActIndex(Plan plan, ActivityImpl activity) { List<PlanElement> pe = plan.getPlanElements(); int activityIndex = pe.indexOf(activity); int indexOfDepartingParkingAct = -1; for (int i = activityIndex; i < pe.size(); i++) { if (pe.get(i) instanceof ActivityImpl) { ActivityImpl parkingAct = (ActivityImpl) plan.getPlanElements().get(i); if (parkingAct.getType().equalsIgnoreCase("parking")) { indexOfDepartingParkingAct = i; break; } } } // if home parking if (indexOfDepartingParkingAct == -1) { for (int i = 0; i < pe.size(); i++) { if (pe.get(i) instanceof ActivityImpl) { ActivityImpl parkingAct = (ActivityImpl) plan.getPlanElements().get(i); if (parkingAct.getType().equalsIgnoreCase("parking")) { indexOfDepartingParkingAct = i; break; } } } } if (indexOfDepartingParkingAct == -1) { throw new Error("plan wrong: no parking in the whole plan"); } return indexOfDepartingParkingAct; }
/** * reurns null, if no parking activity found else id of first parking facility * * @param plan * @return */ public static Id<ActivityFacility> getFirstParkingFacilityId(Plan plan) { for (int i = 0; i < plan.getPlanElements().size(); i++) { if (plan.getPlanElements().get(i) instanceof ActivityImpl) { ActivityImpl activity = (ActivityImpl) plan.getPlanElements().get(i); if (activity.getType().equalsIgnoreCase("parking")) { return activity.getFacilityId(); } } } return null; }
@Override public void run(Person person) { Integer p_id = Integer.valueOf(person.getId().toString()); Coord coord = persons.getPerson(p_id).getHousehold().getCoord(); ActivityFacility f = this.homeFacQuadTree.get(coord.getX(), coord.getY()); Plan plan = person.getSelectedPlan(); for (PlanElement pe : plan.getPlanElements()) { if (pe instanceof ActivityImpl) { ActivityImpl act = (ActivityImpl) pe; if (H.equals(act.getType())) { act.setCoord(f.getCoord()); } } } }
/** * get parking related walking distance of whole day - average per leg * * @param plan * @param facilities * @return */ public static double getParkingRelatedWalkingDistanceOfWholeDayAveragePerLeg( Plan plan, ActivityFacilities facilities) { double travelDistance = 0; int numberOfLegs = 0; List<PlanElement> pe = plan.getPlanElements(); for (int i = 0; i < pe.size(); i++) { if (pe.get(i) instanceof ActivityImpl) { ActivityImpl parkingActivity = (ActivityImpl) pe.get(i); if (parkingActivity.getType().equalsIgnoreCase("parking")) { Coord coordParking = facilities.getFacilities().get(parkingActivity.getFacilityId()).getCoord(); Leg nextLeg = (Leg) pe.get(i + 1); Leg prevLeg = (Leg) pe.get(i - 1); if (nextLeg.getMode().equalsIgnoreCase("walk")) { ActivityImpl nextAct = (ActivityImpl) pe.get(i + 2); if (nextAct.getFacilityId() != null) { Coord nextActFacilityCoord = facilities.getFacilities().get(nextAct.getFacilityId()).getCoord(); travelDistance += GeneralLib.getDistance(coordParking, nextActFacilityCoord); } else { Coord nextActLinkCoord = nextAct.getCoord(); travelDistance += GeneralLib.getDistance(coordParking, nextActLinkCoord); } numberOfLegs++; } if (prevLeg.getMode().equalsIgnoreCase("walk")) { ActivityImpl prevAct = (ActivityImpl) pe.get(i - 2); if (prevAct.getFacilityId() != null) { Coord prevActFacilityCoord = facilities.getFacilities().get(prevAct.getFacilityId()).getCoord(); travelDistance += GeneralLib.getDistance(coordParking, prevActFacilityCoord); } else { Coord prevActLinkCoord = prevAct.getCoord(); travelDistance += GeneralLib.getDistance(coordParking, prevActLinkCoord); } numberOfLegs++; } } } } return travelDistance / numberOfLegs; }
/** * TODO: add test. If the specified arrival is the i-th arrival of the day, return i (with i * starting at 0). * * @param plan * @param parkingArrivalAct * @return */ public static int getParkingArrivalIndex(Plan plan, ActivityImpl parkingArrivalAct) { List<PlanElement> pe = plan.getPlanElements(); int parkingPlanElementIndex = pe.indexOf(parkingArrivalAct); int index = -1; for (int i = 0; i <= parkingPlanElementIndex; i++) { if (pe.get(i) instanceof ActivityImpl) { ActivityImpl activity = (ActivityImpl) plan.getPlanElements().get(i); if (activity.getType().equalsIgnoreCase("parking")) { Leg leg = (Leg) plan.getPlanElements().get(i - 1); if (leg.getMode().equalsIgnoreCase("car")) { index++; } } } } return index; }
public static int getArrivalParkingActIndex(Plan plan, ActivityImpl activity) { List<PlanElement> pe = plan.getPlanElements(); int activityIndex = pe.indexOf(activity); int indexOfArrivalParkingAct = -1; for (int i = activityIndex; 0 < i; i--) { if (pe.get(i) instanceof ActivityImpl) { ActivityImpl parkingAct = (ActivityImpl) plan.getPlanElements().get(i); if (parkingAct.getType().equalsIgnoreCase("parking")) { indexOfArrivalParkingAct = i; break; } } } if (indexOfArrivalParkingAct == -1) { throw new Error("no parking arrival activity found - something is wrong with the plan"); } return indexOfArrivalParkingAct; }
/** * get the first activity after each arrival at a parking. * * @param plan * @return */ public static LinkedList<ActivityImpl> getParkingTargetActivities(Plan plan) { LinkedList<ActivityImpl> list = new LinkedList<ActivityImpl>(); for (int i = 0; i < plan.getPlanElements().size(); i++) { if (plan.getPlanElements().get(i) instanceof ActivityImpl) { ActivityImpl activity = (ActivityImpl) plan.getPlanElements().get(i); if (activity.getType().equalsIgnoreCase("parking")) { Leg leg = (Leg) plan.getPlanElements().get(i - 1); if (leg.getMode().equalsIgnoreCase("car")) { // parking arrival pattern recognized. ActivityImpl targetActivity = (ActivityImpl) plan.getPlanElements().get(i + 2); list.add(targetActivity); } } } } return list; }
/** * The home/first parking comes last (because it is the last parking arrival of the day). * * @param plan * @return */ public static LinkedList<Id<ActivityFacility>> getAllParkingFacilityIds(Plan plan) { LinkedList<Id<ActivityFacility>> parkingFacilityIds = new LinkedList<>(); // recognize parking arrival patterns (this means, there is car leg // after which there is // a parking activity). for (int i = 0; i < plan.getPlanElements().size(); i++) { if (plan.getPlanElements().get(i) instanceof ActivityImpl) { ActivityImpl activity = (ActivityImpl) plan.getPlanElements().get(i); if (activity.getType().equalsIgnoreCase("parking")) { Leg leg = (Leg) plan.getPlanElements().get(i - 1); if (leg.getMode().equalsIgnoreCase("car")) { parkingFacilityIds.add(activity.getFacilityId()); } } } } return parkingFacilityIds; }
public void cleanUpScenario(Scenario sc) { LOG.info("Cleaning up scenario..."); /* TODO Still need to figure out what cleaning up must happen. */ /* Search for location-less activities, and sample its locations from * the kernel density estimates. */ LOG.info("Sampling locations for those without known zones..."); int locationsFixed = 0; int knownLocations = 0; for (Person person : sc.getPopulation().getPersons().values()) { Plan plan = person.getSelectedPlan(); if (plan != null) { for (PlanElement pe : plan.getPlanElements()) { if (pe instanceof Activity) { Activity act = (Activity) pe; Coord coord = act.getCoord(); if (coord.getX() == 0.0 || coord.getY() == 0.0) { ((ActivityImpl) act).setCoord(sampleActivityLocation(act.getType())); locationsFixed++; } else { knownLocations++; } } } } } LOG.info("Number of known locations: " + knownLocations); LOG.info("Number of locations fixed: " + locationsFixed); LOG.info("Done sampling locations."); /* Ensure each activity, except the last, has both a start and end time. */ LOG.info("Ensure each activity has an end time..."); for (Person person : sc.getPopulation().getPersons().values()) { Plan plan = person.getSelectedPlan(); if (plan != null) { List<PlanElement> list = plan.getPlanElements(); for (int i = 0; i < list.size() - 2; i += 2) { PlanElement pe = list.get(i); if (pe instanceof Activity) { Activity act = (Activity) pe; double endTime = act.getEndTime(); if (endTime < 0.0) { double legStart = ((Leg) list.get(i + 1)).getDepartureTime(); act.setEndTime(legStart); } } else { LOG.warn("Every second PlanElement should be of type 'Activity'."); } } } } LOG.info("Done fixing activity end times."); /* Ensure that the home location/coordinate for all members in the * household are the same for all their "h" activities. */ LOG.info("Fix home locations for each household member. "); int homeLocationsFixed = 0; int nonTravellers = 0; for (Household hh : sc.getHouseholds().getHouseholds().values()) { Object o = sc.getHouseholds() .getHouseholdAttributes() .getAttribute(hh.getId().toString(), "transportZone"); if (o instanceof String) { String zoneId = (String) o; Coord homeCoord = null; if (zoneId != null && !zoneId.equalsIgnoreCase("")) { /* There is known home zone. */ Point p = this.zoneMap.get(zoneId).sampleRandomInteriorPoint(); homeCoord = CoordUtils.createCoord(p.getX(), p.getY()); } else { /* There is no transport zone. */ homeCoord = sampleActivityLocation("h"); } /* Now assign the home coordinate to ALL home activities for * all members of the household. */ for (Id<Person> id : hh.getMemberIds()) { Person person = sc.getPopulation().getPersons().get(id); Plan plan = person.getSelectedPlan(); if (plan != null) { for (PlanElement pe : person.getSelectedPlan().getPlanElements()) { if (pe instanceof ActivityImpl) { ActivityImpl act = (ActivityImpl) pe; if (act.getType().equalsIgnoreCase("h")) { act.setCoord(homeCoord); homeLocationsFixed++; } } } } else { /* The member does not have ANY plan. We 'fix' this by * adding aPlan with a single home-based activity for * which not times are specified. */ Plan stayHomePlan = sc.getPopulation().getFactory().createPlan(); Activity act = sc.getPopulation().getFactory().createActivityFromCoord("h", homeCoord); stayHomePlan.addActivity(act); person.addPlan(stayHomePlan); nonTravellers++; } } } } LOG.info("Total number of home locations fixed: " + homeLocationsFixed); LOG.info(" Total number of non-travellers: " + nonTravellers); LOG.info("Done fixing home locations."); /* TODO Check what to do with those household members that are not * travelling. Are they just given a single 'h' activities, and * left at that? */ /* Look for erroneous activity times that can/should be fixed in * the raw travel diary input data. This will typically include very * long activity times or leg durations. */ LOG.info("Checking leg durations:"); int remainingLegOddities = 0; double legDurationThreshold = Time.parseTime("03:00:00"); for (Person p : sc.getPopulation().getPersons().values()) { Plan plan = p.getSelectedPlan(); if (plan != null) { for (PlanElement pe : plan.getPlanElements()) { if (pe instanceof Leg) { double duration = ((Leg) pe).getTravelTime(); if (duration < 0 || duration > legDurationThreshold) { LOG.warn( " -> Odd leg duration: " + p.getId().toString() + " (" + Time.writeTime(duration) + ")"); remainingLegOddities++; } } } } } LOG.info("Done checking leg durations. (" + remainingLegOddities + " remain)"); /* Parse the activity duration times in an effort to pick up * erroneous travel time data that results in negative activity * durations. Then fix in input data. */ LOG.info("Checking activity durations (from leg times):"); int remainingActivityOddities = 0; double activityDurationThreshold = Time.parseTime("16:00:00"); for (Person p : sc.getPopulation().getPersons().values()) { Plan plan = p.getSelectedPlan(); if (plan != null) { for (int i = 1; i < plan.getPlanElements().size() - 2; i += 2) { PlanElement pe1 = plan.getPlanElements().get(i); PlanElement pe2 = plan.getPlanElements().get(i + 2); if (pe1 instanceof Leg && pe2 instanceof Leg) { Leg l1 = (Leg) pe1; Leg l2 = (Leg) pe2; double act = l2.getDepartureTime() - (l1.getDepartureTime() + l1.getTravelTime()); if (act < 0 || act > activityDurationThreshold) { LOG.warn( " -> Odd activity duration: " + p.getId().toString() + " (" + Time.writeTime(act) + ")"); remainingActivityOddities++; } } else { LOG.error("PlanElements not of type Leg!!"); LOG.error(" pe1: " + pe1.getClass().toString()); LOG.error(" pe2: " + pe2.getClass().toString()); } } } } LOG.info("Done checking activity durations. (" + remainingActivityOddities + " remain)"); /* TODO Fix plans for night workers. They typically start with 'h', * but should actually start with 'w'. */ /* TODO Consider what to do with repeating activities, especially * consecutive home activities. */ /* Convert all activity locations to a projected coordinate system. */ LOG.info("Converting all activity locations to EPSG:3857..."); CoordinateTransformation ct = TransformationFactory.getCoordinateTransformation("WGS84", "EPSG:3857"); for (Person person : sc.getPopulation().getPersons().values()) { Plan plan = person.getSelectedPlan(); if (plan != null) { for (PlanElement pe : plan.getPlanElements()) { if (pe instanceof Activity) { Activity act = (Activity) pe; ((ActivityImpl) act).setCoord(ct.transform(act.getCoord())); } } } } LOG.info("Done converting activity locations."); LOG.info("Done cleaning up scenario."); }