diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/NearestParkingDynLeg.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/NearestParkingDynLeg.java
index 96bbd7928c5..a5f4cdcf143 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/NearestParkingDynLeg.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/NearestParkingDynLeg.java
@@ -1,20 +1,21 @@
package org.matsim.contrib.parking.parkingsearch.DynAgent;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.population.Activity;
import org.matsim.api.core.v01.population.Leg;
import org.matsim.api.core.v01.population.Plan;
-import org.matsim.contrib.parking.parkingsearch.events.RemoveParkingActivityEvent;
-import org.matsim.contrib.parking.parkingsearch.events.ReserveParkingLocationEvent;
-import org.matsim.contrib.parking.parkingsearch.events.SelectNewParkingLocationEvent;
-import org.matsim.contrib.parking.parkingsearch.events.StartParkingSearchEvent;
+import org.matsim.contrib.parking.parkingsearch.ParkingUtils;
+import org.matsim.contrib.parking.parkingsearch.events.*;
import org.matsim.contrib.parking.parkingsearch.manager.FacilityBasedParkingManager;
import org.matsim.contrib.parking.parkingsearch.manager.ParkingSearchManager;
import org.matsim.contrib.parking.parkingsearch.search.NearestParkingSpotSearchLogic;
import org.matsim.contrib.parking.parkingsearch.search.ParkingSearchLogic;
import org.matsim.core.api.experimental.events.EventsManager;
import org.matsim.core.mobsim.framework.MobsimTimer;
+import org.matsim.core.population.PopulationUtils;
import org.matsim.core.population.routes.NetworkRoute;
import org.matsim.core.utils.collections.Tuple;
import org.matsim.vehicles.Vehicle;
@@ -26,6 +27,7 @@
*/
public class NearestParkingDynLeg extends ParkingDynLeg {
private boolean parkingAtEndOfLeg = true;
+ private boolean passangerInteractionAtParkingFacilityAtEndOfLeg = false;
private boolean reachedDestinationWithoutParking = false;
private boolean alreadyReservedParking = false;
private boolean driveToBaseWithoutParking = false;
@@ -34,18 +36,19 @@ public class NearestParkingDynLeg extends ParkingDynLeg {
private final int planIndexNextActivity;
private Plan plan;
private Id nextSelectedParkingLink = null;
+ protected static final Logger log = LogManager.getLogger(NearestParkingDynLeg.class);
public NearestParkingDynLeg(Leg currentPlannedLeg, NetworkRoute route, Plan plan, int planIndexNextActivity, ParkingSearchLogic logic,
ParkingSearchManager parkingManager, Id vehicleId, MobsimTimer timer, EventsManager events) {
super(currentPlannedLeg.getMode(), route, logic, parkingManager, vehicleId, timer, events);
this.followingActivity = (Activity) plan.getPlanElements().get(planIndexNextActivity);
- followingActivity.setStartTime(timer.getTimeOfDay());
this.currentPlannedLeg = currentPlannedLeg;
this.plan = plan;
this.planIndexNextActivity = planIndexNextActivity;
- if (followingActivity.getAttributes().getAsMap().containsKey("parking") && followingActivity.getAttributes().getAttribute("parking").equals(
- "noParking"))
+ if (ParkingUtils.checkIfActivityHasNoParking(followingActivity))
parkingAtEndOfLeg = false;
+ if (ParkingUtils.checkIfActivityHasPassengerInteraction(followingActivity))
+ passangerInteractionAtParkingFacilityAtEndOfLeg = true;
}
@Override
@@ -85,7 +88,7 @@ public void movedOverNode(Id newLinkId) {
@Override
public Id getNextLinkId() {
- if (!parkingMode && parkingAtEndOfLeg) {
+ if (!passangerInteractionAtParkingFacilityAtEndOfLeg && (!parkingMode && parkingAtEndOfLeg)) {
parkingMode = true;
this.events.processEvent(new StartParkingSearchEvent(timer.getTimeOfDay(), vehicleId, currentLinkId));
}
@@ -98,12 +101,18 @@ public Id getNextLinkId() {
return linkIds.get(currentLinkIdx + 1);
} else {
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg && !hasFoundParking && followingActivity.getLinkId().equals(currentLinkId)) {
+ createWaitingActivityUntilPassengerInteractionIsPossible(currentLinkId, vehicleId, timer.getTimeOfDay());
+ this.events
+ .processEvent(new StartWaitingForParkingEvent(timer.getTimeOfDay(), vehicleId, currentLinkId));
+ }
if (hasFoundParking || reachedDestinationWithoutParking) {
// easy, we can just park where at our destination link
- if (hasFoundParking) {
+ if (hasFoundParking && !passangerInteractionAtParkingFacilityAtEndOfLeg) {
+ //calculate parkingTime for parking_activity
double parkingDuration;
double expectedDrivingDurationToPickup;
- double drivingDurationFromDropOff = timer.getTimeOfDay() - currentPlannedLeg.getDepartureTime().seconds();
+ double drivingDurationFromGetOff = timer.getTimeOfDay() - currentPlannedLeg.getDepartureTime().seconds();
if (nextSelectedParkingLink.equals(currentLinkId)) {
expectedDrivingDurationToPickup = ((NearestParkingSpotSearchLogic) this.logic).getExpectedTravelTime(
@@ -112,7 +121,9 @@ public Id getNextLinkId() {
expectedDrivingDurationToPickup = ((NearestParkingSpotSearchLogic) this.logic).getExpectedTravelTime(
currentPlannedLeg.getRoute().getStartLinkId(), timer.getTimeOfDay(), currentLinkId);
}
- parkingDuration = followingActivity.getMaximumDuration().seconds() - drivingDurationFromDropOff - expectedDrivingDurationToPickup;
+ parkingDuration = followingActivity.getMaximumDuration().seconds()
+ - drivingDurationFromGetOff - expectedDrivingDurationToPickup
+ - ((FacilityBasedParkingManager) parkingManager).getParkStageActivityDuration();
followingActivity.setMaximumDuration(parkingDuration);
}
this.logic.reset();
@@ -125,10 +136,19 @@ public Id getNextLinkId() {
}
}
// need to find the next link
- double nextPickupTime = followingActivity.getStartTime().seconds() + followingActivity.getMaximumDuration().seconds();
- double maxParkingDuration = followingActivity.getMaximumDuration().seconds() - (followingActivity.getStartTime().seconds() - timer.getTimeOfDay());
+ double nextPickupTime;
+ double maxParkingDuration;
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg){
+ nextPickupTime = 0.;
+ maxParkingDuration = followingActivity.getMaximumDuration().seconds();
+ }
+ else {
+ nextPickupTime = currentPlannedLeg.getDepartureTime().seconds() + followingActivity.getMaximumDuration().seconds();
+ maxParkingDuration = nextPickupTime - timer.getTimeOfDay();
+ }
Id nextLinkId = ((NearestParkingSpotSearchLogic) this.logic).getNextLink(currentLinkId, route.getEndLinkId(), vehicleId, mode,
- timer.getTimeOfDay(), maxParkingDuration, nextPickupTime);
+ timer.getTimeOfDay(), maxParkingDuration, nextPickupTime, passangerInteractionAtParkingFacilityAtEndOfLeg,
+ followingActivity.getCoord());
if (((NearestParkingSpotSearchLogic) this.logic).isNextParkingActivitySkipped() && parkingAtEndOfLeg) {
removeNextActivityAndFollowingLeg();
parkingAtEndOfLeg = false;
@@ -163,9 +183,19 @@ public Id getNextLinkId() {
}
}
+ private void createWaitingActivityUntilPassengerInteractionIsPossible(Id newLinkId, Id vehicleId, double now) {
+ Activity waitingActivity = PopulationUtils.createActivityFromLinkId(ParkingUtils.WaitingForParkingActivityType, newLinkId);
+ ParkingUtils.setNoParkingForActivity(waitingActivity);
+ plan.getPlanElements().add(planIndexNextActivity, waitingActivity);
+ hasFoundParking = true;
+ ((FacilityBasedParkingManager) parkingManager).addVehicleForWaitingForParking(newLinkId, vehicleId, now);
+ }
+
private void removeNextActivityAndFollowingLeg() {
plan.getPlanElements().remove(planIndexNextActivity);
plan.getPlanElements().remove(planIndexNextActivity);
+// log.info(
+// plan.getPerson().getId().toString() + ": Parking activity after getOff point '" + ((Activity)plan.getPlanElements().get(planIndexNextActivity - 2)).getType() + "' is removed, because no parking facility was found.");
}
public boolean driveToBaseWithoutParking() {
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/BenensonParkingAgentLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/BenensonParkingAgentLogic.java
index c799cbc1355..381bfd331d2 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/BenensonParkingAgentLogic.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/BenensonParkingAgentLogic.java
@@ -1,5 +1,5 @@
/**
- *
+ *
*/
package org.matsim.contrib.parking.parkingsearch.DynAgent.agentLogic;
@@ -9,7 +9,6 @@
import org.matsim.api.core.v01.population.Route;
import org.matsim.contrib.dynagent.DynAction;
import org.matsim.contrib.parking.parkingsearch.DynAgent.BenensonDynLeg;
-import org.matsim.contrib.parking.parkingsearch.DynAgent.agentLogic.ParkingAgentLogic;
import org.matsim.contrib.parking.parkingsearch.manager.ParkingSearchManager;
import org.matsim.contrib.parking.parkingsearch.manager.vehicleteleportationlogic.VehicleTeleportationLogic;
import org.matsim.contrib.parking.parkingsearch.routing.ParkingRouter;
@@ -29,37 +28,37 @@ public class BenensonParkingAgentLogic extends ParkingAgentLogic {
/**
* @param plan
* @param parkingManager
- * @param walkLegFactory
+ * @param walkRouter
* @param parkingRouter
* @param events
* @param parkingLogic
* @param timer
* @param teleportationLogic
*/
-
-
+
+
public BenensonParkingAgentLogic(Plan plan, ParkingSearchManager parkingManager, RoutingModule walkRouter, Network network,
ParkingRouter parkingRouter, EventsManager events, ParkingSearchLogic parkingLogic, MobsimTimer timer,
VehicleTeleportationLogic teleportationLogic, ParkingSearchConfigGroup configGroup) {
super(plan, parkingManager, walkRouter, network, parkingRouter, events, parkingLogic, timer, teleportationLogic, configGroup);
}
-
+
@Override
protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now) {
// we have unparked, now we need to get going by car again.
-
+
Leg currentPlannedLeg = (Leg) currentPlanElement;
Route plannedRoute = currentPlannedLeg.getRoute();
NetworkRoute actualRoute = this.parkingRouter.getRouteFromParkingToDestination(plannedRoute.getEndLinkId(), now, agent.getCurrentLinkId());
- if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now))||(isinitialLocation)){
+ if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now))||(isInitialLocation)){
this.lastParkActionState = LastParkActionState.CARTRIP;
- isinitialLocation = false;
+ isInitialLocation = false;
Leg currentLeg = (Leg) this.currentPlanElement;
//this could be Car, Carsharing, Motorcylce, or whatever else mode we have, so we want our leg to reflect this.
return new BenensonDynLeg(currentLeg.getMode(), actualRoute, parkingLogic, parkingManager, currentlyAssignedVehicleId, timer, events);
}
else throw new RuntimeException("parking location mismatch");
-
+
}
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/MemoryBasedParkingAgentLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/MemoryBasedParkingAgentLogic.java
index dbe7b937923..b7358bc6a39 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/MemoryBasedParkingAgentLogic.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/MemoryBasedParkingAgentLogic.java
@@ -1,5 +1,5 @@
/**
- *
+ *
*/
package org.matsim.contrib.parking.parkingsearch.DynAgent.agentLogic;
@@ -31,22 +31,22 @@ public MemoryBasedParkingAgentLogic(Plan plan, ParkingSearchManager parkingManag
super(plan, parkingManager, walkRouter, network, parkingRouter, events, parkingLogic, timer, teleportationLogic, configGroup);
}
-
+
@Override
protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now) {
// we have unparked, now we need to get going by car again.
-
+
Leg currentPlannedLeg = (Leg) currentPlanElement;
Route plannedRoute = currentPlannedLeg.getRoute();
NetworkRoute actualRoute = this.parkingRouter.getRouteFromParkingToDestination(plannedRoute.getEndLinkId(), now, agent.getCurrentLinkId());
- if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now))||(isinitialLocation)){
+ if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now))||(isInitialLocation)){
this.lastParkActionState = LastParkActionState.CARTRIP;
- isinitialLocation = false;
+ isInitialLocation = false;
Leg currentLeg = (Leg) this.currentPlanElement;
//this could be Car, Carsharing, Motorcylce, or whatever else mode we have, so we want our leg to reflect this.
return new DistanceMemoryDynLeg(currentLeg.getMode(), actualRoute, parkingLogic, parkingManager, currentlyAssignedVehicleId, timer, events);
}
else throw new RuntimeException("parking location mismatch");
-
+
}
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/NearestParkingSpotAgentLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/NearestParkingSpotAgentLogic.java
index faec3310574..f3a7e671b14 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/NearestParkingSpotAgentLogic.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/NearestParkingSpotAgentLogic.java
@@ -10,6 +10,7 @@
import org.matsim.contrib.dynagent.StaticPassengerDynLeg;
import org.matsim.contrib.parking.parkingsearch.DynAgent.NearestParkingDynLeg;
import org.matsim.contrib.parking.parkingsearch.ParkingUtils;
+import org.matsim.contrib.parking.parkingsearch.manager.FacilityBasedParkingManager;
import org.matsim.contrib.parking.parkingsearch.manager.ParkingSearchManager;
import org.matsim.contrib.parking.parkingsearch.manager.vehicleteleportationlogic.VehicleTeleportationLogic;
import org.matsim.contrib.parking.parkingsearch.routing.ParkingRouter;
@@ -54,50 +55,35 @@ public DynAction computeNextAction(DynAction oldAction, double now) {
if (lastParkActionState.equals(LastParkActionState.CARTRIP) && ((NearestParkingDynLeg) oldAction).driveToBaseWithoutParking())
this.lastParkActionState = LastParkActionState.WALKFROMPARK;
- switch (lastParkActionState) {
- case ACTIVITY:
- return nextStateAfterActivity(oldAction, now);
-
- case CARTRIP:
- return nextStateAfterCarTrip(oldAction, now);
-
- case NONCARTRIP:
- return nextStateAfterNonCarTrip(oldAction, now);
-
- case PARKACTIVITY:
- return nextStateAfterParkActivity(oldAction, now);
-
- case UNPARKACTIVITY:
- return nextStateAfterUnParkActivity(oldAction, now);
-
- case WALKFROMPARK:
- return nextStateAfterWalkFromPark(oldAction, now);
-
- case WALKTOPARK:
- return nextStateAfterWalkToPark(oldAction, now);
-
- }
- throw new RuntimeException("unreachable code");
- }
+ return switch (lastParkActionState) {
+ case ACTIVITY -> nextStateAfterActivity(oldAction, now);
+ case CARTRIP -> nextStateAfterCarTrip(oldAction, now);
+ case NONCARTRIP -> nextStateAfterNonCarTrip(oldAction, now);
+ case PARKACTIVITY -> nextStateAfterParkActivity(oldAction, now);
+ case UNPARKACTIVITY -> nextStateAfterUnParkActivity(oldAction, now);
+ case WALKFROMPARK -> nextStateAfterWalkFromPark(oldAction, now);
+ case WALKTOPARK -> nextStateAfterWalkToPark(oldAction, now);
+ };
+ }
@Override
protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now) {
// we have unparked, now we need to get going by car again.
Leg currentPlannedLeg = (Leg) currentPlanElement;
+ currentPlannedLeg.setDepartureTime(timer.getTimeOfDay());
Route plannedRoute = currentPlannedLeg.getRoute();
NetworkRoute actualRoute = this.parkingRouter.getRouteFromParkingToDestination(plannedRoute.getEndLinkId(), now, agent.getCurrentLinkId());
actualRoute.setVehicleId(currentlyAssignedVehicleId);
if (!plannedRoute.getStartLinkId().equals(actualRoute.getStartLinkId()))
currentPlannedLeg.setRoute(actualRoute);
- if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now)) || (isinitialLocation)) {
+ if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now)) || (isInitialLocation)) {
this.lastParkActionState = LastParkActionState.CARTRIP;
- isinitialLocation = false;
+ isInitialLocation = false;
// Leg currentLeg = (Leg) this.currentPlanElement;
int planIndexNextActivity = planIndex + 1;
Activity nextPlanElement = (Activity) plan.getPlanElements().get(planIndexNextActivity);
- if (nextPlanElement.getAttributes().getAsMap().containsKey("parking") && nextPlanElement.getAttributes().getAttribute("parking").equals(
- "noParking"))
+ if (ParkingUtils.checkIfActivityHasNoParking(nextPlanElement))
this.lastParkActionState = LastParkActionState.WALKFROMPARK;
//this could be Car, Carsharing, Motorcylce, or whatever else mode we have, so we want our leg to reflect this.
return new NearestParkingDynLeg(currentPlannedLeg, actualRoute, plan, planIndexNextActivity, parkingLogic, parkingManager,
@@ -133,6 +119,22 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
// we could either depart by car or not next
if (plan.getPlanElements().size() >= planIndex + 1) {
+ if (plan.getPlanElements().get(planIndex) instanceof Activity && ((Activity) plan.getPlanElements().get(planIndex)).getType().equals(
+ ParkingUtils.WaitingForParkingActivityType)) {
+ //now the waiting activity has finished and we can park now
+ this.parkingManager.parkVehicleHere(Id.create(this.agent.getId(), Vehicle.class), agent.getCurrentLinkId(), now);
+ return nextStateAfterNonCarTrip(oldAction, now);
+ }
+ if (plan.getPlanElements().get(planIndex + 1) instanceof Activity)
+ return nextStateAfterNonCarTrip(oldAction, now);
+ if (plan.getPlanElements().get(planIndex) instanceof Activity && ((Activity) plan.getPlanElements().get(planIndex)).getType().contains("_GetOff")) {
+ ((Activity) plan.getPlanElements().get(planIndex)).setEndTime(now);
+ ((Activity) plan.getPlanElements().get(planIndex + 4)).setStartTime(now + ((Activity) plan.getPlanElements().get(planIndex + 2)).getMaximumDuration().seconds());
+ // checks if it is possible to stay from getOff until getIn
+ boolean possibleToStay = checkIfParkingIsPossibleUntilNextActivities(this.planIndex,this.planIndex + 2);
+ if (possibleToStay)
+ return nextStateAfterNonCarTrip(oldAction, now);
+ }
planIndex++;
this.currentPlanElement = plan.getPlanElements().get(planIndex);
Leg currentLeg = (Leg) currentPlanElement;
@@ -141,7 +143,7 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
Id parkLink = this.parkingManager.getVehicleParkingLocation(vehicleId);
if (parkLink == null) {
- //this is the first activity of a day and our parking manager does not provide informations about initial stages. We suppose the car is parked where we are
+ //this is the first activity of a day and our parking manager does not provide information about initial stages. We suppose the car is parked where we are
parkLink = agent.getCurrentLinkId();
}
@@ -151,14 +153,13 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
Facility toFacility = new LinkWrapperFacility(network.getLinks().get(teleportedParkLink));
List extends PlanElement> walkTrip = walkRouter.calcRoute(
DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson()));
- if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg)) {
+ if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg walkLeg)) {
String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with non_network_walk to access the network. Not implemented in parking yet!";
log.error(message);
throw new RuntimeException(message);
}
- Leg walkLeg = (Leg) walkTrip.get(0);
this.currentlyAssignedVehicleId = vehicleId;
- this.stageInteractionType = ParkingUtils.PARKACTIVITYTYPE;
+ this.stageInteractionType = ParkingUtils.ParkingStageInteractionType;
if (!walkLeg.getTravelTime().equals(OptionalTime.defined(0.))) {
this.lastParkActionState = LastParkActionState.WALKTOPARK;
return new StaticPassengerDynLeg(walkLeg.getRoute(), walkLeg.getMode());
@@ -188,10 +189,96 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
protected DynAction nextStateAfterWalkToPark(DynAction oldAction, double now) {
//walk2park is complete, we can unpark.
this.lastParkActionState = LastParkActionState.UNPARKACTIVITY;
- PlanElement beforePlanElement = plan.getPlanElements().get(planIndex - 1);
- if (beforePlanElement.getAttributes().getAsMap().containsKey("parking") && beforePlanElement.getAttributes().getAttribute("parking").equals(
- "noParking"))
- return nextStateAfterUnParkActivity(oldAction, now);
+ Activity beforePlanElement = (Activity) plan.getPlanElements().get(planIndex - 1);
+ if (ParkingUtils.checkIfActivityHasNoParking(beforePlanElement))
+ return nextStateAfterUnParkActivity(oldAction, now); // wenn kein Parken dann einfach weiter
return new IdleDynActivity(this.stageInteractionType, now + configGroup.getUnparkduration());
}
+
+ @Override
+ protected DynAction nextStateAfterCarTrip(DynAction oldAction, double now) {
+ if (this.plan.getPlanElements().get(planIndex + 1) instanceof Activity && ((Activity) this.plan.getPlanElements().get(
+ planIndex + 1)).getType().equals(ParkingUtils.WaitingForParkingActivityType)) {
+ //next activity is waiting for parking. Thats why we have no parkVehicleHere at this moment
+ this.lastParkActionState = LastParkActionState.PARKACTIVITY;
+ this.currentlyAssignedVehicleId = null;
+ this.parkingLogic.reset();
+ return new IdleDynActivity(this.stageInteractionType, now + configGroup.getParkduration());
+ }
+ // car trip is complete, we have found a parking space (not part of the logic), block it and start to park
+ if (this.parkingManager.parkVehicleHere(Id.create(this.agent.getId(), Vehicle.class), agent.getCurrentLinkId(), now)) {
+ this.lastParkActionState = LastParkActionState.PARKACTIVITY;
+ this.currentlyAssignedVehicleId = null;
+ this.parkingLogic.reset();
+ return new IdleDynActivity(this.stageInteractionType, now + configGroup.getParkduration());
+ } else throw new RuntimeException("No parking possible");
+ }
+
+ @Override
+ protected DynAction nextStateAfterNonCarTrip(DynAction oldAction, double now) {
+
+ this.currentPlanElement = plan.getPlanElements().get(planIndex + 1);
+ Activity nextPlannedActivity = (Activity) this.currentPlanElement;
+ // checks if you can extend parking here until getIn
+ if (nextPlannedActivity.getType().equals(ParkingUtils.ParkingActivityType) && plan.getPlanElements().get(planIndex + 2) instanceof Leg) {
+ checkIfParkingIsPossibleUntilNextActivities(planIndex + 1,planIndex + 1);
+ }
+ // switch back to activity
+ planIndex++;
+ this.lastParkActionState = LastParkActionState.ACTIVITY;
+ final double endTime;
+ if (nextPlannedActivity.getEndTime().isUndefined()) {
+ if (nextPlannedActivity.getMaximumDuration().isUndefined()) {
+ endTime = Double.POSITIVE_INFINITY;
+ //last activity of a day
+ } else {
+ endTime = now + nextPlannedActivity.getMaximumDuration().seconds();
+ }
+ } else {
+ endTime = nextPlannedActivity.getEndTime().seconds();
+ }
+ return new IdleDynActivity(nextPlannedActivity.getType(), endTime);
+
+ }
+
+ private boolean checkIfParkingIsPossibleUntilNextActivities(int indexOfCurrentActivity, int indexOfParkingActivity) {
+ int indexOfFollowingActivity = indexOfCurrentActivity + 2;
+ Activity followingActivity = ((Activity) plan.getPlanElements().get(indexOfFollowingActivity));
+ //checks if it is possible to stay from the current getOff until the getIn
+ if (indexOfFollowingActivity == indexOfParkingActivity) {
+ Activity currentActivity = ((Activity) plan.getPlanElements().get(this.planIndex));
+ Activity activityAfterFollowing = ((Activity) plan.getPlanElements().get(this.planIndex + 4));
+ if (agent.getCurrentLinkId().equals(activityAfterFollowing.getLinkId()) && !ParkingUtils.checkIfActivityHasNoParking(
+ (Activity) currentPlanElement)) {
+ boolean canParkAtFacilityUntilGetIn = ((FacilityBasedParkingManager) parkingManager).canParkAtThisFacilityUntilEnd(
+ agent.getCurrentLinkId(),
+ followingActivity.getMaximumDuration().seconds(), currentActivity.getMaximumDuration().seconds(),
+ activityAfterFollowing.getMaximumDuration().seconds(), timer.getTimeOfDay());
+ if (canParkAtFacilityUntilGetIn) {
+ plan.getPlanElements().remove(this.planIndex + 3);
+ plan.getPlanElements().remove(this.planIndex + 1);
+ ((FacilityBasedParkingManager) parkingManager).registerStayFromGetOffUntilGetIn(this.agent.getVehicle().getId());
+ return true;
+ }
+ }
+ }
+ // checks if the now started parking activity can extend until the end of the following GetIn activity
+ else if (indexOfCurrentActivity == indexOfParkingActivity) {
+ Activity currentActivity = ((Activity) plan.getPlanElements().get(this.planIndex + 1));
+ if (agent.getCurrentLinkId().equals(followingActivity.getLinkId()) && !ParkingUtils.checkIfActivityHasNoParking(
+ followingActivity)) {
+ boolean canParkAtFacilityUntilGetIn = ((FacilityBasedParkingManager) parkingManager).canParkAtThisFacilityUntilEnd(
+ agent.getCurrentLinkId(),
+ currentActivity.getMaximumDuration().seconds(), 0.,
+ followingActivity.getMaximumDuration().seconds(), timer.getTimeOfDay());
+ if (canParkAtFacilityUntilGetIn) {
+ plan.getPlanElements().remove(indexOfParkingActivity + 1);
+ currentActivity.setEndTime(followingActivity.getStartTime().seconds());
+ ((FacilityBasedParkingManager) parkingManager).registerParkingBeforeGetIn(this.agent.getVehicle().getId());
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/ParkingAgentLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/ParkingAgentLogic.java
index 2bda5aa8698..dd2fb4fa74b 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/ParkingAgentLogic.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/ParkingAgentLogic.java
@@ -59,25 +59,25 @@
/**
* @author jbischoff
- *
*/
public class ParkingAgentLogic implements DynAgentLogic {
- public enum LastParkActionState {
+ public enum LastParkActionState {
- // we have the following cases of ending dynacts:
- NONCARTRIP, // non-car trip arrival: start Activity
- CARTRIP, // car-trip arrival: add park-car activity
- PARKACTIVITY, // park-car activity: get next PlanElement & add walk leg to activity location
- WALKFROMPARK ,// walk-leg to act: start next PlanElement Activity
- ACTIVITY, // ordinary activity: get next Leg, if car: go to car, otherwise add ordinary leg by other mode
- WALKTOPARK, // walk-leg to car: add unpark activity
- UNPARKACTIVITY // unpark activity: find the way to the next route & start leg
+ // we have the following cases of ending dynacts:
+ NONCARTRIP, // non-car trip arrival: start Activity
+ CARTRIP, // car-trip arrival: add park-car activity
+ PARKACTIVITY, // park-car activity: get next PlanElement & add walk leg to activity location
+ WALKFROMPARK,// walk-leg to act: start next PlanElement Activity
+ ACTIVITY, // ordinary activity: get next Leg, if car: go to car, otherwise add ordinary leg by other mode
+ WALKTOPARK, // walk-leg to car: add unpark activity
+ UNPARKACTIVITY // unpark activity: find the way to the next route & start leg
}
+
protected LastParkActionState lastParkActionState;
protected DynAgent agent;
protected int planIndex;
-// protected Iterator planElemIter;
+ // protected Iterator planElemIter;
protected Plan plan;
protected PlanElement currentPlanElement;
protected ParkingSearchManager parkingManager;
@@ -88,20 +88,18 @@ public enum LastParkActionState {
protected EventsManager events;
protected ParkingSearchLogic parkingLogic;
protected VehicleTeleportationLogic teleportationLogic;
- protected boolean isinitialLocation = true;
+ protected boolean isInitialLocation = true;
protected Id currentlyAssignedVehicleId = null;
protected String stageInteractionType = null;
protected ParkingSearchConfigGroup configGroup;
protected static final Logger log = LogManager.getLogger(ParkingAgentLogic.class);
/**
- * @param plan
- * (always starts with Activity)
+ * @param plan (always starts with Activity)
*/
- public ParkingAgentLogic(Plan plan, ParkingSearchManager parkingManager, RoutingModule walkRouter, Network network,
- ParkingRouter parkingRouter, EventsManager events, ParkingSearchLogic parkingLogic, MobsimTimer timer,
- VehicleTeleportationLogic teleportationLogic, ParkingSearchConfigGroup configGroup) {
-// planElemIter = plan.getPlanElements().iterator();
+ public ParkingAgentLogic(Plan plan, ParkingSearchManager parkingManager, RoutingModule walkRouter, Network network,
+ ParkingRouter parkingRouter, EventsManager events, ParkingSearchLogic parkingLogic, MobsimTimer timer,
+ VehicleTeleportationLogic teleportationLogic, ParkingSearchConfigGroup configGroup) {
this.plan = plan;
this.parkingManager = parkingManager;
this.walkRouter = walkRouter;
@@ -141,32 +139,17 @@ public DynAction computeNextAction(DynAction oldAction, double now) {
// ordinary activity: get next Leg, if car: go to car, otherwise add ordinary leg by other mode
// walk-leg to car: add unpark activity
// unpark activity: find the way to the next route & start leg
- switch (lastParkActionState){
- case ACTIVITY:
- return nextStateAfterActivity(oldAction, now);
-
- case CARTRIP:
- return nextStateAfterCarTrip(oldAction,now);
-
- case NONCARTRIP:
- return nextStateAfterNonCarTrip(oldAction,now);
-
- case PARKACTIVITY:
- return nextStateAfterParkActivity(oldAction,now);
-
- case UNPARKACTIVITY:
- return nextStateAfterUnParkActivity(oldAction,now);
-
- case WALKFROMPARK:
- return nextStateAfterWalkFromPark(oldAction,now);
-
- case WALKTOPARK:
- return nextStateAfterWalkToPark(oldAction,now);
-
- }
- throw new RuntimeException("unreachable code");
-
- }
+ return switch (lastParkActionState) {
+ case ACTIVITY -> nextStateAfterActivity(oldAction, now);
+ case CARTRIP -> nextStateAfterCarTrip(oldAction, now);
+ case NONCARTRIP -> nextStateAfterNonCarTrip(oldAction, now);
+ case PARKACTIVITY -> nextStateAfterParkActivity(oldAction, now);
+ case UNPARKACTIVITY -> nextStateAfterUnParkActivity(oldAction, now);
+ case WALKFROMPARK -> nextStateAfterWalkFromPark(oldAction, now);
+ case WALKTOPARK -> nextStateAfterWalkToPark(oldAction, now);
+ };
+
+ }
protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now) {
// we have unparked, now we need to get going by car again.
@@ -174,15 +157,14 @@ protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now
Leg currentPlannedLeg = (Leg) currentPlanElement;
Route plannedRoute = currentPlannedLeg.getRoute();
NetworkRoute actualRoute = this.parkingRouter.getRouteFromParkingToDestination(plannedRoute.getEndLinkId(), now, agent.getCurrentLinkId());
- if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now))||(isinitialLocation)){
+ if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now)) || (isInitialLocation)) {
this.lastParkActionState = LastParkActionState.CARTRIP;
- isinitialLocation = false;
+ isInitialLocation = false;
Leg currentLeg = (Leg) this.currentPlanElement;
//this could be Car, Carsharing, Motorcylce, or whatever else mode we have, so we want our leg to reflect this.
return new ParkingDynLeg(currentLeg.getMode(), actualRoute, parkingLogic, parkingManager, currentlyAssignedVehicleId, timer, events);
- }
- else throw new RuntimeException("parking location mismatch");
+ } else throw new RuntimeException("parking location mismatch");
}
@@ -200,15 +182,15 @@ protected DynAction nextStateAfterWalkFromPark(DynAction oldAction, double now)
protected DynAction nextStateAfterParkActivity(DynAction oldAction, double now) {
// add a walk leg after parking
Leg currentPlannedLeg = (Leg) currentPlanElement;
- Facility fromFacility = new LinkWrapperFacility (network.getLinks().get(agent.getCurrentLinkId()));
- Facility toFacility = new LinkWrapperFacility (network.getLinks().get(currentPlannedLeg.getRoute().getEndLinkId()));
- List extends PlanElement> walkTrip = walkRouter.calcRoute(DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson()));
- if (walkTrip.size() != 1 || ! (walkTrip.get(0) instanceof Leg)) {
+ Facility fromFacility = new LinkWrapperFacility(network.getLinks().get(agent.getCurrentLinkId()));
+ Facility toFacility = new LinkWrapperFacility(network.getLinks().get(currentPlannedLeg.getRoute().getEndLinkId()));
+ List extends PlanElement> walkTrip = walkRouter.calcRoute(
+ DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson()));
+ if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg walkLeg)) {
String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with non_network_walk to access the network. Not implemented in parking yet!";
log.error(message);
throw new RuntimeException(message);
}
- Leg walkLeg = (Leg) walkTrip.get(0);
this.lastParkActionState = LastParkActionState.WALKFROMPARK;
this.stageInteractionType = null;
return new StaticPassengerDynLeg(walkLeg.getRoute(), walkLeg.getMode());
@@ -223,11 +205,11 @@ protected DynAction nextStateAfterNonCarTrip(DynAction oldAction, double now) {
final double endTime;
if (nextPlannedActivity.getEndTime().isUndefined()) {
if (nextPlannedActivity.getMaximumDuration().isUndefined()) {
- endTime = Double.POSITIVE_INFINITY;
- //last activity of a day
- } else {
+ endTime = Double.POSITIVE_INFINITY;
+ //last activity of a day
+ } else {
endTime = now + nextPlannedActivity.getMaximumDuration().seconds();
- }
+ }
} else {
endTime = nextPlannedActivity.getEndTime().seconds();
}
@@ -237,13 +219,12 @@ protected DynAction nextStateAfterNonCarTrip(DynAction oldAction, double now) {
protected DynAction nextStateAfterCarTrip(DynAction oldAction, double now) {
// car trip is complete, we have found a parking space (not part of the logic), block it and start to park
- if (this.parkingManager.parkVehicleHere(Id.create(this.agent.getId(), Vehicle.class), agent.getCurrentLinkId(), now)){
- this.lastParkActionState = LastParkActionState.PARKACTIVITY;
- this.currentlyAssignedVehicleId = null;
- this.parkingLogic.reset();
+ if (this.parkingManager.parkVehicleHere(Id.create(this.agent.getId(), Vehicle.class), agent.getCurrentLinkId(), now)) {
+ this.lastParkActionState = LastParkActionState.PARKACTIVITY;
+ this.currentlyAssignedVehicleId = null;
+ this.parkingLogic.reset();
return new IdleDynActivity(this.stageInteractionType, now + configGroup.getParkduration());
- }
- else throw new RuntimeException ("No parking possible");
+ } else throw new RuntimeException("No parking possible");
}
protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
@@ -263,19 +244,18 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
Facility fromFacility = new LinkWrapperFacility(network.getLinks().get(agent.getCurrentLinkId()));
Id teleportedParkLink = this.teleportationLogic.getVehicleLocation(agent.getCurrentLinkId(), vehicleId, parkLink, now,
- currentLeg.getMode());
+ currentLeg.getMode());
Facility toFacility = new LinkWrapperFacility(network.getLinks().get(teleportedParkLink));
List extends PlanElement> walkTrip = walkRouter.calcRoute(
- DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson()));
- if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg)) {
+ DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson()));
+ if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg walkLeg)) {
String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with non_network_walk to access the network. Not implemented in parking yet!";
log.error(message);
throw new RuntimeException(message);
}
- Leg walkLeg = (Leg) walkTrip.get(0);
this.lastParkActionState = LastParkActionState.WALKTOPARK;
this.currentlyAssignedVehicleId = vehicleId;
- this.stageInteractionType = ParkingUtils.PARKACTIVITYTYPE;
+ this.stageInteractionType = ParkingUtils.ParkingStageInteractionType;
return new StaticPassengerDynLeg(walkLeg.getRoute(), walkLeg.getMode());
} else if (currentLeg.getMode().equals(TransportMode.pt)) {
if (currentLeg.getRoute() instanceof TransitPassengerRoute) {
@@ -292,8 +272,8 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
}
} else throw new RuntimeException(
- "no more leg to follow but activity is ending\nLastPlanElement: " + currentPlanElement.toString() + "\n Agent " + this.agent.getId() + "\nTime: " + Time.writeTime(
- now));
+ "no more leg to follow but activity is ending\nLastPlanElement: " + currentPlanElement.toString() + "\n Agent " + this.agent.getId() + "\nTime: " + Time.writeTime(
+ now));
}
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/ParkingUtils.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/ParkingUtils.java
index fc5abd290c6..c3f2a38eb87 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/ParkingUtils.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/ParkingUtils.java
@@ -21,18 +21,21 @@
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.network.Link;
+import org.matsim.api.core.v01.population.Activity;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
- * @author jbischoff, tschlenther
+ * @author jbischoff, tschlenther, Ricardo Ewert
*
*/
public class ParkingUtils {
- static public final String PARKACTIVITYTYPE = "parking";
+ static public final String ParkingStageInteractionType = "parking";
+ static public final String ParkingActivityType = "parking_activity";
+ static public final String WaitingForParkingActivityType = "waitingForParkingSpace_activity";
static public final int NO_OF_LINKS_TO_GET_ON_ROUTE = 5;
@@ -143,4 +146,45 @@ public static List getOutgoingLinksForMode(Link link, String mode) {
return outGoingModeLinks;
}
+ /**
+ * Checks if the activity has parking while the activity.
+ *
+ * @param followingActivity
+ * @return
+ */
+ public static boolean checkIfActivityHasNoParking(Activity followingActivity) {
+ return followingActivity.getAttributes().getAsMap().containsKey("parking") && followingActivity.getAttributes().getAttribute(
+ "parking").equals("noParking");
+
+ }
+
+ /**
+ * Sets that while this activity we simulate no parking activities.
+ *
+ * @param activity
+ */
+ public static void setNoParkingForActivity(Activity activity) {
+ activity.getAttributes().putAttribute("parking", "noParking");
+ }
+
+ /**
+ * This activity has a passenger interaction. This would mean that the location is fixed, and can not be changed.
+ *
+ * @param activity
+ */
+ public static void setPassangerInteractionForActivity(Activity activity) {
+ activity.getAttributes().putAttribute("parking", "PassangerInteraction");
+ }
+
+ /**
+ * Checks if the activity has a passanger interaction. This would mean that the location is fixed, and can not be changed.
+ *
+ * @param activity
+ * @return
+ */
+ public static boolean checkIfActivityHasPassengerInteraction(Activity activity) {
+ return activity.getAttributes().getAsMap().containsKey("parking") && activity.getAttributes().getAttribute(
+ "parking").equals(
+ "PassangerInteraction");
+ }
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingListener.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingListener.java
index 9203fe45526..41e370c8065 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingListener.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingListener.java
@@ -26,9 +26,13 @@
import org.matsim.core.controler.OutputDirectoryHierarchy;
import org.matsim.core.controler.events.IterationEndsEvent;
import org.matsim.core.controler.listener.IterationEndsListener;
+import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent;
+import org.matsim.core.mobsim.framework.events.MobsimInitializedEvent;
+import org.matsim.core.mobsim.framework.listeners.MobsimBeforeSimStepListener;
+import org.matsim.core.mobsim.framework.listeners.MobsimInitializedListener;
+import org.matsim.core.mobsim.qsim.QSim;
import org.matsim.core.utils.io.IOUtils;
-
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.List;
@@ -38,7 +42,7 @@
*
*/
-public class ParkingListener implements IterationEndsListener {
+public class ParkingListener implements IterationEndsListener, MobsimBeforeSimStepListener, MobsimInitializedListener {
@Inject
ParkingSearchManager manager;
@@ -59,7 +63,7 @@ private void writeStatsByTimesteps(List produceBeneStatistics, int itera
BufferedWriter bw = IOUtils.getBufferedWriter(output.getIterationFilename(iteration, "parkingStatsPerTimeSteps.csv"));
try {
- String header = "time;rejectedReservations;foundParking;unpark";
+ String header = "time;rejectedParkingRequest;foundParking;unpark";
bw.write(header);
bw.newLine();
for (String s : produceBeneStatistics){
@@ -82,7 +86,7 @@ private void writeStats(List produceStatistics, int iteration) {
BufferedWriter bw = IOUtils.getBufferedWriter(output.getIterationFilename(iteration, "parkingStats.csv"));
try {
- String header = "linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedReservations";
+ String header = "linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn";
bw.write(header);
bw.newLine();
for (String s : produceStatistics){
@@ -99,4 +103,15 @@ private void writeStats(List produceStatistics, int iteration) {
}
+ @Override
+ public void notifyMobsimBeforeSimStep(MobsimBeforeSimStepEvent event) {
+ ((FacilityBasedParkingManager) manager).checkFreeCapacitiesForWaitingVehicles((QSim) event.getQueueSimulation(), event.getSimulationTime());
+ }
+
+ @Override
+ public void notifyMobsimInitialized(final MobsimInitializedEvent e) {
+ QSim qSim = (QSim) e.getQueueSimulation();
+ ((FacilityBasedParkingManager) manager).setQSim(qSim);
+
+ }
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingSlotVisualiser.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingSlotVisualiser.java
index e475acbb181..50587d72059 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingSlotVisualiser.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingSlotVisualiser.java
@@ -1,202 +1,202 @@
-/* *********************************************************************** *
- * project: org.matsim.*
- * *********************************************************************** *
- * *
- * copyright : (C) ${year} by the members listed in the COPYING, *
- * LICENSE and WARRANTY file. *
- * email : info at matsim dot org *
- * *
- * *********************************************************************** *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * See also COPYING, LICENSE and WARRANTY file *
- * *
- * *********************************************************************** */
-
-package org.matsim.contrib.parking.parkingsearch.evaluation;
-
-import com.google.inject.Inject;
-import org.apache.commons.lang3.mutable.MutableDouble;
-import org.apache.logging.log4j.LogManager;
-import org.matsim.api.core.v01.Coord;
-import org.matsim.api.core.v01.Id;
-import org.matsim.api.core.v01.Scenario;
-import org.matsim.api.core.v01.events.PersonEntersVehicleEvent;
-import org.matsim.api.core.v01.events.PersonLeavesVehicleEvent;
-import org.matsim.api.core.v01.events.VehicleEntersTrafficEvent;
-import org.matsim.api.core.v01.events.VehicleLeavesTrafficEvent;
-import org.matsim.api.core.v01.events.handler.PersonEntersVehicleEventHandler;
-import org.matsim.api.core.v01.events.handler.PersonLeavesVehicleEventHandler;
-import org.matsim.api.core.v01.events.handler.VehicleEntersTrafficEventHandler;
-import org.matsim.api.core.v01.events.handler.VehicleLeavesTrafficEventHandler;
-import org.matsim.api.core.v01.network.Link;
-import org.matsim.api.core.v01.network.Network;
-import org.matsim.contrib.parking.parkingsearch.ParkingUtils;
-import org.matsim.core.controler.events.IterationEndsEvent;
-import org.matsim.core.controler.listener.IterationEndsListener;
-import org.matsim.core.gbl.MatsimRandom;
-import org.matsim.core.utils.collections.Tuple;
-import org.matsim.core.utils.io.IOUtils;
-import org.matsim.facilities.ActivityFacility;
-import org.matsim.vehicles.Vehicle;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.util.*;
-import java.util.Map.Entry;
-
-public class ParkingSlotVisualiser implements PersonEntersVehicleEventHandler, PersonLeavesVehicleEventHandler, VehicleLeavesTrafficEventHandler, VehicleEntersTrafficEventHandler, IterationEndsListener {
-
- Network network;
-
- protected Map, ParkingSlotManager> slotsOnLink = new HashMap, ParkingSlotManager>();
- protected Map, Double> midnightParkers = new HashMap, Double>();
- protected Map, ParkingSlotManager> vehiclesResponsibleManager = new HashMap<>();
- Random r = MatsimRandom.getLocalInstance();
- protected List parkings = new ArrayList<>();
-
- Map, Id> parkedVehicles = new HashMap, Id>();
-
- /**
- *
- */
- @Inject
- public ParkingSlotVisualiser(Scenario scenario) {
- this.network = scenario.getNetwork();
- Map, ActivityFacility> parkingFacilities = scenario.getActivityFacilities().getFacilitiesForActivityType(
- ParkingUtils.PARKACTIVITYTYPE);
- initialize(parkingFacilities);
- }
-
- public ParkingSlotVisualiser(Network network, Map, ActivityFacility> parkingFacilities) {
- this.network = network;
- initialize(parkingFacilities);
- }
-
- private void initialize(Map, ActivityFacility> parkingFacilities) {
- Map, MutableDouble> nrOfSlotsPerLink = new HashMap, MutableDouble>();
- for (ActivityFacility fac : parkingFacilities.values()) {
- Id linkId = fac.getLinkId();
- if (nrOfSlotsPerLink.containsKey(linkId)) {
- nrOfSlotsPerLink.get(linkId).add(fac.getActivityOptions().get(ParkingUtils.PARKACTIVITYTYPE).getCapacity());
- } else {
- nrOfSlotsPerLink.put(linkId, new MutableDouble(fac.getActivityOptions().get(ParkingUtils.PARKACTIVITYTYPE).getCapacity()));
- }
- }
-
- for (Id linkID : nrOfSlotsPerLink.keySet()) {
-// LogManager.getLogger(getClass()).info("initialize parking visualisation for link " + linkID);
- this.slotsOnLink.put(linkID, new ParkingSlotManager(network.getLinks().get(linkID), nrOfSlotsPerLink.get(linkID).intValue()));
- }
- }
-
-
- @Override
- public void reset(int iteration) {
- for (Id link : this.slotsOnLink.keySet()) {
- this.slotsOnLink.get(link).setAllParkingTimesToZero();
- }
- }
-
- @Override
- public void handleEvent(VehicleLeavesTrafficEvent event) {
- if (this.slotsOnLink.containsKey(event.getLinkId())) {
- this.vehiclesResponsibleManager.put(event.getVehicleId(), this.slotsOnLink.get(event.getLinkId()));
- }
- }
-
- @Override
- public void handleEvent(PersonLeavesVehicleEvent event) {
- ParkingSlotManager manager = this.vehiclesResponsibleManager.remove(event.getVehicleId());
- if (manager != null) {
- Tuple parkingTuple = manager.processParking(event.getTime(), event.getVehicleId());
- this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + event.getTime() + ";" +
- parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "free");
- this.parkedVehicles.put(event.getVehicleId(), manager.getLinkId());
- }
- }
-
-
- @Override
- public void handleEvent(PersonEntersVehicleEvent event) {
- if (this.parkedVehicles.containsKey(event.getVehicleId())) {
- ParkingSlotManager manager = this.slotsOnLink.get(this.parkedVehicles.get(event.getVehicleId()));
- Tuple parkingTuple = manager.processUnParking(event.getTime(), event.getVehicleId());
- this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + event.getTime() + ";" +
- parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "veh" + event.getVehicleId());
- this.parkedVehicles.remove(event.getVehicleId());
- } else {
- midnightParkers.put(event.getVehicleId(), event.getTime());
- }
- }
-
- /* (non-Javadoc)
- * @see org.matsim.api.core.v01.events.handler.VehicleEntersTrafficEventHandler#handleEvent(org.matsim.api.core.v01.events.VehicleEntersTrafficEvent)
- */
- @Override
- public void handleEvent(VehicleEntersTrafficEvent event) {
- if (this.midnightParkers.containsKey(event.getVehicleId())) {
- if (this.slotsOnLink.containsKey(event.getLinkId())) {
- ParkingSlotManager manager = this.slotsOnLink.get(event.getLinkId());
- Tuple parkingTuple = manager.processUnParking(event.getTime(), event.getVehicleId());
- if (parkingTuple != null) {
- this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + event.getTime() + ";" +
- parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "veh" + event.getVehicleId());
- }
- }
- this.midnightParkers.remove(event.getVehicleId());
- }
- }
-
- public void finishDay() {
-
- for (Id linkId : this.slotsOnLink.keySet()) {
- ParkingSlotManager manager = this.slotsOnLink.get(linkId);
- Map, Tuple> occupiedSlots = manager.getOccupiedSlots();
-
- double endOfDay = 30 * 3600;
- for (Entry, Tuple> e : occupiedSlots.entrySet()) {
- Tuple parkingTuple = e.getValue();
- this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + endOfDay + ";" +
- parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "veh" + e.getKey());
-
- // set back to 0
- }
-
- List> freeSlots = manager.getFreeSlots();
- for (Tuple parkingTuple : freeSlots) {
- this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + endOfDay + ";" +
- parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "free");
- }
- }
- }
-
- public void plotSlotOccupation(String filename) {
- String head = "LinkId;from;To;X;Y;OccupiedByVehicle";
- BufferedWriter bw = IOUtils.getBufferedWriter(filename);
- try {
- bw.write(head);
- for (String s : this.parkings) {
- bw.newLine();
- bw.write(s);
- }
- bw.flush();
- bw.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- LogManager.getLogger(getClass()).info("FINISHED WRITING PARKING SLOT VISUALISATION FILE TO: " + filename);
- }
-
- @Override
- public void notifyIterationEnds(IterationEndsEvent event) {
- String path = event.getServices().getControlerIO().getIterationFilename(event.getIteration(),
- "ParkingSlots_it" + event.getIteration() + ".csv");
- this.finishDay();
- this.plotSlotOccupation(path);
- }
-}
-
+/* *********************************************************************** *
+ * project: org.matsim.*
+ * *********************************************************************** *
+ * *
+ * copyright : (C) ${year} by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * *********************************************************************** */
+
+package org.matsim.contrib.parking.parkingsearch.evaluation;
+
+import com.google.inject.Inject;
+import org.apache.commons.lang3.mutable.MutableDouble;
+import org.apache.logging.log4j.LogManager;
+import org.matsim.api.core.v01.Coord;
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.Scenario;
+import org.matsim.api.core.v01.events.PersonEntersVehicleEvent;
+import org.matsim.api.core.v01.events.PersonLeavesVehicleEvent;
+import org.matsim.api.core.v01.events.VehicleEntersTrafficEvent;
+import org.matsim.api.core.v01.events.VehicleLeavesTrafficEvent;
+import org.matsim.api.core.v01.events.handler.PersonEntersVehicleEventHandler;
+import org.matsim.api.core.v01.events.handler.PersonLeavesVehicleEventHandler;
+import org.matsim.api.core.v01.events.handler.VehicleEntersTrafficEventHandler;
+import org.matsim.api.core.v01.events.handler.VehicleLeavesTrafficEventHandler;
+import org.matsim.api.core.v01.network.Link;
+import org.matsim.api.core.v01.network.Network;
+import org.matsim.contrib.parking.parkingsearch.ParkingUtils;
+import org.matsim.core.controler.events.IterationEndsEvent;
+import org.matsim.core.controler.listener.IterationEndsListener;
+import org.matsim.core.gbl.MatsimRandom;
+import org.matsim.core.utils.collections.Tuple;
+import org.matsim.core.utils.io.IOUtils;
+import org.matsim.facilities.ActivityFacility;
+import org.matsim.vehicles.Vehicle;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.util.*;
+import java.util.Map.Entry;
+
+public class ParkingSlotVisualiser implements PersonEntersVehicleEventHandler, PersonLeavesVehicleEventHandler, VehicleLeavesTrafficEventHandler, VehicleEntersTrafficEventHandler, IterationEndsListener {
+
+ Network network;
+
+ protected Map, ParkingSlotManager> slotsOnLink = new HashMap, ParkingSlotManager>();
+ protected Map, Double> midnightParkers = new HashMap, Double>();
+ protected Map, ParkingSlotManager> vehiclesResponsibleManager = new HashMap<>();
+ Random r = MatsimRandom.getLocalInstance();
+ protected List parkings = new ArrayList<>();
+
+ protected Map, Id> parkedVehicles = new HashMap, Id>();
+
+ /**
+ *
+ */
+ @Inject
+ public ParkingSlotVisualiser(Scenario scenario) {
+ this.network = scenario.getNetwork();
+ Map, ActivityFacility> parkingFacilities = scenario.getActivityFacilities().getFacilitiesForActivityType(
+ ParkingUtils.ParkingStageInteractionType);
+ initialize(parkingFacilities);
+ }
+
+ public ParkingSlotVisualiser(Network network, Map, ActivityFacility> parkingFacilities) {
+ this.network = network;
+ initialize(parkingFacilities);
+ }
+
+ private void initialize(Map, ActivityFacility> parkingFacilities) {
+ Map, MutableDouble> nrOfSlotsPerLink = new HashMap, MutableDouble>();
+ for (ActivityFacility fac : parkingFacilities.values()) {
+ Id linkId = fac.getLinkId();
+ if (nrOfSlotsPerLink.containsKey(linkId)) {
+ nrOfSlotsPerLink.get(linkId).add(fac.getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity());
+ } else {
+ nrOfSlotsPerLink.put(linkId, new MutableDouble(fac.getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity()));
+ }
+ }
+
+ for (Id linkID : nrOfSlotsPerLink.keySet()) {
+// LogManager.getLogger(getClass()).info("initialize parking visualisation for link " + linkID);
+ this.slotsOnLink.put(linkID, new ParkingSlotManager(network.getLinks().get(linkID), nrOfSlotsPerLink.get(linkID).intValue()));
+ }
+ }
+
+
+ @Override
+ public void reset(int iteration) {
+ for (Id link : this.slotsOnLink.keySet()) {
+ this.slotsOnLink.get(link).setAllParkingTimesToZero();
+ }
+ }
+
+ @Override
+ public void handleEvent(VehicleLeavesTrafficEvent event) {
+ if (this.slotsOnLink.containsKey(event.getLinkId())) {
+ this.vehiclesResponsibleManager.put(event.getVehicleId(), this.slotsOnLink.get(event.getLinkId()));
+ }
+ }
+
+ @Override
+ public void handleEvent(PersonLeavesVehicleEvent event) {
+ ParkingSlotManager manager = this.vehiclesResponsibleManager.remove(event.getVehicleId());
+ if (manager != null) {
+ Tuple parkingTuple = manager.processParking(event.getTime(), event.getVehicleId());
+ this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + event.getTime() + ";" +
+ parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "free");
+ this.parkedVehicles.put(event.getVehicleId(), manager.getLinkId());
+ }
+ }
+
+
+ @Override
+ public void handleEvent(PersonEntersVehicleEvent event) {
+ if (this.parkedVehicles.containsKey(event.getVehicleId())) {
+ ParkingSlotManager manager = this.slotsOnLink.get(this.parkedVehicles.get(event.getVehicleId()));
+ Tuple parkingTuple = manager.processUnParking(event.getTime(), event.getVehicleId());
+ this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + event.getTime() + ";" +
+ parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "veh" + event.getVehicleId());
+ this.parkedVehicles.remove(event.getVehicleId());
+ } else {
+ midnightParkers.put(event.getVehicleId(), event.getTime());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.matsim.api.core.v01.events.handler.VehicleEntersTrafficEventHandler#handleEvent(org.matsim.api.core.v01.events.VehicleEntersTrafficEvent)
+ */
+ @Override
+ public void handleEvent(VehicleEntersTrafficEvent event) {
+ if (this.midnightParkers.containsKey(event.getVehicleId())) {
+ if (this.slotsOnLink.containsKey(event.getLinkId())) {
+ ParkingSlotManager manager = this.slotsOnLink.get(event.getLinkId());
+ Tuple parkingTuple = manager.processUnParking(event.getTime(), event.getVehicleId());
+ if (parkingTuple != null) {
+ this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + event.getTime() + ";" +
+ parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "veh" + event.getVehicleId());
+ }
+ }
+ this.midnightParkers.remove(event.getVehicleId());
+ }
+ }
+
+ public void finishDay() {
+
+ for (Id linkId : this.slotsOnLink.keySet()) {
+ ParkingSlotManager manager = this.slotsOnLink.get(linkId);
+ Map, Tuple> occupiedSlots = manager.getOccupiedSlots();
+
+ double endOfDay = 30 * 3600;
+ for (Entry, Tuple> e : occupiedSlots.entrySet()) {
+ Tuple parkingTuple = e.getValue();
+ this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + endOfDay + ";" +
+ parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "veh" + e.getKey());
+
+ // set back to 0
+ }
+
+ List> freeSlots = manager.getFreeSlots();
+ for (Tuple parkingTuple : freeSlots) {
+ this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + endOfDay + ";" +
+ parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "free");
+ }
+ }
+ }
+
+ public void plotSlotOccupation(String filename) {
+ String head = "LinkId;from;To;X;Y;OccupiedByVehicle";
+ BufferedWriter bw = IOUtils.getBufferedWriter(filename);
+ try {
+ bw.write(head);
+ for (String s : this.parkings) {
+ bw.newLine();
+ bw.write(s);
+ }
+ bw.flush();
+ bw.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ LogManager.getLogger(getClass()).info("FINISHED WRITING PARKING SLOT VISUALISATION FILE TO: " + filename);
+ }
+
+ @Override
+ public void notifyIterationEnds(IterationEndsEvent event) {
+ String path = event.getServices().getControlerIO().getIterationFilename(event.getIteration(),
+ "ParkingSlots_it" + event.getIteration() + ".csv");
+ this.finishDay();
+ this.plotSlotOccupation(path);
+ }
+}
+
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/events/StartWaitingForParkingEvent.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/events/StartWaitingForParkingEvent.java
new file mode 100644
index 00000000000..992fd8763e6
--- /dev/null
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/events/StartWaitingForParkingEvent.java
@@ -0,0 +1,68 @@
+/* *********************************************************************** *
+ * project: org.matsim.*
+ * *
+ * *********************************************************************** *
+ * *
+ * copyright : (C) 2016 by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * *********************************************************************** */
+
+package org.matsim.contrib.parking.parkingsearch.events;
+
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.events.Event;
+import org.matsim.api.core.v01.network.Link;
+import org.matsim.vehicles.Vehicle;
+
+import java.util.Map;
+
+/**
+ * @author jbischoff
+ */
+
+public class StartWaitingForParkingEvent extends Event {
+ public static final String EVENT_TYPE = "started waiting for parking";
+ public static final String ATTRIBUTE_VEHICLE = "vehicle";
+ public static final String ATTRIBUTE_LINK = "link";
+ private final Id linkId;
+ private final Id vehicleId;
+
+ public StartWaitingForParkingEvent(final double time, Id vehicleId, Id linkId) {
+ super(time);
+ this.linkId = linkId;
+ this.vehicleId = vehicleId;
+
+ }
+
+ @Override
+ public String getEventType() {
+ return EVENT_TYPE;
+ }
+
+ public Id getLinkId() {
+ return linkId;
+ }
+
+ public Id getVehicleId() {
+ return vehicleId;
+ }
+
+ @Override
+ public Map getAttributes() {
+ Map attr = super.getAttributes();
+ attr.put(ATTRIBUTE_VEHICLE, this.vehicleId.toString());
+ attr.put(ATTRIBUTE_LINK, this.linkId.toString());
+ return attr;
+ }
+
+}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/events/StartWaitingForParkingEventHandler.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/events/StartWaitingForParkingEventHandler.java
new file mode 100644
index 00000000000..24d5beb7d33
--- /dev/null
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/events/StartWaitingForParkingEventHandler.java
@@ -0,0 +1,32 @@
+/* *********************************************************************** *
+ * project: org.matsim.*
+ * *
+ * *********************************************************************** *
+ * *
+ * copyright : (C) 2016 by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * *********************************************************************** */
+
+package org.matsim.contrib.parking.parkingsearch.events;
+
+import org.matsim.core.events.handler.EventHandler;
+
+/**
+ * @author jbischoff
+ */
+
+public interface StartWaitingForParkingEventHandler extends EventHandler {
+
+ public void handleEvent(StartWaitingForParkingEvent event);
+
+}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/FacilityBasedParkingManager.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/FacilityBasedParkingManager.java
index ce0cc3a9e4d..9b3b8eff107 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/FacilityBasedParkingManager.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/FacilityBasedParkingManager.java
@@ -26,26 +26,32 @@
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.network.Network;
+import org.matsim.contrib.dynagent.DynAgent;
import org.matsim.contrib.parking.parkingsearch.ParkingUtils;
import org.matsim.contrib.parking.parkingsearch.sim.ParkingSearchConfigGroup;
+import org.matsim.core.mobsim.qsim.QSim;
import org.matsim.core.utils.misc.Time;
import org.matsim.facilities.ActivityFacility;
+import org.matsim.facilities.ActivityOption;
import org.matsim.vehicles.Vehicle;
import java.util.*;
import java.util.Map.Entry;
/**
- * @author jbischoff, schlenther
- *
+ * @author jbischoff, schlenther, Ricardo Ewert
*/
public class FacilityBasedParkingManager implements ParkingSearchManager {
protected Map, Integer> capacity = new HashMap<>();
protected Map, MutableLong> occupation = new HashMap<>();
protected Map, MutableLong> reservationsRequests = new HashMap<>();
- protected Map, MutableLong> rejectedReservations = new HashMap<>();
+ protected Map, MutableLong> rejectedParkingRequest = new HashMap<>();
protected Map, MutableLong> numberOfParkedVehicles = new HashMap<>();
+ protected Map, MutableLong> numberOfWaitingActivities = new HashMap<>();
+ protected Map, MutableLong> numberOfStaysFromGetOffUntilGetIn = new HashMap<>();
+ protected Map, MutableLong> numberOfParkingBeforeGetIn = new HashMap<>();
+ protected Map, TreeMap>> waitingVehicles = new HashMap<>();
protected TreeMap rejectedReservationsByTime = new TreeMap<>();
protected TreeMap foundParkingByTime = new TreeMap<>();
protected TreeMap unparkByTime = new TreeMap<>();
@@ -54,8 +60,10 @@ public class FacilityBasedParkingManager implements ParkingSearchManager {
protected Map, Id> parkingReservation = new HashMap<>();
protected Map, Id> parkingLocationsOutsideFacilities = new HashMap<>();
protected Map, Set>> facilitiesPerLink = new HashMap<>();
- protected Network network;
+ protected Network network;
+ protected ParkingSearchConfigGroup psConfigGroup;
protected boolean canParkOnlyAtFacilities;
+ private QSim qsim;
private final int maxSlotIndex;
private final int maxTime;
private final int timeBinSize;
@@ -63,14 +71,15 @@ public class FacilityBasedParkingManager implements ParkingSearchManager {
@Inject
public FacilityBasedParkingManager(Scenario scenario) {
- ParkingSearchConfigGroup psConfigGroup = (ParkingSearchConfigGroup) scenario.getConfig().getModules().get(ParkingSearchConfigGroup.GROUP_NAME);
+ psConfigGroup = (ParkingSearchConfigGroup) scenario.getConfig().getModules().get(
+ ParkingSearchConfigGroup.GROUP_NAME);
canParkOnlyAtFacilities = psConfigGroup.getCanParkOnlyAtFacilities();
this.network = scenario.getNetwork();
parkingFacilities = scenario.getActivityFacilities()
- .getFacilitiesForActivityType(ParkingUtils.PARKACTIVITYTYPE);
+ .getFacilitiesForActivityType(ParkingUtils.ParkingStageInteractionType);
LogManager.getLogger(getClass()).info(parkingFacilities.toString());
- this.timeBinSize = 15*60;
- this.maxTime = 24 * 3600 -1;
+ this.timeBinSize = 15 * 60;
+ this.maxTime = 24 * 3600 - 1;
this.maxSlotIndex = (this.maxTime / this.timeBinSize) + 1;
this.startTime = 9 * 3600;
@@ -82,10 +91,14 @@ public FacilityBasedParkingManager(Scenario scenario) {
}
parkingOnLink.add(fac.getId());
this.facilitiesPerLink.put(linkId, parkingOnLink);
+ this.waitingVehicles.computeIfAbsent(linkId, (k) -> new TreeMap<>());
this.occupation.put(fac.getId(), new MutableLong(0));
this.reservationsRequests.put(fac.getId(), new MutableLong(0));
- this.rejectedReservations.put(fac.getId(), new MutableLong(0));
+ this.rejectedParkingRequest.put(fac.getId(), new MutableLong(0));
this.numberOfParkedVehicles.put(fac.getId(), new MutableLong(0));
+ this.numberOfWaitingActivities.put(fac.getId(), new MutableLong(0));
+ this.numberOfStaysFromGetOffUntilGetIn.put(fac.getId(), new MutableLong(0));
+ this.numberOfParkingBeforeGetIn.put(fac.getId(), new MutableLong(0));
}
int slotIndex = getTimeSlotIndex(startTime);
while (slotIndex <= maxSlotIndex) {
@@ -109,6 +122,39 @@ public boolean reserveSpaceIfVehicleCanParkHere(Id vehicleId, Id
return canPark;
}
+ /**
+ * Checks if it is possible if you can park at this link for the complete time.
+ *
+ * @param linkId
+ * @param stopDuration
+ * @param getOffDuration
+ * @param pickUpDuration
+ * @param now
+ * @return
+ */
+ public boolean canParkAtThisFacilityUntilEnd(Id linkId, double stopDuration, double getOffDuration, double pickUpDuration, double now) {
+ Set> facilities = this.facilitiesPerLink.get(linkId);
+ if (facilities != null) {
+ double totalNeededParkingDuration = getOffDuration + stopDuration + pickUpDuration;
+ for (Id facility : facilities) {
+ double maxParkingDurationAtFacilityInHours = Double.MAX_VALUE;
+ if (this.parkingFacilities.get(facility).getAttributes().getAsMap().containsKey("maxParkingDurationInHours"))
+ maxParkingDurationAtFacilityInHours = 3600 * (double) this.parkingFacilities.get(facility).getAttributes().getAsMap().get(
+ "maxParkingDurationInHours");
+ if (maxParkingDurationAtFacilityInHours > totalNeededParkingDuration) {
+ ActivityOption parkingOptions = this.parkingFacilities.get(facility).getActivityOptions().get("parking");
+ if (!parkingOptions.getOpeningTimes().isEmpty()) {
+ if ((parkingOptions.getOpeningTimes().first().getStartTime() == 0 && parkingOptions.getOpeningTimes().first().getEndTime() == 24 * 3600))
+ if (parkingOptions.getOpeningTimes().first().getStartTime() <= now && parkingOptions.getOpeningTimes().first().getEndTime() >= now + totalNeededParkingDuration)
+ return true;
+ } else
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private boolean linkIdHasAvailableParkingForVehicle(Id linkId, Id vid) {
// LogManager.getLogger(getClass()).info("link "+linkId+" vehicle "+vid);
if (!this.facilitiesPerLink.containsKey(linkId) && !canParkOnlyAtFacilities) {
@@ -125,8 +171,8 @@ private boolean linkIdHasAvailableParkingForVehicle(Id linkId, Id
}
Set> parkingFacilitiesAtLink = this.facilitiesPerLink.get(linkId);
for (Id fac : parkingFacilitiesAtLink) {
- double cap = this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.PARKACTIVITYTYPE)
- .getCapacity();
+ double cap = this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType)
+ .getCapacity();
this.reservationsRequests.get(fac).increment();
if (this.occupation.get(fac).doubleValue() < cap) {
// LogManager.getLogger(getClass()).info("occ:
@@ -136,7 +182,7 @@ private boolean linkIdHasAvailableParkingForVehicle(Id linkId, Id
return true;
}
- this.rejectedReservations.get(fac).increment();
+ this.rejectedParkingRequest.get(fac).increment();
}
return false;
}
@@ -150,7 +196,7 @@ public Id getVehicleParkingLocation(Id vehicleId) {
@Override
public boolean parkVehicleHere(Id vehicleId, Id linkId, double time) {
- return parkVehicleAtLink(vehicleId, linkId, time);
+ return parkVehicleAtLink(vehicleId, linkId, time);
}
protected boolean parkVehicleAtLink(Id vehicleId, Id linkId, double time) {
@@ -167,7 +213,7 @@ protected boolean parkVehicleAtLink(Id vehicleId, Id linkId, doub
return true;
} else {
throw new RuntimeException("no parking reservation found for vehicle " + vehicleId.toString()
- + "arrival on link " + linkId + " with parking restriction");
+ + " arrival on link " + linkId + " with parking restriction");
}
}
}
@@ -193,11 +239,14 @@ public List produceStatistics() {
for (Entry, MutableLong> e : this.occupation.entrySet()) {
Id linkId = this.parkingFacilities.get(e.getKey()).getLinkId();
double capacity = this.parkingFacilities.get(e.getKey()).getActivityOptions()
- .get(ParkingUtils.PARKACTIVITYTYPE).getCapacity();
+ .get(ParkingUtils.ParkingStageInteractionType).getCapacity();
double x = this.parkingFacilities.get(e.getKey()).getCoord().getX();
double y = this.parkingFacilities.get(e.getKey()).getCoord().getY();
- String s = linkId.toString() + ";" + x + ";" + y + ";" + e.getKey().toString() + ";" + capacity + ";" + e.getValue().toString() + ";" + this.reservationsRequests.get(e.getKey()).toString() + ";" + this.numberOfParkedVehicles.get(e.getKey()).toString() + ";" + this.rejectedReservations.get(e.getKey()).toString();
+ String s = linkId.toString() + ";" + x + ";" + y + ";" + e.getKey().toString() + ";" + capacity + ";" + e.getValue().toString() + ";" + this.reservationsRequests.get(
+ e.getKey()).toString() + ";" + this.numberOfParkedVehicles.get(e.getKey()).toString() + ";" + this.rejectedParkingRequest.get(
+ e.getKey()).toString() + ";" + this.numberOfWaitingActivities.get(
+ e.getKey()).toString() + ";" + this.numberOfStaysFromGetOffUntilGetIn.get(e.getKey()).intValue() + ";" + this.numberOfParkingBeforeGetIn.get(e.getKey()).intValue();
stats.add(s);
}
return stats;
@@ -208,31 +257,32 @@ public List produceTimestepsStatistics() {
for (int time : rejectedReservationsByTime.keySet()) {
String s = Time.writeTime(time, Time.TIMEFORMAT_HHMM) + ";" + rejectedReservationsByTime.get(time) + ";" + foundParkingByTime.get(
- time) + ";" + unparkByTime.get(time);
+ time) + ";" + unparkByTime.get(time);
stats.add(s);
}
return stats;
}
- public double getNrOfAllParkingSpacesOnLink (Id linkId){
+
+ public double getNrOfAllParkingSpacesOnLink(Id linkId) {
double allSpaces = 0;
Set> parkingFacilitiesAtLink = this.facilitiesPerLink.get(linkId);
if (!(parkingFacilitiesAtLink == null)) {
- for (Id fac : parkingFacilitiesAtLink){
- allSpaces += this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.PARKACTIVITYTYPE).getCapacity();
+ for (Id fac : parkingFacilitiesAtLink) {
+ allSpaces += this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity();
}
}
return allSpaces;
}
- public double getNrOfFreeParkingSpacesOnLink (Id linkId){
+ public double getNrOfFreeParkingSpacesOnLink(Id linkId) {
double allFreeSpaces = 0;
Set> parkingFacilitiesAtLink = this.facilitiesPerLink.get(linkId);
if (parkingFacilitiesAtLink == null) {
return 0;
} else {
- for (Id fac : parkingFacilitiesAtLink){
- int cap = (int) this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.PARKACTIVITYTYPE).getCapacity();
+ for (Id fac : parkingFacilitiesAtLink) {
+ int cap = (int) this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity();
allFreeSpaces += (cap - this.occupation.get(fac).intValue());
}
}
@@ -243,11 +293,11 @@ public Map, ActivityFacility> getParkingFacilities() {
return this.parkingFacilities;
}
- public void registerRejectedReservation(double now){
+ public void registerRejectedReservation(double now) {
rejectedReservationsByTime.get(getTimeSlotIndex(now) * timeBinSize).increment();
}
- public TreeSet getTimeSteps(){
+ public TreeSet getTimeSteps() {
TreeSet timeSteps = new TreeSet<>();
int slotIndex = 0;
while (slotIndex <= maxSlotIndex) {
@@ -261,15 +311,77 @@ private int getTimeSlotIndex(final double time) {
if (time > this.maxTime) {
return this.maxSlotIndex;
}
- return ((int)time / this.timeBinSize);
+ return ((int) time / this.timeBinSize);
+ }
+
+ /**
+ * Gives the duration of the staging activity of parking
+ *
+ * @return
+ */
+ public double getParkStageActivityDuration() {
+ return psConfigGroup.getParkduration();
+ }
+
+ /**
+ * Gives the duration of the staging activity of unparking
+ *
+ * @return
+ */
+ public double getUnParkStageActivityDuration() {
+ return psConfigGroup.getUnparkduration();
}
@Override
public void reset(int iteration) {
- for (Id fac : this.rejectedReservations.keySet()) {
- this.rejectedReservations.get(fac).setValue(0);
+ for (Id fac : this.rejectedParkingRequest.keySet()) {
+ this.rejectedParkingRequest.get(fac).setValue(0);
this.reservationsRequests.get(fac).setValue(0);
this.numberOfParkedVehicles.get(fac).setValue(0);
+ this.numberOfWaitingActivities.get(fac).setValue(0);
+ }
+ waitingVehicles.clear();
+ }
+
+ public void addVehicleForWaitingForParking(Id linkId, Id vehicleId, double now) {
+// System.out.println(now + ": vehicle " +vehicleId.toString() + " starts waiting here: " + linkId.toString());
+ waitingVehicles.get(linkId).put(now + getParkStageActivityDuration() + 1, vehicleId);
+ for (Id fac : this.facilitiesPerLink.get(linkId)) {
+ this.numberOfWaitingActivities.get(fac).increment();
+ break;
+ }
+
+ }
+
+ public void checkFreeCapacitiesForWaitingVehicles(QSim qSim, double now) {
+ for (Id linkId : waitingVehicles.keySet()) {
+ if (!waitingVehicles.get(linkId).isEmpty()) {
+ for (Id fac : this.facilitiesPerLink.get(linkId)) {
+ int cap = (int) this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity();
+ while (this.occupation.get(fac).intValue() < cap && !waitingVehicles.get(linkId).isEmpty()) {
+ double startWaitingTime = waitingVehicles.get(linkId).firstKey();
+ if (startWaitingTime > now)
+ break;
+ Id vehcileId = waitingVehicles.get(linkId).remove(startWaitingTime);
+ DynAgent agent = (DynAgent) qSim.getAgents().get(Id.createPersonId(vehcileId.toString()));
+ reserveSpaceIfVehicleCanParkHere(vehcileId, linkId);
+ agent.endActivityAndComputeNextState(now);
+ qsim.rescheduleActivityEnd(agent);
+ }
+ }
+ }
}
}
+
+ public void setQSim(QSim qSim) {
+ qsim = qSim;
+ }
+
+ public void registerStayFromGetOffUntilGetIn(Id vehcileId) {
+ this.numberOfStaysFromGetOffUntilGetIn.get(parkingLocations.get(vehcileId)).increment();
+ }
+
+ public void registerParkingBeforeGetIn(Id vehcileId) {
+ this.numberOfParkingBeforeGetIn.get(parkingLocations.get(vehcileId)).increment();
+ }
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ZoneParkingManager.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ZoneParkingManager.java
index 5311933db84..b9fbebe4699 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ZoneParkingManager.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ZoneParkingManager.java
@@ -1,5 +1,5 @@
/**
- *
+ *
*/
package org.matsim.contrib.parking.parkingsearch.manager;
@@ -23,90 +23,92 @@
*/
public class ZoneParkingManager extends FacilityBasedParkingManager {
- private HashMap>> linksOfZone;
- private HashMap totalCapOfZone;
- private HashMap occupationOfZone;
-
+ private HashMap>> linksOfZone;
+ private HashMap totalCapOfZone;
+ private HashMap occupationOfZone;
+
/**
* @param scenario
*/
@Inject
public ZoneParkingManager(Scenario scenario, String[] pathToZoneTxtFiles) {
super(scenario);
-
- this.linksOfZone = new HashMap>>();
- this.totalCapOfZone = new HashMap();
- this.occupationOfZone = new HashMap();
-
- for(String zone: pathToZoneTxtFiles){
+
+ this.linksOfZone = new HashMap>>();
+ this.totalCapOfZone = new HashMap();
+ this.occupationOfZone = new HashMap();
+
+ for (String zone : pathToZoneTxtFiles) {
readZone(zone);
}
-
- for(String zone: this.linksOfZone.keySet()){
+
+ for (String zone : this.linksOfZone.keySet()) {
calculateTotalZoneParkCapacity(zone);
- this.occupationOfZone.put(zone,0.0);
+ this.occupationOfZone.put(zone, 0.0);
}
}
-
+
/**
* reads in a tabular file that declares which link id's are in the monitored zone
- * the part between the last '/' and the file type extension in the given path is considered to be the zone name
+ * the part between the last '/' and the file type extension in the given path is considered to be the zone name
* @param pathToZoneFile
*/
- void readZone(String pathToZoneFile){
- String zone = pathToZoneFile.substring(pathToZoneFile.lastIndexOf("/")+1, pathToZoneFile.lastIndexOf("."));
-
+ void readZone(String pathToZoneFile) {
+ String zone = pathToZoneFile.substring(pathToZoneFile.lastIndexOf("/") + 1, pathToZoneFile.lastIndexOf("."));
+
HashSet> links = new HashSet>();
-
+
TabularFileParserConfig config = new TabularFileParserConfig();
- config.setDelimiterTags(new String[] {"\t"});
- config.setFileName(pathToZoneFile);
- config.setCommentTags(new String[] { "#" });
- new TabularFileParser().parse(config, new TabularFileHandler() {
+ config.setDelimiterTags(new String[]{"\t"});
+ config.setFileName(pathToZoneFile);
+ config.setCommentTags(new String[]{"#"});
+ new TabularFileParser().parse(config, new TabularFileHandler() {
@Override
public void startRow(String[] row) {
Id linkId = Id.createLinkId(row[0]);
links.add(linkId);
}
-
- });
-
- this.linksOfZone.put(zone, links);
+
+ });
+
+ this.linksOfZone.put(zone, links);
}
-
- private void calculateTotalZoneParkCapacity(String zoneName){
+
+ private void calculateTotalZoneParkCapacity(String zoneName) {
double cap = 0.0;
- for(Id link : this.linksOfZone.get(zoneName)){
+ for (Id link : this.linksOfZone.get(zoneName)) {
cap += getNrOfAllParkingSpacesOnLink(link);
- }
+ }
this.totalCapOfZone.put(zoneName, cap);
}
-
+
@Override
public boolean parkVehicleHere(Id vehicleId, Id linkId, double time) {
if (parkVehicleAtLink(vehicleId, linkId, time)) {
- for(String zone : this.linksOfZone.keySet()){
- if(linksOfZone.get(zone).contains(linkId) && this.facilitiesPerLink.containsKey(linkId)){
+ for (String zone : this.linksOfZone.keySet()) {
+ if (linksOfZone.get(zone).contains(linkId) && this.facilitiesPerLink.containsKey(linkId)) {
double newOcc = this.occupationOfZone.get(zone) + 1;
- if(this.totalCapOfZone.get(zone) vehicleId, Id linkId, double time) {
if (!this.parkingLocations.containsKey(vehicleId)) {
@@ -115,35 +117,36 @@ public boolean unParkVehicleHere(Id vehicleId, Id linkId, double
} else {
Id fac = this.parkingLocations.remove(vehicleId);
this.occupation.get(fac).decrement();
-
+
Id parkingLink = this.parkingFacilities.get(fac).getLinkId();
- for(String zone : this.linksOfZone.keySet()){
- if(linksOfZone.get(zone).contains(parkingLink)){
+ for (String zone : this.linksOfZone.keySet()) {
+ if (linksOfZone.get(zone).contains(parkingLink)) {
double newOcc = this.occupationOfZone.get(zone) - 1;
- if(newOcc < 0 ){
- //in iteration 0 agents can "leave parking spaces" (get into traffic), but the manager didn't record them to be parked
+ if (newOcc < 0) {
+ //in iteration 0 agents can "leave parking spaces" (get into traffic), but the manager didn't record them to be parked
newOcc = 0;
}
- this.occupationOfZone.put(zone,newOcc);
+ this.occupationOfZone.put(zone, newOcc);
}
}
- return true;
+ return true;
}
}
-
-
- public double getOccupancyRatioOfZone(String zone){
- if(!(this.linksOfZone.keySet().contains(zone))) throw new RuntimeException("zone " + zone + " was not defined. thus, could'nt calculate occupancy ratio.");
+
+
+ public double getOccupancyRatioOfZone(String zone) {
+ if (!(this.linksOfZone.keySet().contains(zone)))
+ throw new RuntimeException("zone " + zone + " was not defined. thus, could'nt calculate occupancy ratio.");
return (this.occupationOfZone.get(zone) / this.totalCapOfZone.get(zone));
}
-
- public Set getZones(){
+
+ public Set getZones() {
return this.linksOfZone.keySet();
}
-
- public double getTotalCapacityOfZone(String zone){
+
+ public double getTotalCapacityOfZone(String zone) {
return this.totalCapOfZone.get(zone);
}
-
+
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/NearestParkingSpotSearchLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/NearestParkingSpotSearchLogic.java
index 041e74c2198..d87bf0408fe 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/NearestParkingSpotSearchLogic.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/NearestParkingSpotSearchLogic.java
@@ -49,6 +49,7 @@ public class NearestParkingSpotSearchLogic implements ParkingSearchLogic {
private NetworkRoute actualRoute = null;
private final boolean canReserveParkingSlot;
private final boolean canCheckParkingCapacitiesInAdvanced;
+ private double distanceFromBaseToAttraction = Double.NaN;
private boolean useRandomLinkChoice;
private int currentLinkIdx;
private final HashSet> triedParking;
@@ -79,22 +80,32 @@ public NearestParkingSpotSearchLogic(Network network, ParkingRouter parkingRoute
* @param baseLinkId linkId of the origin destination where the parkingSearch starts
*/
public Id getNextLink(Id currentLinkId, Id baseLinkId, Id vehicleId, String mode, double now,
- double maxParkingDuration, double nextPickupTime) {
-
+ double maxParkingDuration, double nextPickupTime, boolean passangerInteractionAtParkingFacilityAtEndOfLeg,
+ Coord coordOfAttraction) {
+ double maxAdditionalDistanceToAttraction = Double.MAX_VALUE;
+ // if a passenger interaction take place at a facility the walking distance to the attraction should be not extended by the value of maxAdditionalDistanceToAttraction
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg) {
+ if (Double.isNaN(distanceFromBaseToAttraction))
+ findDistanceBetweenBaseLinkAndAttraction(baseLinkId, coordOfAttraction);
+ maxAdditionalDistanceToAttraction = 200.;
+ }
if (actualRoute == null) {
- actualRoute = findRouteToNearestParkingFacility(baseLinkId, currentLinkId, canCheckParkingCapacitiesInAdvanced, now, maxParkingDuration);
- checkIfDrivingToNextParkingLocationIsPossible(currentLinkId, baseLinkId, now, nextPickupTime);
- if (actualRoute != null) {
- actualRoute.setVehicleId(vehicleId);
- }
+ actualRoute = findRouteToNearestParkingFacility(baseLinkId, currentLinkId, canCheckParkingCapacitiesInAdvanced, now,
+ maxParkingDuration,
+ passangerInteractionAtParkingFacilityAtEndOfLeg, maxAdditionalDistanceToAttraction, coordOfAttraction);
+ if (!passangerInteractionAtParkingFacilityAtEndOfLeg)
+ checkIfDrivingToNextParkingLocationIsPossible(currentLinkId, baseLinkId, now, nextPickupTime);
triedParking.clear();
} else if (currentLinkId.equals(actualRoute.getEndLinkId()) && !skipParkingActivity) {
currentLinkIdx = 0;
- actualRoute = findRouteToNearestParkingFacility(baseLinkId, currentLinkId, canCheckParkingCapacitiesInAdvanced, now, maxParkingDuration);
- checkIfDrivingToNextParkingLocationIsPossible(currentLinkId, baseLinkId, now, nextPickupTime);
- if (actualRoute != null) {
- actualRoute.setVehicleId(vehicleId);
- }
+ actualRoute = findRouteToNearestParkingFacility(baseLinkId, currentLinkId, canCheckParkingCapacitiesInAdvanced, now,
+ maxParkingDuration,
+ passangerInteractionAtParkingFacilityAtEndOfLeg, maxAdditionalDistanceToAttraction, coordOfAttraction);
+ if (!passangerInteractionAtParkingFacilityAtEndOfLeg)
+ checkIfDrivingToNextParkingLocationIsPossible(currentLinkId, baseLinkId, now, nextPickupTime);
+ }
+ if (actualRoute != null) {
+ actualRoute.setVehicleId(vehicleId);
}
//if no possible parking was found. The vehicle takes a random next link. Background assumption: parking only at given parking slots
if (actualRoute == null) {
@@ -111,6 +122,20 @@ public Id getNextLink(Id currentLinkId, Id baseLinkId, Id baseLinkId, Coord coordOfAttraction) {
+ for (ActivityFacility activityFacility : activityFacilities.values()) {
+ if (activityFacility.getLinkId().equals(baseLinkId))
+ distanceFromBaseToAttraction = NetworkUtils.getEuclideanDistance(activityFacility.getCoord(),
+ coordOfAttraction);
+ }
+ }
+
/**
* Checks if it is possible to drive to the new parking facility and to drive back to the base without extending the startTime of the following activity.
* If the resulting parking time at the new facility is less then 5 minutes the vehicle will drive directly to the next activity location.
@@ -175,7 +200,9 @@ public boolean isUseRandomLinkChoice() {
}
private NetworkRoute findRouteToNearestParkingFacility(Id baseLinkId, Id currentLinkId, boolean canCheckParkingCapacitiesInAdvanced,
- double now, double maxParkingDuration) {
+ double now, double maxParkingDuration,
+ boolean passangerInteractionAtParkingFacilityAtEndOfLeg, double maxDistanceFromBase,
+ Coord coordOfAttraction) {
TreeMap euclideanDistanceToParkingFacilities = new TreeMap<>();
ActivityFacility nearstActivityFacility = null;
NetworkRoute selectedRoute = null;
@@ -183,29 +210,31 @@ private NetworkRoute findRouteToNearestParkingFacility(Id baseLinkId, Id now || parkingOptions.getOpeningTimes().first().getEndTime() < latestEndOfParking)
- continue;
+ if (parkingOptions.getOpeningTimes().first().getStartTime() > now && parkingOptions.getOpeningTimes().first().getEndTime() < latestEndOfParking)
+ continue;
}
- //check if approx. the max parking time at facility will not exceed
+ //check if approx. the max parking time at facility will not exceed, assumption: "parking duration - 30 minutes" is parking Time.
if (activityFacility.getAttributes().getAsMap().containsKey("maxParkingDurationInHours")) { //TODO vielleicht etwas sparsamer machen
double maxParkingDurationAtFacility = 3600 * (double) activityFacility.getAttributes().getAsMap().get("maxParkingDurationInHours");
- if (maxParkingDuration > maxParkingDurationAtFacility)
+ if (maxParkingDuration - 30*60 > maxParkingDurationAtFacility)
continue;
- double expectedTravelTimeFromParkingToBase = getExpectedTravelTime(baseLinkId, now, activityFacility.getLinkId());
- double expectedTravelTimeFromCurrentToParking = getExpectedTravelTime(activityFacility.getLinkId(), now, currentLinkId);
- double expectedParkingTime = maxParkingDuration - expectedTravelTimeFromCurrentToParking - expectedTravelTimeFromParkingToBase;
- if (expectedParkingTime > maxParkingDurationAtFacility)
+ }
+
+ //TODO beschreiben was passiert
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg) {
+ double distanceBetweenThisParkingFacilityAndTheAttraction = NetworkUtils.getEuclideanDistance(activityFacility.getCoord(),
+ coordOfAttraction);
+ if (distanceBetweenThisParkingFacilityAndTheAttraction - distanceFromBaseToAttraction > maxDistanceFromBase)
continue;
}
// create Euclidean distances to the parking activities to find routes only to the nearest facilities in the next step
@@ -213,7 +242,11 @@ private NetworkRoute findRouteToNearestParkingFacility(Id baseLinkId, Id baseLinkId, Id maxParkingDurationAtFacility)
+ continue;
+ }
counter++;
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg && euclideanDistanceToParkingFacilities.size() > triedParking.size())
+ if (triedParking.contains(activityFacility.getId()))
+ continue;
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg && euclideanDistanceToParkingFacilities.size() == triedParking.size())
+ triedParking.clear();
NetworkRoute possibleRoute = this.parkingRouter.getRouteFromParkingToDestination(activityFacility.getLinkId(), now,
currentLinkId);
+ // reason is that we expect that the driver will always take the nearest possible getOff point to reduce the walk distance for the guests
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg){
+ selectedRoute = possibleRoute;
+ nearstActivityFacility = activityFacility;
+ break;
+ }
double travelTimeToParking = possibleRoute.getTravelTime().seconds();
double travelTimeFromParking = travelTimeToParking;
if (!baseLinkId.equals(currentLinkId)) {
@@ -276,6 +328,7 @@ public void reset() {
actualRoute = null;
currentLinkIdx = 0;
skipParkingActivity = false;
+ distanceFromBaseToAttraction = Double.NaN;
}
}