diff --git a/src/main/java/org/matsim/dashboards/LausitzSimWrapperRunner.java b/src/main/java/org/matsim/dashboards/LausitzSimWrapperRunner.java index 29e09b6..d0794b5 100644 --- a/src/main/java/org/matsim/dashboards/LausitzSimWrapperRunner.java +++ b/src/main/java/org/matsim/dashboards/LausitzSimWrapperRunner.java @@ -31,6 +31,7 @@ import org.matsim.simwrapper.SimWrapper; import org.matsim.simwrapper.SimWrapperConfigGroup; import org.matsim.simwrapper.dashboard.NoiseDashboard; +import org.matsim.simwrapper.dashboard.TripDashboard; import picocli.CommandLine; import java.io.IOException; @@ -54,6 +55,8 @@ public final class LausitzSimWrapperRunner implements MATSimAppCommand { @CommandLine.Option(names = "--noise", defaultValue = "false", description = "create noise dashboard") private boolean noise; + @CommandLine.Option(names = "--trips", defaultValue = "false", description = "create trips dashboard") + private boolean trips; public LausitzSimWrapperRunner(){ @@ -63,7 +66,7 @@ public LausitzSimWrapperRunner(){ @Override public Integer call() throws Exception { - if (!noise){ + if (!noise && !trips){ throw new IllegalArgumentException("you have not configured any dashboard to be created! Please use command line parameters!"); } @@ -83,7 +86,18 @@ public Integer call() throws Exception { //add dashboards according to command line parameters // if more dashboards are to be added here, we need to check if noise==true before adding noise dashboard here - sw.addDashboard(Dashboard.customize(new NoiseDashboard()).context("noise")); + if (noise) { + sw.addDashboard(Dashboard.customize(new NoiseDashboard()).context("noise")); + } + + if (trips) { + sw.addDashboard(new TripDashboard( + "lausitz_mode_share.csv", + "lausitz_mode_share_per_dist.csv", + "lausitz_mode_users.csv") + .withGroupedRefData("lausitz_mode_share_per_group_dist_ref.csv", "age", "economic_status", "income") + .withDistanceDistribution("lausitz_mode_share_distance_distribution.csv")); + } try { diff --git a/src/main/java/org/matsim/run/LausitzPtScenario.java b/src/main/java/org/matsim/run/LausitzPtScenario.java new file mode 100644 index 0000000..8c73028 --- /dev/null +++ b/src/main/java/org/matsim/run/LausitzPtScenario.java @@ -0,0 +1,216 @@ +package org.matsim.run; + +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.TransportMode; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.network.Node; +import org.matsim.application.MATSimApplication; +import org.matsim.core.config.Config; +import org.matsim.core.controler.Controler; +import org.matsim.core.network.NetworkUtils; +import org.matsim.core.population.routes.RouteUtils; +import org.matsim.pt.transitSchedule.api.*; +import org.matsim.vehicles.Vehicle; +import org.matsim.vehicles.VehicleType; +import org.matsim.vehicles.Vehicles; + +import javax.annotation.Nullable; +import java.util.*; + +/** + * Run the Lausitz scenario including a new regional rail transit line between hoyerswerda and cottbus. + * All necessary configs will be made in this class. + */ +public class LausitzPtScenario extends LausitzScenario { + + private final LausitzScenario baseScenario = new LausitzScenario(sample, emissions); + + public LausitzPtScenario(@Nullable Config config) { + super(config); + } + + public LausitzPtScenario(@Nullable String args) { + super(args); + } + + public LausitzPtScenario() { + super(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION)); + } + + public static void main(String[] args) { + MATSimApplication.run(LausitzPtScenario.class, args); + } + + @Nullable + @Override + protected Config prepareConfig(Config config) { + // apply all config changes from base scenario class + baseScenario.prepareConfig(config); + + return config; + } + + @Override + protected void prepareScenario(Scenario scenario) { + // apply all scenario changes from base scenario class + baseScenario.prepareScenario(scenario); + +// pt stops are basically nodes, BUT are assigned to links +// each pt stop is assigned a circle link to and from the same node. +// the first "real" link has the to and from node from the circle link as fromNode + +// create pt network nodes + Node hoyerswerda = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_regio_159285.8"), new Coord(863538.8869276098, 5711014.921688189)); + Node hoyerswerdaNeustadt = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_regio_135278.2"), new Coord(865993.0603089998, 5710758.211643816)); + Node spremberg = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_regio_315415.7"), new Coord(873850.5174500551,5727598.197541567)); + Node bagenz = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_short_2726.2"), new Coord(875299.1792959593,5736556.872374279)); + Node neuhausen = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_short_2476.2"), new Coord(874002.1110680653, 5740162.957866353)); + Node cottbus = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_short_5453.5"), new Coord(867315.8562388942, 5746748.406057102)); + +// create links first direction +// for speed and length deduction see internal documentation on drive + Link startLink1 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_0"), hoyerswerda, hoyerswerda, scenario.getNetwork(), 50., 0.1, 100000.0, 1.0); + Link link1 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_1"), hoyerswerda, hoyerswerdaNeustadt, scenario.getNetwork(), 2600., 2600./3*60, 100000.0, 1.0); + Link link2 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_2"), hoyerswerdaNeustadt, spremberg, scenario.getNetwork(), 30000., 20., 100000.0, 1.0); + Link link3 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_3"), spremberg, bagenz, scenario.getNetwork(), 10000., 10000./7*60, 100000.0, 1.0); + Link link4 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_4"), bagenz, neuhausen, scenario.getNetwork(), 4000., 4000./4*60, 100000.0, 1.0); + Link link5 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_5"), neuhausen, cottbus, scenario.getNetwork(), 10000., 10000./7*60, 100000.0, 1.0); + +// create links second direction + Link startLink2 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_6"), cottbus, cottbus, scenario.getNetwork(), 50., 0.1, 100000.0, 1.0); + Link link6 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_7"), cottbus, neuhausen, scenario.getNetwork(), 10000., 10000./7*60, 100000.0, 1.0); + Link link7 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_8"), neuhausen, bagenz, scenario.getNetwork(), 4000., 4000./4*60, 100000.0, 1.0); + Link link8 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_9"), bagenz, spremberg, scenario.getNetwork(), 10000., 10000./7*60, 100000.0, 1.0); + Link link9 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_10"), spremberg, hoyerswerdaNeustadt, scenario.getNetwork(), 30000., 20., 100000.0, 1.0); + Link link10 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_11"), hoyerswerdaNeustadt, hoyerswerda, scenario.getNetwork(), 2600., 2600./3*60, 100000.0, 1.0); + + TransitSchedule schedule = scenario.getTransitSchedule(); + TransitScheduleFactory fac = schedule.getFactory(); + TransitLine line = fac.createTransitLine(Id.create("RE-VSP1", TransitLine.class)); + + List transitInfoList = new ArrayList<>(); + +// map with all new pt links and their respective travel time + Map travelTimes = new HashMap<>(); + travelTimes.put(startLink1, startLink1.getLength() / startLink1.getFreespeed()); + travelTimes.put(startLink2, startLink2.getLength() / startLink2.getFreespeed()); + travelTimes.put(link1, link1.getLength() / link1.getFreespeed()); + travelTimes.put(link2, link2.getLength() / link2.getFreespeed()); + travelTimes.put(link3, link3.getLength() / link3.getFreespeed()); + travelTimes.put(link4, link4.getLength() / link4.getFreespeed()); + travelTimes.put(link5, link5.getLength() / link5.getFreespeed()); + travelTimes.put(link6, link6.getLength() / link6.getFreespeed()); + travelTimes.put(link7, link7.getLength() / link7.getFreespeed()); + travelTimes.put(link8, link8.getLength() / link8.getFreespeed()); + travelTimes.put(link9, link9.getLength() / link9.getFreespeed()); + travelTimes.put(link10, link10.getLength() / link10.getFreespeed()); + + int i = 0; + for (List linkList : List.of(List.of(startLink1, link1, link2, link3, link4, link5), List.of(startLink2, link6, link7, link8, link9, link10))) { + transitInfoList.add(configureTransitStops(linkList, scenario.getNetwork(), schedule, fac, i, travelTimes)); + i++; + } + + int j = 0; + for (TransitInfo info : transitInfoList) { + TransitRoute route = fac.createTransitRoute(Id.create(line.getId() + "_" + j, TransitRoute.class), RouteUtils.createNetworkRoute(info.links), info.transitStops, "rail"); + +// transit line should depart every hour to and from hoyerswerda +// transit lines cottbus - spremberg / - ruhland operate 4/5am - 11pm -> pick similar frequency, start and end of operation interval + +// create departures for each route + List departures; + if (j == 0) { +// hoyerswerda -> cottbus possible connection to re10/43 frankfurt(oder) (every hour at :02), to re2 berlin (every hour at :04) + departures = createDepartures(fac, info.travelTime, route, 2); + } else { +// cottbus -> hoyerswerda possible connection to re15 dresden (every hour at :33) and with 1 connection to Leipzig + departures = createDepartures(fac, info.travelTime, route, 33); + } + // create transit vehicle for each departure and add to transit vehicles + departures.forEach(d -> { + Vehicles vehicles = scenario.getTransitVehicles(); + VehicleType regio = vehicles.getVehicleTypes().get(Id.create("RE_RB_veh_type", VehicleType.class)); + Vehicle vehicle = vehicles.getFactory().createVehicle(Id.createVehicleId(d.getId().toString()), regio); + vehicles.addVehicle(vehicle); + d.setVehicleId(vehicle.getId()); + route.addDeparture(d); + }); + line.addRoute(route); + + j++; + } + schedule.addTransitLine(line); + } + + @Override + protected void prepareControler(Controler controler) { + // apply all controller changes from base scenario class + baseScenario.prepareControler(controler); +// TODO: add potential new Listeners here +// maybe a special controler for the new pt line would be handy?! + } + private TransitInfo configureTransitStops(List linkList, Network network, TransitSchedule schedule, TransitScheduleFactory fac, int count, Map travelTimes) { + List> links = new ArrayList<>(); + List stops = new ArrayList<>(); + + double travelTime = 0.; + + for (Link l : linkList) { + l.setAllowedModes(Set.of(TransportMode.pt)); + network.addLink(l); + + Node toNode = l.getToNode(); + +// create stop with to node id minus prefix pt_ + TransitStopFacility stopFac = fac.createTransitStopFacility(Id.create(toNode.getId().toString().substring(toNode.getId().toString().indexOf("pt_") + + "pt_".length()) + "_" + count, TransitStopFacility.class), toNode.getCoord(), false); + stopFac.setLinkId(l.getId()); + schedule.addStopFacility(stopFac); + + double arrivalDelay = 0.; + double departureDelay = 0.; + + if (!l.getId().toString().equals("pt_vsp_0") && !l.getId().toString().equals("pt_vsp_6")) { +// delay for fictive start links = 0, else see below + travelTime += travelTimes.get(l); + arrivalDelay = travelTime; + departureDelay = arrivalDelay + 60; + } + + TransitRouteStop stop = fac.createTransitRouteStop(stopFac, arrivalDelay, departureDelay); + stop.setAwaitDepartureTime(true); + stops.add(stop); + links.add(l.getId()); + } + return new TransitInfo(links, stops, travelTime); + } + + private List createDepartures(TransitScheduleFactory fac, double travelTime, TransitRoute route, int connectionTrainDeparture) { + List departures = new ArrayList<>(); + + for (int k = 0; k <= 24; k++) { + int arrival = (k * 60 + connectionTrainDeparture - 10) * 60; + +// no connection before 4am + if (arrival < 4 * 3600 || arrival > 24 * 3600) { + continue; + } + +// departure time = arrival - (travelTime - 1min per intermediate stop for entering / leaving passengers) +// departure id = route id + prefix pt_ and suffix consecutive number + double departureTime = arrival - (travelTime + (route.getStops().size() - 2) * 60.); + Departure departure = fac.createDeparture(Id.create("pt_" + route.getId() + "_" + k, Departure.class), departureTime); + departures.add(departure); + } + + return departures; + } + + private record TransitInfo(List> links, List transitStops, Double travelTime) { + + } +} diff --git a/src/main/java/org/matsim/run/LausitzScenario.java b/src/main/java/org/matsim/run/LausitzScenario.java index 4ecfbf7..b8b6dde 100644 --- a/src/main/java/org/matsim/run/LausitzScenario.java +++ b/src/main/java/org/matsim/run/LausitzScenario.java @@ -79,10 +79,10 @@ public class LausitzScenario extends MATSimApplication { private double alpha; @CommandLine.Mixin - private final SampleOptions sample = new SampleOptions( 100, 25, 10, 1); + SampleOptions sample = new SampleOptions( 100, 25, 10, 1); @CommandLine.Option(names = "--emissions", defaultValue = "PERFORM_EMISSIONS_ANALYSIS", description = "Define if emission analysis should be performed or not.") - private EmissionAnalysisHandling emissions; + EmissionAnalysisHandling emissions; public LausitzScenario(@Nullable Config config) { @@ -97,6 +97,11 @@ public LausitzScenario() { super(String.format("input/v1.1/lausitz-v1.1-10pct.config.xml", VERSION, VERSION)); } + public LausitzScenario(SampleOptions sample, EmissionAnalysisHandling handling) { + this.sample = sample; + this.emissions = handling; + } + public static void main(String[] args) { MATSimApplication.run(LausitzScenario.class, args); } diff --git a/src/main/java/org/matsim/run/RunLausitzPtScenario.java b/src/main/java/org/matsim/run/RunLausitzPtScenario.java index f38b3cf..0f40604 100644 --- a/src/main/java/org/matsim/run/RunLausitzPtScenario.java +++ b/src/main/java/org/matsim/run/RunLausitzPtScenario.java @@ -1,212 +1,17 @@ package org.matsim.run; -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.TransportMode; -import org.matsim.api.core.v01.network.Link; -import org.matsim.api.core.v01.network.Network; -import org.matsim.api.core.v01.network.Node; import org.matsim.application.MATSimApplication; -import org.matsim.core.config.Config; -import org.matsim.core.controler.Controler; -import org.matsim.core.network.NetworkUtils; -import org.matsim.core.population.routes.RouteUtils; -import org.matsim.pt.transitSchedule.api.*; -import org.matsim.vehicles.Vehicle; -import org.matsim.vehicles.VehicleType; -import org.matsim.vehicles.Vehicles; - -import javax.annotation.Nullable; -import java.util.*; /** - * Run the Lausitz scenario including a new regional rail transit line between hoyerswerda and cottbus. - * All necessary configs will be made in this class. + * Run the Lausitz PT scenario policy case. */ -public class RunLausitzPtScenario extends MATSimApplication { - - private final LausitzScenario baseScenario = new LausitzScenario(); +public final class RunLausitzPtScenario { - public RunLausitzPtScenario(@Nullable Config config) { - super(config); - } - - public RunLausitzPtScenario() { - super(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION)); + private RunLausitzPtScenario() { } public static void main(String[] args) { - MATSimApplication.run(RunLausitzPtScenario.class, args); - } - - @Nullable - @Override - protected Config prepareConfig(Config config) { - // apply all config changes from base scenario class - baseScenario.prepareConfig(config); - - return config; + MATSimApplication.execute(LausitzPtScenario.class, args); } - @Override - protected void prepareScenario(Scenario scenario) { - // apply all scenario changes from base scenario class - baseScenario.prepareScenario(scenario); - -// pt stops are basically nodes, BUT are assigned to links -// each pt stop is assigned a circle link to and from the same node. -// the first "real" link has the to and from node from the circle link as fromNode - -// create pt network nodes - Node hoyerswerda = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_regio_159285.8"), new Coord(863538.8869276098, 5711014.921688189)); - Node hoyerswerdaNeustadt = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_regio_135278.2"), new Coord(865993.0603089998, 5710758.211643816)); - Node spremberg = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_regio_315415.7"), new Coord(873850.5174500551,5727598.197541567)); - Node bagenz = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_short_2726.2"), new Coord(875299.1792959593,5736556.872374279)); - Node neuhausen = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_short_2476.2"), new Coord(874002.1110680653, 5740162.957866353)); - Node cottbus = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_short_5453.5"), new Coord(867315.8562388942, 5746748.406057102)); - -// create links first direction -// for speed and length deduction see internal documentation on drive - Link startLink1 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_0"), hoyerswerda, hoyerswerda, scenario.getNetwork(), 50., 0.1, 100000.0, 1.0); - Link link1 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_1"), hoyerswerda, hoyerswerdaNeustadt, scenario.getNetwork(), 2600., 2600./3*60, 100000.0, 1.0); - Link link2 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_2"), hoyerswerdaNeustadt, spremberg, scenario.getNetwork(), 30000., 20., 100000.0, 1.0); - Link link3 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_3"), spremberg, bagenz, scenario.getNetwork(), 10000., 10000./7*60, 100000.0, 1.0); - Link link4 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_4"), bagenz, neuhausen, scenario.getNetwork(), 4000., 4000./4*60, 100000.0, 1.0); - Link link5 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_5"), neuhausen, cottbus, scenario.getNetwork(), 10000., 10000./7*60, 100000.0, 1.0); - -// create links second direction - Link startLink2 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_6"), cottbus, cottbus, scenario.getNetwork(), 50., 0.1, 100000.0, 1.0); - Link link6 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_7"), cottbus, neuhausen, scenario.getNetwork(), 10000., 10000./7*60, 100000.0, 1.0); - Link link7 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_8"), neuhausen, bagenz, scenario.getNetwork(), 4000., 4000./4*60, 100000.0, 1.0); - Link link8 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_9"), bagenz, spremberg, scenario.getNetwork(), 10000., 10000./7*60, 100000.0, 1.0); - Link link9 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_10"), spremberg, hoyerswerdaNeustadt, scenario.getNetwork(), 30000., 20., 100000.0, 1.0); - Link link10 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_11"), hoyerswerdaNeustadt, hoyerswerda, scenario.getNetwork(), 2600., 2600./3*60, 100000.0, 1.0); - - TransitSchedule schedule = scenario.getTransitSchedule(); - TransitScheduleFactory fac = schedule.getFactory(); - TransitLine line = fac.createTransitLine(Id.create("RE-VSP1", TransitLine.class)); - - List transitInfoList = new ArrayList<>(); - -// map with all new pt links and their respective travel time - Map travelTimes = new HashMap<>(); - travelTimes.put(startLink1, startLink1.getLength() / startLink1.getFreespeed()); - travelTimes.put(startLink2, startLink2.getLength() / startLink2.getFreespeed()); - travelTimes.put(link1, link1.getLength() / link1.getFreespeed()); - travelTimes.put(link2, link2.getLength() / link2.getFreespeed()); - travelTimes.put(link3, link3.getLength() / link3.getFreespeed()); - travelTimes.put(link4, link4.getLength() / link4.getFreespeed()); - travelTimes.put(link5, link5.getLength() / link5.getFreespeed()); - travelTimes.put(link6, link6.getLength() / link6.getFreespeed()); - travelTimes.put(link7, link7.getLength() / link7.getFreespeed()); - travelTimes.put(link8, link8.getLength() / link8.getFreespeed()); - travelTimes.put(link9, link9.getLength() / link9.getFreespeed()); - travelTimes.put(link10, link10.getLength() / link10.getFreespeed()); - - int i = 0; - for (List linkList : List.of(List.of(startLink1, link1, link2, link3, link4, link5), List.of(startLink2, link6, link7, link8, link9, link10))) { - transitInfoList.add(configureTransitStops(linkList, scenario.getNetwork(), schedule, fac, i, travelTimes)); - i++; - } - - int j = 0; - for (TransitInfo info : transitInfoList) { - TransitRoute route = fac.createTransitRoute(Id.create(line.getId() + "_" + j, TransitRoute.class), RouteUtils.createNetworkRoute(info.links), info.transitStops, "rail"); - -// transit line should depart every hour to and from hoyerswerda -// transit lines cottbus - spremberg / - ruhland operate 4/5am - 11pm -> pick similar frequency, start and end of operation interval - -// create departures for each route - List departures; - if (j == 0) { -// hoyerswerda -> cottbus possible connection to re10/43 frankfurt(oder) (every hour at :02), to re2 berlin (every hour at :04) - departures = createDepartures(fac, info.travelTime, route, 2); - } else { -// cottbus -> hoyerswerda possible connection to re15 dresden (every hour at :33) and with 1 connection to Leipzig - departures = createDepartures(fac, info.travelTime, route, 33); - } - // create transit vehicle for each departure and add to transit vehicles - departures.forEach(d -> { - Vehicles vehicles = scenario.getTransitVehicles(); - VehicleType regio = vehicles.getVehicleTypes().get(Id.create("RE_RB_veh_type", VehicleType.class)); - Vehicle vehicle = vehicles.getFactory().createVehicle(Id.createVehicleId(d.getId().toString()), regio); - vehicles.addVehicle(vehicle); - d.setVehicleId(vehicle.getId()); - route.addDeparture(d); - }); - line.addRoute(route); - - j++; - } - schedule.addTransitLine(line); - } - - @Override - protected void prepareControler(Controler controler) { - // apply all controller changes from base scenario class - baseScenario.prepareControler(controler); -// TODO: add potential new Listeners here -// maybe a special controler for the new pt line would be handy?! - } - private TransitInfo configureTransitStops(List linkList, Network network, TransitSchedule schedule, TransitScheduleFactory fac, int count, Map travelTimes) { - List> links = new ArrayList<>(); - List stops = new ArrayList<>(); - - double travelTime = 0.; - - for (Link l : linkList) { - l.setAllowedModes(Set.of(TransportMode.pt)); - network.addLink(l); - - Node toNode = l.getToNode(); - -// create stop with to node id minus prefix pt_ - TransitStopFacility stopFac = fac.createTransitStopFacility(Id.create(toNode.getId().toString().substring(toNode.getId().toString().indexOf("pt_") - + "pt_".length()) + "_" + count, TransitStopFacility.class), toNode.getCoord(), false); - stopFac.setLinkId(l.getId()); - schedule.addStopFacility(stopFac); - - double arrivalDelay = 0.; - double departureDelay = 0.; - - if (!l.getId().toString().equals("pt_vsp_0") && !l.getId().toString().equals("pt_vsp_6")) { -// delay for fictive start links = 0, else see below - travelTime += travelTimes.get(l); - arrivalDelay = travelTime; - departureDelay = arrivalDelay + 60; - } - - TransitRouteStop stop = fac.createTransitRouteStop(stopFac, arrivalDelay, departureDelay); - stop.setAwaitDepartureTime(true); - stops.add(stop); - links.add(l.getId()); - } - return new TransitInfo(links, stops, travelTime); - } - - private List createDepartures(TransitScheduleFactory fac, double travelTime, TransitRoute route, int connectionTrainDeparture) { - List departures = new ArrayList<>(); - - for (int k = 0; k <= 24; k++) { - int arrival = (k * 60 + connectionTrainDeparture - 10) * 60; - -// no connection before 4am - if (arrival < 4 * 3600 || arrival > 24 * 3600) { - continue; - } - -// departure time = arrival - (travelTime - 1min per intermediate stop for entering / leaving passengers) -// departure id = route id + prefix pt_ and suffix consecutive number - double departureTime = arrival - (travelTime + (route.getStops().size() - 2) * 60.); - Departure departure = fac.createDeparture(Id.create("pt_" + route.getId() + "_" + k, Departure.class), departureTime); - departures.add(departure); - } - - return departures; - } - - private record TransitInfo(List> links, List transitStops, Double travelTime) { - - } } diff --git a/src/main/java/org/matsim/run/analysis/PtLineAnalysis.java b/src/main/java/org/matsim/run/analysis/PtLineAnalysis.java new file mode 100644 index 0000000..b527005 --- /dev/null +++ b/src/main/java/org/matsim/run/analysis/PtLineAnalysis.java @@ -0,0 +1,70 @@ +package org.matsim.run.analysis; + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.events.PersonEntersVehicleEvent; +import org.matsim.api.core.v01.events.handler.PersonEntersVehicleEventHandler; +import org.matsim.api.core.v01.population.Person; +import org.matsim.application.MATSimAppCommand; +import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.events.EventsUtils; +import org.matsim.core.events.MatsimEventsReader; +import picocli.CommandLine; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; + +@CommandLine.Command( + name = "pt-line", + description = "Get all agents who use the newly created pt line." +) +public class PtLineAnalysis implements MATSimAppCommand { + + @CommandLine.Option(names = "--events", description = "Events to be analyzed.", required = true) + private String eventsFile; + + @CommandLine.Option(names = "--output", description = "Output path", required = true) + private String outputPath; + + Map, Double> ptPersons = new HashMap<>(); + + public static void main(String[] args) { + new PtLineAnalysis().execute(args); + } + + @Override + public Integer call() throws Exception { + + EventsManager manager = EventsUtils.createEventsManager(); + manager.addHandler(new PersonEntersPtVehicleEventHandler()); + manager.initProcessing(); + + MatsimEventsReader reader = new MatsimEventsReader(manager); + reader.readFile(eventsFile); + manager.finishProcessing(); + + try (CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(Path.of(outputPath)), CSVFormat.DEFAULT)) { + printer.printRecord("person", "time"); + for (Map.Entry, Double> e : ptPersons.entrySet()) { + printer.printRecord(e.getKey().toString(), e.getValue()); + } + } + + return 0; + } + + + private final class PersonEntersPtVehicleEventHandler implements PersonEntersVehicleEventHandler { + @Override + public void handleEvent(PersonEntersVehicleEvent event) { + if (event.getVehicleId().toString().contains("RE-VSP1")) { + if (!event.getPersonId().toString().contains("pt_")) { + ptPersons.put(event.getPersonId(), event.getTime()); + } + } + } + } +} diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java index a172498..10f2f79 100644 --- a/src/test/java/org/matsim/run/RunIntegrationTest.java +++ b/src/test/java/org/matsim/run/RunIntegrationTest.java @@ -119,7 +119,7 @@ void runScenarioIncludingAdditionalPtLine() { new PopulationWriter(population).write(inputPath.toString()); - assert MATSimApplication.execute(RunLausitzPtScenario.class, config, + assert MATSimApplication.execute(LausitzPtScenario.class, config, "--1pct", "--iterations", "1", "--output", utils.getOutputDirectory(),