diff --git a/CHANGELOG.md b/CHANGELOG.md index 9545c2e..30ae61c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ included in the (note yet determined) next version number. - No changes yet +**Version 1.0.2** + +- Added output that contains all rentals + **Version 1.0.1** - Fix the issue where vehicles are returned to the pickup instead of the drop-off station for station absed service diff --git a/README.md b/README.md index cd6ab57..d752e52 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ Main reference: ## Versioning and Packging -The current version of `matsim-sharing` is `1.0.1` and is based on MATSim `13.0`. You can access it through the `v1.0.1` tag. The -`master` branch is kept at version `1.0.1` until the next release is prepared, +The current version of `matsim-sharing` is `1.0.2` and is based on MATSim `13.0`. You can access it through the `v1.0.2` tag. The +`master` branch is kept at version `1.0.2` until the next release is prepared, but may include additional developments since the last release. The code is available as a Maven package. To use it, add the following repository @@ -39,6 +39,6 @@ Afterwards, you can add the following dependency to your project: org.matsim.contrib sharing - 1.0.1 + 1.0.2 ``` diff --git a/pom.xml b/pom.xml index c20d043..1cd79cd 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.matsim.contrib sharing - 1.0.1 + 1.0.2 UTF-8 diff --git a/src/main/java/org/matsim/contrib/sharing/analysis/SharingTeleportedControlerListener.java b/src/main/java/org/matsim/contrib/sharing/analysis/SharingTeleportedControlerListener.java new file mode 100644 index 0000000..062ad3c --- /dev/null +++ b/src/main/java/org/matsim/contrib/sharing/analysis/SharingTeleportedControlerListener.java @@ -0,0 +1,76 @@ +package org.matsim.contrib.sharing.analysis; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.util.Set; + +import org.matsim.contrib.sharing.service.RentalInfo; +import org.matsim.contrib.sharing.service.SharingTeleportedRentalsHandler; +import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.controler.events.IterationEndsEvent; +import org.matsim.core.controler.events.StartupEvent; +import org.matsim.core.controler.listener.IterationEndsListener; +import org.matsim.core.controler.listener.StartupListener; +import org.matsim.core.utils.io.IOUtils; + +import com.google.inject.Inject; + +public class SharingTeleportedControlerListener implements StartupListener, IterationEndsListener { + + private final SharingTeleportedRentalsHandler sharingHandler; + private final EventsManager eventsManager; + private String serviceid; + + @Inject + public SharingTeleportedControlerListener(SharingTeleportedRentalsHandler sharingHandler, + EventsManager eventsManager, String serviceid) { + this.sharingHandler = sharingHandler; + this.eventsManager = eventsManager; + this.serviceid = serviceid; + + } + + @Override + public void notifyStartup(StartupEvent event) { + + this.eventsManager.addHandler(this.sharingHandler); + + } + + public void notifyIterationEnds(IterationEndsEvent event) { + + if (event.getIteration() > 0) { + // write all data gathered in csv files + String path = event.getServices().getControlerIO().getIterationPath(event.getIteration()) + + "/sharingrentals_" + serviceid + ".csv"; + + Set rentals = this.sharingHandler.getRentals(); + try { + // Because we want to write to CSV we would use the generic bufferred writer and + // specify the csv file name + BufferedWriter writer = IOUtils.getBufferedWriter(path); + writer.write( + "personid;starttime;endtime;distancedriven;pickupstationid;pickupstationlinkid;dropoffstationid;dropoffstationlinkid;" + + "vehicleid;serviceid\n"); + for (RentalInfo rental : rentals) { + + writer.write(String.join(";", rental.personId.toString(), Double.toString(rental.startTime), + Double.toString(rental.endTime), Double.toString(rental.distance), rental.pickupStationId, + rental.pickupLinkId.toString(), rental.dropoffStationId, rental.dropoffLinkId.toString(), + rental.vehicleId, rental.serviceId.toString())); + writer.newLine(); + } + // flush() tells the Writer to output the stream + writer.flush(); + + // it is good practice to close the stream when no more output is expected + writer.close(); + + } catch (IOException e) { + + e.printStackTrace(); + } + } + } + +} diff --git a/src/main/java/org/matsim/contrib/sharing/run/SharingServiceModule.java b/src/main/java/org/matsim/contrib/sharing/run/SharingServiceModule.java index f8d4141..7829333 100644 --- a/src/main/java/org/matsim/contrib/sharing/run/SharingServiceModule.java +++ b/src/main/java/org/matsim/contrib/sharing/run/SharingServiceModule.java @@ -6,6 +6,7 @@ import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.network.Network; import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; +import org.matsim.contrib.sharing.analysis.SharingTeleportedControlerListener; import org.matsim.contrib.sharing.io.DefaultSharingServiceSpecification; import org.matsim.contrib.sharing.io.SharingServiceReader; import org.matsim.contrib.sharing.io.SharingServiceSpecification; @@ -28,6 +29,7 @@ import com.google.inject.Singleton; + public class SharingServiceModule extends AbstractDvrpModeModule { private final SharingServiceConfigGroup serviceConfig; public SharingServiceModule(SharingServiceConfigGroup serviceConfig) { @@ -112,9 +114,17 @@ public void install() { } else { - addEventHandlerBinding().toProvider(modalProvider(getter -> { + bindModal(SharingTeleportedRentalsHandler.class).toProvider(modalProvider(getter -> { EventsManager eventsManager = getter.get(EventsManager.class); return new SharingTeleportedRentalsHandler(eventsManager, serviceConfig); + })).in(Singleton.class); + + // addEventHandlerBinding().to(modalKey(SharingTeleportedRentalsHandler.class)); + + addControlerListenerBinding().toProvider(modalProvider(getter -> { + EventsManager eventsManager = getter.get(EventsManager.class); + SharingTeleportedRentalsHandler sharingHandler = getter.getModal(SharingTeleportedRentalsHandler.class); + return new SharingTeleportedControlerListener(sharingHandler, eventsManager, SharingUtils.getServiceMode(serviceConfig)); })); } diff --git a/src/main/java/org/matsim/contrib/sharing/service/RentalInfo.java b/src/main/java/org/matsim/contrib/sharing/service/RentalInfo.java new file mode 100644 index 0000000..32d7bd2 --- /dev/null +++ b/src/main/java/org/matsim/contrib/sharing/service/RentalInfo.java @@ -0,0 +1,35 @@ +package org.matsim.contrib.sharing.service; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.population.Person; + +public class RentalInfo { + + public double startTime; + public double endTime; + public double distance; + public Id serviceId; + public Id personId; + public Id pickupLinkId; + public Id dropoffLinkId; + + public String vehicleId; + public String pickupStationId; + public String dropoffStationId; + + public RentalInfo(double starttime, double endtime, Id serviceId, Id personId, Id pickupLinkId, + Id dropoffLinkId, String vehicleId, String pickupstationId, + String dropoffstationId, double distance) { + this.startTime = starttime; + this.endTime = endtime; + this.distance = distance; + this.serviceId = serviceId; + this.personId = personId; + this.pickupLinkId = pickupLinkId; + this.dropoffLinkId = dropoffLinkId; + this.vehicleId = vehicleId; + this.pickupStationId = pickupstationId; + this.dropoffStationId = dropoffstationId; + } +} diff --git a/src/main/java/org/matsim/contrib/sharing/service/SharingTeleportedRentalsHandler.java b/src/main/java/org/matsim/contrib/sharing/service/SharingTeleportedRentalsHandler.java index 742e9c0..9297547 100644 --- a/src/main/java/org/matsim/contrib/sharing/service/SharingTeleportedRentalsHandler.java +++ b/src/main/java/org/matsim/contrib/sharing/service/SharingTeleportedRentalsHandler.java @@ -1,7 +1,9 @@ package org.matsim.contrib.sharing.service; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.PersonMoneyEvent; @@ -23,6 +25,7 @@ public class SharingTeleportedRentalsHandler private SharingServiceConfigGroup serviceParams; private Map, SharingPickupEvent> pickups = new HashMap<>(); private Map, Double> distance = new HashMap<>(); + private Set rentals = new HashSet<>(); public static final String PERSON_MONEY_EVENT_PURPOSE_SHARING_FARE = "sharingFare"; @@ -70,15 +73,29 @@ public void handleEvent(SharingDropoffEvent event) { eventsManager.processEvent(new PersonMoneyEvent(event.getTime(), event.getPersonId(), -sharedFare, PERSON_MONEY_EVENT_PURPOSE_SHARING_FARE, event.getServiceId().toString())); - this.distance.remove(event.getPersonId()); + SharingPickupEvent pickupEvent = this.pickups.get(event.getPersonId()); + + RentalInfo rentalInfo = new RentalInfo(pickupEvent.getTime(), event.getTime(), event.getServiceId(), + event.getPersonId(), pickupEvent.getLinkId(), event.getLinkId(), + pickupEvent.getAttributes().get("vehicle"), pickupEvent.getAttributes().get("station"), + event.getAttributes().get("station"), this.distance.get(event.getPersonId())); + this.rentals.add(rentalInfo); + this.pickups.remove(event.getPersonId()); + this.distance.remove(event.getPersonId()); + } } + + public Set getRentals() { + return this.rentals; + } @Override public void reset(int iteration) { pickups.clear(); distance.clear(); + rentals.clear(); } }