From 3530b6964ebef6d6894b7c27080a452fa3055987 Mon Sep 17 00:00:00 2001 From: Chengqi Lu <43133404+luchengqi7@users.noreply.github.com> Date: Mon, 5 Aug 2024 17:01:06 +0200 Subject: [PATCH 01/34] Add necessary setup for DRT estimate and teleportation --- .../org/matsim/run/RunLausitzDrtScenario.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java index fbec143..29dd7ca 100644 --- a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java +++ b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java @@ -7,6 +7,7 @@ import org.matsim.api.core.v01.network.Link; import org.matsim.application.MATSimApplication; import org.matsim.application.options.ShpOptions; +import org.matsim.contrib.drt.estimator.DrtEstimatorModule; import org.matsim.contrib.drt.optimizer.constraints.DefaultDrtOptimizationConstraintsSet; import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsParams; import org.matsim.contrib.drt.optimizer.insertion.extensive.ExtensiveInsertionSearchParams; @@ -24,6 +25,7 @@ import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.config.groups.SubtourModeChoiceConfigGroup; +import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.network.algorithms.MultimodalNetworkCleaner; import org.matsim.core.utils.geometry.geotools.MGC; @@ -98,6 +100,11 @@ protected Config prepareConfig(Config config) { multiModeDrtConfigGroup.addParameterSet(drtConfigGroup); } + // set to drt estimate and teleport + for (DrtConfigGroup drtConfigGroup : multiModeDrtConfigGroup.getModalElements()) { + drtConfigGroup.simulationType = DrtConfigGroup.SimulationType.estimateAndTeleport; + } + // this is needed for DynAgents for DVRP config.qsim().setSimStarttimeInterpretation(QSimConfigGroup.StarttimeInterpretation.onlyUseStarttime); @@ -174,6 +181,7 @@ protected void prepareScenario(Scenario scenario) { //TODO: is the following if clause needed when using the DRT Estimator?! // TODO: @CL where does the estimator draw its vehicles from? Are vehicle types even needed? + // --> No vehicle file is needed if DRT estimator is used. But the vehicle file can be specified as usual. // if there are no vehicles of above type: add some if (scenario.getVehicles().getVehicles().values().stream().filter(v -> v.getType().getId().equals(drtTypeId)).toList().isEmpty()) { @@ -195,6 +203,8 @@ protected void prepareScenario(Scenario scenario) { protected void prepareControler(Controler controler) { // TODO + Config config = controler.getConfig(); + // apply all controller changes from base scenario class baseScenario.prepareControler(controler); @@ -206,7 +216,23 @@ protected void prepareControler(Controler controler) { // this is necessary for drt / dvrp to work! controler.configureQSimComponents(DvrpQSimComponents.activateAllModes(ConfigUtils.addOrGetModule(controler.getConfig(), MultiModeDrtConfigGroup.class))); - + MultiModeDrtConfigGroup multiModeDrtConfigGroup = MultiModeDrtConfigGroup.get(config); + for (DrtConfigGroup drtConfigGroup : multiModeDrtConfigGroup.getModalElements()) { + // TODO uncomment theses after the new estimator is merged to the matsim-lib master branch +// controler.addOverridingModule(new AbstractModule() { +// @Override +// public void install() { +// DrtEstimatorModule.bindEstimator(binder(), drtConfigGroup.mode).toInstance( +// new DirectTripBasedDrtEstimator.Builder() +// .setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(meanWaitTime)) +// .setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, waitTimeStd)) +// .setRideDurationEstimator(new ConstantRideDurationEstimator(rideTimeAlpha, rideTimeBeta)) +// .setRideDurationDistributionGenerator(new NormalDistributionGenerator(2, rideTimeStd)) +// .build() +// ); +// } +// }); + } } } From 7acdaa5a29dc0e512f313e4dc176de1900c0b14b Mon Sep 17 00:00:00 2001 From: Chengqi Lu <43133404+luchengqi7@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:10:10 +0200 Subject: [PATCH 02/34] upgrade matsim version In order to include DRT estimation model --- pom.xml | 2 +- .../org/matsim/run/RunLausitzDrtScenario.java | 45 +++++++++++++------ 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index 9599da4..2c5c4ec 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ - 2025.0-PR3340 + 2025.0-PR3333 diff --git a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java index 29dd7ca..07e43a8 100644 --- a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java +++ b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java @@ -8,6 +8,10 @@ import org.matsim.application.MATSimApplication; import org.matsim.application.options.ShpOptions; import org.matsim.contrib.drt.estimator.DrtEstimatorModule; +import org.matsim.contrib.drt.estimator.impl.DirectTripBasedDrtEstimator; +import org.matsim.contrib.drt.estimator.impl.distribution.NormalDistributionGenerator; +import org.matsim.contrib.drt.estimator.impl.trip_estimation.ConstantRideDurationEstimator; +import org.matsim.contrib.drt.estimator.impl.waiting_time_estimation.ConstantWaitingTimeEstimator; import org.matsim.contrib.drt.optimizer.constraints.DefaultDrtOptimizationConstraintsSet; import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsParams; import org.matsim.contrib.drt.optimizer.insertion.extensive.ExtensiveInsertionSearchParams; @@ -48,6 +52,21 @@ public final class RunLausitzDrtScenario extends MATSimApplication { @CommandLine.Option(names = "--drt-shp", description = "Path to shp file for adding drt not network links as an allowed mode.", defaultValue = "./input/shp/lausitz.shp") private String drtAreaShp; + @CommandLine.Option(names = "--typ-wt", description = "typical waiting time", defaultValue = "300") + private double typicalWaitTime; + + @CommandLine.Option(names = "--wt-std", description = "waiting time standard deviation", defaultValue = "0.3") + private double waitTimeStd; + + @CommandLine.Option(names = "--ride-time-alpha", description = "ride time estimator alpha", defaultValue = "1.25") + private double rideTimeAlpha; + + @CommandLine.Option(names = "--ride-time-beta", description = "ride time estimator beta", defaultValue = "300") + private double rideTimeBeta; + + @CommandLine.Option(names = "--ride-time-std", description = "ride duration standard deviation", defaultValue = "0.3") + private double rideTimeStd; + private final LausitzScenario baseScenario = new LausitzScenario(); public RunLausitzDrtScenario() { @@ -219,19 +238,19 @@ protected void prepareControler(Controler controler) { MultiModeDrtConfigGroup multiModeDrtConfigGroup = MultiModeDrtConfigGroup.get(config); for (DrtConfigGroup drtConfigGroup : multiModeDrtConfigGroup.getModalElements()) { // TODO uncomment theses after the new estimator is merged to the matsim-lib master branch -// controler.addOverridingModule(new AbstractModule() { -// @Override -// public void install() { -// DrtEstimatorModule.bindEstimator(binder(), drtConfigGroup.mode).toInstance( -// new DirectTripBasedDrtEstimator.Builder() -// .setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(meanWaitTime)) -// .setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, waitTimeStd)) -// .setRideDurationEstimator(new ConstantRideDurationEstimator(rideTimeAlpha, rideTimeBeta)) -// .setRideDurationDistributionGenerator(new NormalDistributionGenerator(2, rideTimeStd)) -// .build() -// ); -// } -// }); + controler.addOverridingModule(new AbstractModule() { + @Override + public void install() { + DrtEstimatorModule.bindEstimator(binder(), drtConfigGroup.mode).toInstance( + new DirectTripBasedDrtEstimator.Builder() + .setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(typicalWaitTime)) + .setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, waitTimeStd)) + .setRideDurationEstimator(new ConstantRideDurationEstimator(rideTimeAlpha, rideTimeBeta)) + .setRideDurationDistributionGenerator(new NormalDistributionGenerator(2, rideTimeStd)) + .build() + ); + } + }); } } From f0c0d2032f0df89e0d3d0ecd149ad929752fc7be Mon Sep 17 00:00:00 2001 From: sime94 Date: Thu, 29 Aug 2024 16:25:58 +0200 Subject: [PATCH 03/34] try to make first test run --- .../org/matsim/run/RunLausitzDrtScenario.java | 49 +++++-------------- .../org/matsim/run/RunIntegrationTest.java | 2 +- 2 files changed, 14 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java index 07e43a8..bbf4b9f 100644 --- a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java +++ b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java @@ -82,27 +82,21 @@ public static void main(String[] args) { @Nullable @Override protected Config prepareConfig(Config config) { -// TODO: have a look in config.xml if there is more configs to be adapted to make it "ready" for drt -> do this here -// TODO: add drt stops / shp file here?! OR create stops / shp in code?! -// TODO: add drt to mdoeparams, add as network mode, add as main mode? add to SMC, add to scoring params?! -// TODO: add drt speedup params, add drt fare params?! - -// TODO: talk to CL about whether to use new drt approach (see kelheim) or not.. and how to implement it - // apply all config changes from base scenario class baseScenario.prepareConfig(config); DvrpConfigGroup dvrpConfigGroup = ConfigUtils.addOrGetModule(config, DvrpConfigGroup.class); dvrpConfigGroup.networkModes = Set.of(TransportMode.drt); + + MultiModeDrtConfigGroup multiModeDrtConfigGroup = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); if (multiModeDrtConfigGroup.getModalElements().isEmpty()) { DrtConfigGroup drtConfigGroup = new DrtConfigGroup(); - drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.stopbased; + drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.serviceAreaBased; drtConfigGroup.stopDuration = 60.; -// TODO: shp files have been created and are located on sjhared svn - drtConfigGroup.transitStopFile = ""; + drtConfigGroup.drtServiceAreaShapeFile = drtAreaShp; // optimization params now are in its own paramSet, hence the below lines DrtOptimizationConstraintsParams optimizationConstraints = new DrtOptimizationConstraintsParams(); @@ -113,9 +107,6 @@ protected Config prepareConfig(Config config) { optimizationConstraints.addParameterSet(optimizationConstraintsSet); drtConfigGroup.addParameterSet(optimizationConstraints); drtConfigGroup.addParameterSet(new ExtensiveInsertionSearchParams()); -// TODO: talk to KN whether to put in fare params here.. logic could be: we assume that everybody has a Deutschlandticket so no fare at all is charged?! -// this may draw more than the costumer, who want to take the train in Ruhland?! So maybe it makes sense to apply a baseFare and give it back to the agents after the sim via person money event? -// OR just put in drt fare via scoring mode params multiModeDrtConfigGroup.addParameterSet(drtConfigGroup); } @@ -130,7 +121,7 @@ protected Config prepareConfig(Config config) { ScoringConfigGroup scoringConfigGroup = ConfigUtils.addOrGetModule(config, ScoringConfigGroup.class); if (!scoringConfigGroup.getModes().containsKey(TransportMode.drt)) { -// TODO: talk to KN about this ASC value. Either set it equal to PT or 0?? +// ASC drt = ASC pt as discussed in PHD seminar24 // add mode params for drt if missing and set ASC + marg utility of traveling = 0 scoringConfigGroup.addModeParams(new ScoringConfigGroup.ModeParams(TransportMode.drt) .setConstant(scoringConfigGroup.getModes().get(TransportMode.pt).getConstant()) @@ -154,8 +145,6 @@ protected Config prepareConfig(Config config) { @Override protected void prepareScenario(Scenario scenario) { -// TODO - // apply all scenario changes from base scenario class baseScenario.prepareScenario(scenario); @@ -168,6 +157,8 @@ protected void prepareScenario(Scenario scenario) { // add drt as allowed mode for whole Lausitz region Geometry geometry = new ShpOptions(drtAreaShp, null, null).getGeometry(); +// with the estimator, drt is teleported, but we may need drt as an allowed mode for +// separate drt post simulation for (Link link : scenario.getNetwork().getLinks().values()) { if (link.getAllowedModes().contains(TransportMode.car)) { boolean isInside = MGC.coord2Point(link.getFromNode().getCoord()).within(geometry) || @@ -196,32 +187,19 @@ protected void prepareScenario(Scenario scenario) { capacity.setSeats(1); scenario.getVehicles().addVehicleType(drtType); - } - -//TODO: is the following if clause needed when using the DRT Estimator?! -// TODO: @CL where does the estimator draw its vehicles from? Are vehicle types even needed? - // --> No vehicle file is needed if DRT estimator is used. But the vehicle file can be specified as usual. - // if there are no vehicles of above type: add some - if (scenario.getVehicles().getVehicles().values().stream().filter(v -> v.getType().getId().equals(drtTypeId)).toList().isEmpty()) { - - for (int i = 1; i <= 10; i++) { - Vehicle vehicle = VehicleUtils.createVehicle(Id.createVehicleId(TransportMode.drt + "_" + i), scenario.getVehicles().getVehicleTypes().get(drtTypeId)); - vehicle.getAttributes().putAttribute("dvrpMode", TransportMode.drt); -// TODO: put linkId - vehicle.getAttributes().putAttribute("startLink", "ABC"); - vehicle.getAttributes().putAttribute("serviceBeginTime", 0.); - vehicle.getAttributes().putAttribute("serviceEndTime", 86400.); - scenario.getVehicles().addVehicle(vehicle); - } + Vehicle drtDummy = VehicleUtils.createVehicle(Id.createVehicleId("drtDummy"), drtType); + drtDummy.getAttributes().putAttribute("dvrpMode", TransportMode.drt); + drtDummy.getAttributes().putAttribute("startLink", "706048410#0"); + drtDummy.getAttributes().putAttribute("serviceBeginTime", 0.); + drtDummy.getAttributes().putAttribute("serviceEndTime", 86400.); + scenario.getVehicles().addVehicle(drtDummy); } } @Override protected void prepareControler(Controler controler) { -// TODO - Config config = controler.getConfig(); // apply all controller changes from base scenario class @@ -237,7 +215,6 @@ protected void prepareControler(Controler controler) { MultiModeDrtConfigGroup multiModeDrtConfigGroup = MultiModeDrtConfigGroup.get(config); for (DrtConfigGroup drtConfigGroup : multiModeDrtConfigGroup.getModalElements()) { - // TODO uncomment theses after the new estimator is merged to the matsim-lib master branch controler.addOverridingModule(new AbstractModule() { @Override public void install() { diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java index 83e0d75..da309c4 100644 --- a/src/test/java/org/matsim/run/RunIntegrationTest.java +++ b/src/test/java/org/matsim/run/RunIntegrationTest.java @@ -61,11 +61,11 @@ void runScenarioIncludingDrt() { assert MATSimApplication.execute(RunLausitzDrtScenario.class, config, "--1pct", + "--drt-shp", "C:/Users/Simon/Documents/vsp-projects/matsim-lausitz/input/shp/lausitz.shp", "--iterations", "1", "--config:plans.inputPlansFile", "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/lausitz/input/v1.0/lausitz-v1.0-1pct.plans-initial.xml.gz", "--output", utils.getOutputDirectory(), "--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code"; - } @Test From dac01369c8d2ac4affce574b6f8686e1b1f7b993 Mon Sep 17 00:00:00 2001 From: Chengqi Lu <43133404+luchengqi7@users.noreply.github.com> Date: Mon, 5 Aug 2024 17:01:06 +0200 Subject: [PATCH 04/34] Add necessary setup for DRT estimate and teleportation --- .../org/matsim/run/RunLausitzDrtScenario.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java index fbec143..29dd7ca 100644 --- a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java +++ b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java @@ -7,6 +7,7 @@ import org.matsim.api.core.v01.network.Link; import org.matsim.application.MATSimApplication; import org.matsim.application.options.ShpOptions; +import org.matsim.contrib.drt.estimator.DrtEstimatorModule; import org.matsim.contrib.drt.optimizer.constraints.DefaultDrtOptimizationConstraintsSet; import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsParams; import org.matsim.contrib.drt.optimizer.insertion.extensive.ExtensiveInsertionSearchParams; @@ -24,6 +25,7 @@ import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.config.groups.SubtourModeChoiceConfigGroup; +import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.network.algorithms.MultimodalNetworkCleaner; import org.matsim.core.utils.geometry.geotools.MGC; @@ -98,6 +100,11 @@ protected Config prepareConfig(Config config) { multiModeDrtConfigGroup.addParameterSet(drtConfigGroup); } + // set to drt estimate and teleport + for (DrtConfigGroup drtConfigGroup : multiModeDrtConfigGroup.getModalElements()) { + drtConfigGroup.simulationType = DrtConfigGroup.SimulationType.estimateAndTeleport; + } + // this is needed for DynAgents for DVRP config.qsim().setSimStarttimeInterpretation(QSimConfigGroup.StarttimeInterpretation.onlyUseStarttime); @@ -174,6 +181,7 @@ protected void prepareScenario(Scenario scenario) { //TODO: is the following if clause needed when using the DRT Estimator?! // TODO: @CL where does the estimator draw its vehicles from? Are vehicle types even needed? + // --> No vehicle file is needed if DRT estimator is used. But the vehicle file can be specified as usual. // if there are no vehicles of above type: add some if (scenario.getVehicles().getVehicles().values().stream().filter(v -> v.getType().getId().equals(drtTypeId)).toList().isEmpty()) { @@ -195,6 +203,8 @@ protected void prepareScenario(Scenario scenario) { protected void prepareControler(Controler controler) { // TODO + Config config = controler.getConfig(); + // apply all controller changes from base scenario class baseScenario.prepareControler(controler); @@ -206,7 +216,23 @@ protected void prepareControler(Controler controler) { // this is necessary for drt / dvrp to work! controler.configureQSimComponents(DvrpQSimComponents.activateAllModes(ConfigUtils.addOrGetModule(controler.getConfig(), MultiModeDrtConfigGroup.class))); - + MultiModeDrtConfigGroup multiModeDrtConfigGroup = MultiModeDrtConfigGroup.get(config); + for (DrtConfigGroup drtConfigGroup : multiModeDrtConfigGroup.getModalElements()) { + // TODO uncomment theses after the new estimator is merged to the matsim-lib master branch +// controler.addOverridingModule(new AbstractModule() { +// @Override +// public void install() { +// DrtEstimatorModule.bindEstimator(binder(), drtConfigGroup.mode).toInstance( +// new DirectTripBasedDrtEstimator.Builder() +// .setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(meanWaitTime)) +// .setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, waitTimeStd)) +// .setRideDurationEstimator(new ConstantRideDurationEstimator(rideTimeAlpha, rideTimeBeta)) +// .setRideDurationDistributionGenerator(new NormalDistributionGenerator(2, rideTimeStd)) +// .build() +// ); +// } +// }); + } } } From b2e1d907acd6bdc7391b55da0156589bfa439921 Mon Sep 17 00:00:00 2001 From: Chengqi Lu <43133404+luchengqi7@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:10:10 +0200 Subject: [PATCH 05/34] upgrade matsim version In order to include DRT estimation model --- .../org/matsim/run/RunLausitzDrtScenario.java | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java index 29dd7ca..07e43a8 100644 --- a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java +++ b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java @@ -8,6 +8,10 @@ import org.matsim.application.MATSimApplication; import org.matsim.application.options.ShpOptions; import org.matsim.contrib.drt.estimator.DrtEstimatorModule; +import org.matsim.contrib.drt.estimator.impl.DirectTripBasedDrtEstimator; +import org.matsim.contrib.drt.estimator.impl.distribution.NormalDistributionGenerator; +import org.matsim.contrib.drt.estimator.impl.trip_estimation.ConstantRideDurationEstimator; +import org.matsim.contrib.drt.estimator.impl.waiting_time_estimation.ConstantWaitingTimeEstimator; import org.matsim.contrib.drt.optimizer.constraints.DefaultDrtOptimizationConstraintsSet; import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsParams; import org.matsim.contrib.drt.optimizer.insertion.extensive.ExtensiveInsertionSearchParams; @@ -48,6 +52,21 @@ public final class RunLausitzDrtScenario extends MATSimApplication { @CommandLine.Option(names = "--drt-shp", description = "Path to shp file for adding drt not network links as an allowed mode.", defaultValue = "./input/shp/lausitz.shp") private String drtAreaShp; + @CommandLine.Option(names = "--typ-wt", description = "typical waiting time", defaultValue = "300") + private double typicalWaitTime; + + @CommandLine.Option(names = "--wt-std", description = "waiting time standard deviation", defaultValue = "0.3") + private double waitTimeStd; + + @CommandLine.Option(names = "--ride-time-alpha", description = "ride time estimator alpha", defaultValue = "1.25") + private double rideTimeAlpha; + + @CommandLine.Option(names = "--ride-time-beta", description = "ride time estimator beta", defaultValue = "300") + private double rideTimeBeta; + + @CommandLine.Option(names = "--ride-time-std", description = "ride duration standard deviation", defaultValue = "0.3") + private double rideTimeStd; + private final LausitzScenario baseScenario = new LausitzScenario(); public RunLausitzDrtScenario() { @@ -219,19 +238,19 @@ protected void prepareControler(Controler controler) { MultiModeDrtConfigGroup multiModeDrtConfigGroup = MultiModeDrtConfigGroup.get(config); for (DrtConfigGroup drtConfigGroup : multiModeDrtConfigGroup.getModalElements()) { // TODO uncomment theses after the new estimator is merged to the matsim-lib master branch -// controler.addOverridingModule(new AbstractModule() { -// @Override -// public void install() { -// DrtEstimatorModule.bindEstimator(binder(), drtConfigGroup.mode).toInstance( -// new DirectTripBasedDrtEstimator.Builder() -// .setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(meanWaitTime)) -// .setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, waitTimeStd)) -// .setRideDurationEstimator(new ConstantRideDurationEstimator(rideTimeAlpha, rideTimeBeta)) -// .setRideDurationDistributionGenerator(new NormalDistributionGenerator(2, rideTimeStd)) -// .build() -// ); -// } -// }); + controler.addOverridingModule(new AbstractModule() { + @Override + public void install() { + DrtEstimatorModule.bindEstimator(binder(), drtConfigGroup.mode).toInstance( + new DirectTripBasedDrtEstimator.Builder() + .setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(typicalWaitTime)) + .setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, waitTimeStd)) + .setRideDurationEstimator(new ConstantRideDurationEstimator(rideTimeAlpha, rideTimeBeta)) + .setRideDurationDistributionGenerator(new NormalDistributionGenerator(2, rideTimeStd)) + .build() + ); + } + }); } } From 78cbd4023b6423e44d00f8dc264179ede151e240 Mon Sep 17 00:00:00 2001 From: sime94 Date: Thu, 29 Aug 2024 16:25:58 +0200 Subject: [PATCH 06/34] try to make first test run --- .../org/matsim/run/RunLausitzDrtScenario.java | 49 +++++-------------- .../org/matsim/run/RunIntegrationTest.java | 2 +- 2 files changed, 14 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java index 07e43a8..bbf4b9f 100644 --- a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java +++ b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java @@ -82,27 +82,21 @@ public static void main(String[] args) { @Nullable @Override protected Config prepareConfig(Config config) { -// TODO: have a look in config.xml if there is more configs to be adapted to make it "ready" for drt -> do this here -// TODO: add drt stops / shp file here?! OR create stops / shp in code?! -// TODO: add drt to mdoeparams, add as network mode, add as main mode? add to SMC, add to scoring params?! -// TODO: add drt speedup params, add drt fare params?! - -// TODO: talk to CL about whether to use new drt approach (see kelheim) or not.. and how to implement it - // apply all config changes from base scenario class baseScenario.prepareConfig(config); DvrpConfigGroup dvrpConfigGroup = ConfigUtils.addOrGetModule(config, DvrpConfigGroup.class); dvrpConfigGroup.networkModes = Set.of(TransportMode.drt); + + MultiModeDrtConfigGroup multiModeDrtConfigGroup = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); if (multiModeDrtConfigGroup.getModalElements().isEmpty()) { DrtConfigGroup drtConfigGroup = new DrtConfigGroup(); - drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.stopbased; + drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.serviceAreaBased; drtConfigGroup.stopDuration = 60.; -// TODO: shp files have been created and are located on sjhared svn - drtConfigGroup.transitStopFile = ""; + drtConfigGroup.drtServiceAreaShapeFile = drtAreaShp; // optimization params now are in its own paramSet, hence the below lines DrtOptimizationConstraintsParams optimizationConstraints = new DrtOptimizationConstraintsParams(); @@ -113,9 +107,6 @@ protected Config prepareConfig(Config config) { optimizationConstraints.addParameterSet(optimizationConstraintsSet); drtConfigGroup.addParameterSet(optimizationConstraints); drtConfigGroup.addParameterSet(new ExtensiveInsertionSearchParams()); -// TODO: talk to KN whether to put in fare params here.. logic could be: we assume that everybody has a Deutschlandticket so no fare at all is charged?! -// this may draw more than the costumer, who want to take the train in Ruhland?! So maybe it makes sense to apply a baseFare and give it back to the agents after the sim via person money event? -// OR just put in drt fare via scoring mode params multiModeDrtConfigGroup.addParameterSet(drtConfigGroup); } @@ -130,7 +121,7 @@ protected Config prepareConfig(Config config) { ScoringConfigGroup scoringConfigGroup = ConfigUtils.addOrGetModule(config, ScoringConfigGroup.class); if (!scoringConfigGroup.getModes().containsKey(TransportMode.drt)) { -// TODO: talk to KN about this ASC value. Either set it equal to PT or 0?? +// ASC drt = ASC pt as discussed in PHD seminar24 // add mode params for drt if missing and set ASC + marg utility of traveling = 0 scoringConfigGroup.addModeParams(new ScoringConfigGroup.ModeParams(TransportMode.drt) .setConstant(scoringConfigGroup.getModes().get(TransportMode.pt).getConstant()) @@ -154,8 +145,6 @@ protected Config prepareConfig(Config config) { @Override protected void prepareScenario(Scenario scenario) { -// TODO - // apply all scenario changes from base scenario class baseScenario.prepareScenario(scenario); @@ -168,6 +157,8 @@ protected void prepareScenario(Scenario scenario) { // add drt as allowed mode for whole Lausitz region Geometry geometry = new ShpOptions(drtAreaShp, null, null).getGeometry(); +// with the estimator, drt is teleported, but we may need drt as an allowed mode for +// separate drt post simulation for (Link link : scenario.getNetwork().getLinks().values()) { if (link.getAllowedModes().contains(TransportMode.car)) { boolean isInside = MGC.coord2Point(link.getFromNode().getCoord()).within(geometry) || @@ -196,32 +187,19 @@ protected void prepareScenario(Scenario scenario) { capacity.setSeats(1); scenario.getVehicles().addVehicleType(drtType); - } - -//TODO: is the following if clause needed when using the DRT Estimator?! -// TODO: @CL where does the estimator draw its vehicles from? Are vehicle types even needed? - // --> No vehicle file is needed if DRT estimator is used. But the vehicle file can be specified as usual. - // if there are no vehicles of above type: add some - if (scenario.getVehicles().getVehicles().values().stream().filter(v -> v.getType().getId().equals(drtTypeId)).toList().isEmpty()) { - - for (int i = 1; i <= 10; i++) { - Vehicle vehicle = VehicleUtils.createVehicle(Id.createVehicleId(TransportMode.drt + "_" + i), scenario.getVehicles().getVehicleTypes().get(drtTypeId)); - vehicle.getAttributes().putAttribute("dvrpMode", TransportMode.drt); -// TODO: put linkId - vehicle.getAttributes().putAttribute("startLink", "ABC"); - vehicle.getAttributes().putAttribute("serviceBeginTime", 0.); - vehicle.getAttributes().putAttribute("serviceEndTime", 86400.); - scenario.getVehicles().addVehicle(vehicle); - } + Vehicle drtDummy = VehicleUtils.createVehicle(Id.createVehicleId("drtDummy"), drtType); + drtDummy.getAttributes().putAttribute("dvrpMode", TransportMode.drt); + drtDummy.getAttributes().putAttribute("startLink", "706048410#0"); + drtDummy.getAttributes().putAttribute("serviceBeginTime", 0.); + drtDummy.getAttributes().putAttribute("serviceEndTime", 86400.); + scenario.getVehicles().addVehicle(drtDummy); } } @Override protected void prepareControler(Controler controler) { -// TODO - Config config = controler.getConfig(); // apply all controller changes from base scenario class @@ -237,7 +215,6 @@ protected void prepareControler(Controler controler) { MultiModeDrtConfigGroup multiModeDrtConfigGroup = MultiModeDrtConfigGroup.get(config); for (DrtConfigGroup drtConfigGroup : multiModeDrtConfigGroup.getModalElements()) { - // TODO uncomment theses after the new estimator is merged to the matsim-lib master branch controler.addOverridingModule(new AbstractModule() { @Override public void install() { diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java index 3b1bd33..3224e0a 100644 --- a/src/test/java/org/matsim/run/RunIntegrationTest.java +++ b/src/test/java/org/matsim/run/RunIntegrationTest.java @@ -61,11 +61,11 @@ void runScenarioIncludingDrt() { assert MATSimApplication.execute(RunLausitzDrtScenario.class, config, "--1pct", + "--drt-shp", "C:/Users/Simon/Documents/vsp-projects/matsim-lausitz/input/shp/lausitz.shp", "--iterations", "1", "--config:plans.inputPlansFile", "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/lausitz/input/v1.1/lausitz-v1.1-1pct.plans-initial.xml.gz", "--output", utils.getOutputDirectory(), "--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code"; - } @Test From c47677e0c186e87b53b99fc625d76a0b46d76ad4 Mon Sep 17 00:00:00 2001 From: sime94 Date: Thu, 29 Aug 2024 16:54:34 +0200 Subject: [PATCH 07/34] add some todos --- src/main/java/org/matsim/run/RunLausitzDrtScenario.java | 9 +++------ src/test/java/org/matsim/run/RunIntegrationTest.java | 3 +++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java index bbf4b9f..75ec333 100644 --- a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java +++ b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java @@ -40,15 +40,14 @@ import picocli.CommandLine; import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import java.util.*; /** * Run the Lausitz scenario including a regional DRT service. * All necessary configs will be made in this class. */ public final class RunLausitzDrtScenario extends MATSimApplication { +// TODO: upload correct service area shp file to git @CommandLine.Option(names = "--drt-shp", description = "Path to shp file for adding drt not network links as an allowed mode.", defaultValue = "./input/shp/lausitz.shp") private String drtAreaShp; @@ -88,8 +87,6 @@ protected Config prepareConfig(Config config) { DvrpConfigGroup dvrpConfigGroup = ConfigUtils.addOrGetModule(config, DvrpConfigGroup.class); dvrpConfigGroup.networkModes = Set.of(TransportMode.drt); - - MultiModeDrtConfigGroup multiModeDrtConfigGroup = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); if (multiModeDrtConfigGroup.getModalElements().isEmpty()) { @@ -130,7 +127,7 @@ protected Config prepareConfig(Config config) { SubtourModeChoiceConfigGroup smc = ConfigUtils.addOrGetModule(config, SubtourModeChoiceConfigGroup.class); - if (String.join(",", smc.getModes()).contains(TransportMode.drt)) { + if (!String.join(",", smc.getModes()).contains(TransportMode.drt)) { String[] modes = Arrays.copyOf(smc.getModes(), smc.getModes().length + 1); modes[modes.length - 1] = TransportMode.drt; diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java index 3224e0a..e0b2eac 100644 --- a/src/test/java/org/matsim/run/RunIntegrationTest.java +++ b/src/test/java/org/matsim/run/RunIntegrationTest.java @@ -56,6 +56,9 @@ void runScenario() { @Test void runScenarioIncludingDrt() { + +// TODO: add dummy drt person. +// TODO: test smc with drt. THere has to be some person changing to drt before iteration1 Config config = ConfigUtils.loadConfig(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION)); ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class).defaultDashboards = SimWrapperConfigGroup.Mode.disabled; From 700e9dee23a244fd552d00b97f5cecd328a8853e Mon Sep 17 00:00:00 2001 From: sime94 Date: Mon, 2 Sep 2024 15:43:06 +0200 Subject: [PATCH 08/34] towards proper testing --- .../org/matsim/run/RunLausitzDrtScenario.java | 16 +++--- .../org/matsim/run/RunIntegrationTest.java | 53 ++++++++++++++++++- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java index 75ec333..2a846bf 100644 --- a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java +++ b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java @@ -127,12 +127,16 @@ protected Config prepareConfig(Config config) { SubtourModeChoiceConfigGroup smc = ConfigUtils.addOrGetModule(config, SubtourModeChoiceConfigGroup.class); - if (!String.join(",", smc.getModes()).contains(TransportMode.drt)) { - String[] modes = Arrays.copyOf(smc.getModes(), smc.getModes().length + 1); - modes[modes.length - 1] = TransportMode.drt; - - smc.setModes(modes); - } +// TODO remove this after testing and comment back in the if clause below + smc.setModes(new String[]{TransportMode.drt}); + config.replanning().setFractionOfIterationsToDisableInnovation(1.); + +// if (!String.join(",", smc.getModes()).contains(TransportMode.drt)) { +// String[] modes = Arrays.copyOf(smc.getModes(), smc.getModes().length + 1); +// modes[modes.length - 1] = TransportMode.drt; +// +// smc.setModes(modes); +// } // creates a drt staging activity and adds it to the scoring params DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfigGroup, config.scoring(), config.routing()); diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java index e0b2eac..545a10a 100644 --- a/src/test/java/org/matsim/run/RunIntegrationTest.java +++ b/src/test/java/org/matsim/run/RunIntegrationTest.java @@ -16,6 +16,7 @@ import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; +import org.matsim.core.config.groups.SubtourModeChoiceConfigGroup; import org.matsim.core.events.EventsUtils; import org.matsim.core.network.NetworkUtils; import org.matsim.core.population.PersonUtils; @@ -62,11 +63,61 @@ void runScenarioIncludingDrt() { Config config = ConfigUtils.loadConfig(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION)); ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class).defaultDashboards = SimWrapperConfigGroup.Mode.disabled; + SubtourModeChoiceConfigGroup smc = ConfigUtils.addOrGetModule(config, SubtourModeChoiceConfigGroup.class); + smc.setModes(new String[]{TransportMode.drt}); + + config.replanning().setFractionOfIterationsToDisableInnovation(1.); + + Path inputPath = p.resolve("drt-test-population.xml.gz"); + + Population population = PopulationUtils.createPopulation(config); + PopulationFactory fac = population.getFactory(); + Person person = fac.createPerson(ptPersonId); + Plan plan = PopulationUtils.createPlan(person); + +// home in hoyerswerda + Activity home = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24)); + home.setEndTime(8 * 3600); + Activity home2 = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24)); + home2.setEndTime(19 * 3600); +// work in ruhland rail station + Activity work = fac.createActivityFromCoord("work_2400", new Coord(838300.95,5711890.36)); + work.setEndTime(17 * 3600 + 25 * 60); + + Leg leg = fac.createLeg(TransportMode.drt); + + plan.addActivity(home); + plan.addLeg(leg); + plan.addActivity(work); + plan.addLeg(leg); + plan.addActivity(home2); + + person.addPlan(plan); + PersonUtils.setIncome(person, 1000.); + person.getAttributes().putAttribute("subpopulation", "person"); + population.addPerson(person); + + Person person2 = fac.createPerson(Id.createPersonId("smc-person")); + Plan plan2 = PopulationUtils.createPlan(person2); + Leg carLeg = fac.createLeg(TransportMode.car); + + plan2.addActivity(home); + plan2.addLeg(carLeg); + plan2.addActivity(work); + plan2.addLeg(carLeg); + plan2.addActivity(home2); + person2.addPlan(plan2); + + PersonUtils.setIncome(person2, 1000.); + person2.getAttributes().putAttribute("subpopulation", "person"); + population.addPerson(person2); + new PopulationWriter(population).write(inputPath.toString()); + assert MATSimApplication.execute(RunLausitzDrtScenario.class, config, "--1pct", "--drt-shp", "C:/Users/Simon/Documents/vsp-projects/matsim-lausitz/input/shp/lausitz.shp", "--iterations", "1", - "--config:plans.inputPlansFile", "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/lausitz/input/v1.1/lausitz-v1.1-1pct.plans-initial.xml.gz", + "--config:plans.inputPlansFile", inputPath.toString(), "--output", utils.getOutputDirectory(), "--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code"; } From 7e56092eb214b75524672bd3517b28ac29a14149 Mon Sep 17 00:00:00 2001 From: sime94 Date: Mon, 2 Sep 2024 18:35:21 +0200 Subject: [PATCH 09/34] simplify test setups --- .../org/matsim/run/RunIntegrationTest.java | 105 ++++++------------ 1 file changed, 33 insertions(+), 72 deletions(-) diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java index 545a10a..7824a4b 100644 --- a/src/test/java/org/matsim/run/RunIntegrationTest.java +++ b/src/test/java/org/matsim/run/RunIntegrationTest.java @@ -58,8 +58,6 @@ void runScenario() { @Test void runScenarioIncludingDrt() { -// TODO: add dummy drt person. -// TODO: test smc with drt. THere has to be some person changing to drt before iteration1 Config config = ConfigUtils.loadConfig(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION)); ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class).defaultDashboards = SimWrapperConfigGroup.Mode.disabled; @@ -70,48 +68,7 @@ void runScenarioIncludingDrt() { Path inputPath = p.resolve("drt-test-population.xml.gz"); - Population population = PopulationUtils.createPopulation(config); - PopulationFactory fac = population.getFactory(); - Person person = fac.createPerson(ptPersonId); - Plan plan = PopulationUtils.createPlan(person); - -// home in hoyerswerda - Activity home = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24)); - home.setEndTime(8 * 3600); - Activity home2 = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24)); - home2.setEndTime(19 * 3600); -// work in ruhland rail station - Activity work = fac.createActivityFromCoord("work_2400", new Coord(838300.95,5711890.36)); - work.setEndTime(17 * 3600 + 25 * 60); - - Leg leg = fac.createLeg(TransportMode.drt); - - plan.addActivity(home); - plan.addLeg(leg); - plan.addActivity(work); - plan.addLeg(leg); - plan.addActivity(home2); - - person.addPlan(plan); - PersonUtils.setIncome(person, 1000.); - person.getAttributes().putAttribute("subpopulation", "person"); - population.addPerson(person); - - Person person2 = fac.createPerson(Id.createPersonId("smc-person")); - Plan plan2 = PopulationUtils.createPlan(person2); - Leg carLeg = fac.createLeg(TransportMode.car); - - plan2.addActivity(home); - plan2.addLeg(carLeg); - plan2.addActivity(work); - plan2.addLeg(carLeg); - plan2.addActivity(home2); - person2.addPlan(plan2); - - PersonUtils.setIncome(person2, 1000.); - person2.getAttributes().putAttribute("subpopulation", "person"); - population.addPerson(person2); - new PopulationWriter(population).write(inputPath.toString()); + createTestPopulation(config, inputPath, TransportMode.drt, new Coord(838300.95,5711890.36)); assert MATSimApplication.execute(RunLausitzDrtScenario.class, config, "--1pct", @@ -129,34 +86,7 @@ void runScenarioIncludingAdditionalPtLine() { Path inputPath = p.resolve("pt-test-population.xml.gz"); - Population population = PopulationUtils.createPopulation(config); - PopulationFactory fac = population.getFactory(); - Person person = fac.createPerson(ptPersonId); - Plan plan = PopulationUtils.createPlan(person); - -// home in hoyerswerda - Activity home = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24)); - home.setEndTime(8 * 3600); - Activity home2 = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24)); - home2.setEndTime(19 * 3600); -// work in cottbus - Activity work = fac.createActivityFromCoord("work_2400", new Coord(867489.48,5746587.47)); - work.setEndTime(17 * 3600 + 25 * 60); - - Leg leg = fac.createLeg(TransportMode.pt); - - plan.addActivity(home); - plan.addLeg(leg); - plan.addActivity(work); - plan.addLeg(leg); - plan.addActivity(home2); - - person.addPlan(plan); - PersonUtils.setIncome(person, 1000.); - person.getAttributes().putAttribute("subpopulation", "person"); - population.addPerson(person); - - new PopulationWriter(population).write(inputPath.toString()); + createTestPopulation(config, inputPath, TransportMode.pt, new Coord(867489.48,5746587.47)); assert MATSimApplication.execute(RunLausitzPtScenario.class, config, "--1pct", @@ -191,6 +121,37 @@ void runScenarioIncludingAdditionalPtLine() { } + private static void createTestPopulation(Config config, Path inputPath, String mode, Coord workLocation) { + Population population = PopulationUtils.createPopulation(config); + PopulationFactory fac = population.getFactory(); + Person person = fac.createPerson(ptPersonId); + Plan plan = PopulationUtils.createPlan(person); + +// home in hoyerswerda + Activity home = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24)); + home.setEndTime(8 * 3600); + Activity home2 = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24)); + home2.setEndTime(19 * 3600); +// work in given location + Activity work = fac.createActivityFromCoord("work_2400", workLocation); + work.setEndTime(17 * 3600 + 25 * 60); + + Leg leg = fac.createLeg(mode); + + plan.addActivity(home); + plan.addLeg(leg); + plan.addActivity(work); + plan.addLeg(leg); + plan.addActivity(home2); + + person.addPlan(plan); + PersonUtils.setIncome(person, 1000.); + person.getAttributes().putAttribute("subpopulation", "person"); + population.addPerson(person); + + new PopulationWriter(population).write(inputPath.toString()); + } + private static final class PersonEntersPtVehicleEventHandler implements PersonEntersVehicleEventHandler { static List enterEvents = new ArrayList<>(); From 414e5a301134661819c5e5d40d8e7d48e5b68cc8 Mon Sep 17 00:00:00 2001 From: sime94 Date: Mon, 2 Sep 2024 18:35:41 +0200 Subject: [PATCH 10/34] no drt in smc (for now) --- .../java/org/matsim/run/RunLausitzDrtScenario.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java index 2a846bf..0df586c 100644 --- a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java +++ b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java @@ -28,7 +28,6 @@ import org.matsim.core.config.ConfigUtils; import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.config.groups.ScoringConfigGroup; -import org.matsim.core.config.groups.SubtourModeChoiceConfigGroup; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.network.algorithms.MultimodalNetworkCleaner; @@ -125,19 +124,6 @@ protected Config prepareConfig(Config config) { .setMarginalUtilityOfTraveling(-0.)); } - SubtourModeChoiceConfigGroup smc = ConfigUtils.addOrGetModule(config, SubtourModeChoiceConfigGroup.class); - -// TODO remove this after testing and comment back in the if clause below - smc.setModes(new String[]{TransportMode.drt}); - config.replanning().setFractionOfIterationsToDisableInnovation(1.); - -// if (!String.join(",", smc.getModes()).contains(TransportMode.drt)) { -// String[] modes = Arrays.copyOf(smc.getModes(), smc.getModes().length + 1); -// modes[modes.length - 1] = TransportMode.drt; -// -// smc.setModes(modes); -// } - // creates a drt staging activity and adds it to the scoring params DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfigGroup, config.scoring(), config.routing()); From e894ee81f94107e2d64edc584b40efabbdb355e9 Mon Sep 17 00:00:00 2001 From: sime94 Date: Tue, 3 Sep 2024 16:01:36 +0200 Subject: [PATCH 11/34] re-arrange drt configs --- .../nord-bautzen-waiting-times_utm32N.cpg | 1 + .../nord-bautzen-waiting-times_utm32N.dbf | Bin 0 -> 334 bytes .../nord-bautzen-waiting-times_utm32N.prj | 1 + .../nord-bautzen-waiting-times_utm32N.qmd | 43 +++++ .../nord-bautzen-waiting-times_utm32N.shp | Bin 0 -> 10116 bytes .../nord-bautzen-waiting-times_utm32N.shx | Bin 0 -> 132 bytes src/main/java/org/matsim/run/DrtOptions.java | 140 ++++++++++++++++ .../org/matsim/run/RunLausitzDrtScenario.java | 153 ++---------------- .../matsim/run/prepare/PrepareNetwork.java | 35 ++++ 9 files changed, 237 insertions(+), 136 deletions(-) create mode 100644 input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.cpg create mode 100644 input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.dbf create mode 100644 input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.prj create mode 100644 input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.qmd create mode 100644 input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.shp create mode 100644 input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.shx create mode 100644 src/main/java/org/matsim/run/DrtOptions.java diff --git a/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.cpg b/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.cpg new file mode 100644 index 0000000..3ad133c --- /dev/null +++ b/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.cpg @@ -0,0 +1 @@ +UTF-8 \ No newline at end of file diff --git a/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.dbf b/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.dbf new file mode 100644 index 0000000000000000000000000000000000000000..890fa79cf4b6f1598dd10d529c6ced6dc0b84367 GIT binary patch literal 334 zcmZRs;bdZAU|?uuFb0yCATtFn<_BVN!MPAdUSe)4RLB`b%RxCXs-&_YzPtp?!>XTG z0S*lE@{3Y*lM+iys#5ddqG$|5BLf43kYQ12Mowa0if(a9Vo7E`4qe8`T8uLCD^rV# d%TtR|5)lTWvrx1c8ye(h;xHSb(agX=3IK}sE*$^> literal 0 HcmV?d00001 diff --git a/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.prj b/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.prj new file mode 100644 index 0000000..bd846ae --- /dev/null +++ b/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.prj @@ -0,0 +1 @@ +PROJCS["ETRS_1989_UTM_Zone_32N",GEOGCS["GCS_ETRS_1989",DATUM["D_ETRS_1989",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] \ No newline at end of file diff --git a/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.qmd b/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.qmd new file mode 100644 index 0000000..2cde205 --- /dev/null +++ b/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.qmd @@ -0,0 +1,43 @@ + + + + + + dataset + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + + + + + + + + diff --git a/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.shp b/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.shp new file mode 100644 index 0000000000000000000000000000000000000000..8f4e3912d28c88655aab76996738a1c3a808cbfb GIT binary patch literal 10116 zcmZ|VcU+I(<2UfPNQCy1(4yW~X{fA}PJ>jmqoE~yANSqk@&4o4IoH|OIp;dpMWacu(*B=++!aHMX*6bpg?i@3 zC|{$KR~imeF2$zgyAJ!b`Yc79PIw&O-D*nypO^pN|6D|)apo}6nsRs6t@-%>PYV%g z3QYg|Vgv5NyUK$UQLV1Gmw#bOg#B#NuEM{nv&1Fg_}0V**M5r7x|(}` z6x{Q&%ybyuS;?%vAO7huF(1@NCr=btx1EPQ`0v^bz%^zE&&I=U;|&!X;ru7JId8*Z z%XxKNaD7VayDk5~HTRzD8Y928#(yI6;JK$%eJ|>tLEZM8g?pHW$sxp7_AYzKS7l1H zrMdl`kX|i|`iL5wc>m;m&we_2D`$2{72cQey1EPQt<1S?2&bA#ad`~U38!y_@E$mc zwk+Logihpps&cjA^CcDj0;6=|BN|~S2emZ8q1f=C@J%Oz}Z!I<(q?3b>pRfJ^v+~#G%D@^NF;i^Srev_tWp6s-i=T-cmxbTN zoc`-GOefAEG$SXtreblKD)Lvo?t0K2&g0o8)bX886dR_d1Zqslj6&4I`X6+%Pb%{4 zX;^0U#!FFC7#}J$!3dZ=Cu-H`G{(ogdU`J0ZB-Of2v<>Q7eB&xKWVwp;7)PZ48xbE zq?GFmOXeh0Wj${v=p?H%d+ZWyd8?|u8TpyEE4_UTe?7x}_vTMJ*>G97 zyAa+on|1IU(i;qLNMU{xAu1a@!g0M0y)0tnUAY5AjS5F8xC%hAVF@ORF^{qIpzh)^9p_ z$*j{k4?m0&TbVjbCqh3=#hL0be$BZYCE+6*r#cnk*2`Cg>A&b?M}&j*PS~s5U1Jw4 z^3iTp8vHJ4X=@PT+cg}@UsP{O6tmq*q+mH7)m;X#+w|nj@C=>sav!Cifp@ZoIK4#u z6}%_zhryexiuBsie!eV5=bPX&TobC7;hwMITHj#W-{y2LwBJv&YEJ$JQzB>UC3PNt zr762i9Cq@_lPO1kZ?Jd~X$8M}me~`E@zz+~|KtHI?mDDb3A?4O4f_CF1%!HzV?0Zq z`_W$jV=J_J;x28noo*2(lSgVwKeKgFq zCDk=&B}GDw+goDc?{~kQy|{`ZJ;!~gQ{Ztn>4qtUQ@SEra_`W;CLt?(5iVPKnfD+Z z5x%a)kBuVBS+Cjty(uY(5jvT`MG=LYH{Ne= z#Qf#wYjBU3BLBpB9#DZVrz)v4@l)jSlR`&JxM|Gfov;8!^wx3*8p6HVqb3gpDdKUr z*4+elT%*=&CPa}K!(Ns>@T148inP~J#L-YOav$94BAN1Am?FVO@@0(tuCnP2UBvpM zu06al06x31q|Z$p_0Kx@;2f+vFt)Z;1naBF=(-p1pju<-D#@;rNblJ7a`b zb9i`8z@n$3TX=DO)-mHb*=AD`E7Lu?808Jw%roK-H>GC_%fZCsedk@cTY2937hKeL ztK%V@mNRH_8Ra!!m)%nWH%@Js=@z5Nt{Fk;VurWH3M_1(2v4r`q{$Ke6qvX15eYyrW+)ISxzTmE5AY3GF4r_L>nt*Aik+z>YTA7NSZNnT%(vuz?@l7wEO# zN|BTo30th-`Qr6^?6*dc2bD027;pR)_xr5E1Rrc9BNrE8p{U{=NQ zwx=o-$=uEQ%o#pERKcpKPLbqx{UeO{MaFFLR&dqYW1McVfkR7jh6Y8#0y^j1VYy)* ziOX6P(a_uDb`$2KJ-l*q4@EkcD6uBOS5wZ)XlYZ#c6PXzVI$2W56*HdUNL`ahRuiN1i1cQsYtgaZ%QCB(t*r^97#AU;jfO*0DKZ|Q6) zdWa&v^0|ecFsqu9Ij1#6o_vm!4Tp_bA2EB_P-NU(o>(*`!7qyR zFIvG(g2S&F<<}0NeW*Q5k#|2?8djoy%kEuV*Krj0^W}&1WpGaUQxviKayqyX=8cl_Fmc2ECG|Qe z7Y_2MNDT9&hzsrU)Dc+v-ldIw@L0vNGxqS%9)-$BUKIHfu!`RW&Xa9@$8`baDPT=H z18>&7=6)ZZ@p0C7hHsrtqIO-R$mTBbFV=8IieHR^AMV#?3fmXCJF;dg76&(6lDTIQNf9^h)!9L?m8je}TQo%yl6np6V7u!^oON)kNKxKu;6_47hkRMZo z-O+Z&^`;vZb-@Z^%s)rr7m<|GM_Ai=)kYfHN9KH%%U_rztXd}lH+0JR%)?^dxj_oB zfVbn>5|ro6l3Q}y7~#JahHM%6{eGOb1CG9vzRE3zBK^m_rI_@CW}+cw{(NQKw(xGK2k z%f*b-@W!MDDaQDY`%>!A0Y{$NI4}i|3h`zr-JwWM{xkU{xIcO|O1k3jQe+`|{4xb^ zdNU}}18;iYDx?6%uC{x^kw}r^xnnkm;0mWY)iiiJjlcag%#-wN$=Ul9Dfm)q6%Ob4 zpP5g9Jp`x&F|eSN_02c%1wZR0@vtZBwv&4vV7?1AGRT0t?NSYT;K8Er(a+(}OE{wc z!g;|i-Y?*&s=E#GNffyfs29-!$1}-osDM2LY^<8$jLDPfj>%Y0GEJx2;fToO%qEz9 z>Il6P)>@={n`H`_D*%Wmp3wD}mTW5px{%q+EOox~FYxlILVSN&P5SjufW=ySGl1>qobNgo= z!*S59=}-2C{n3xugeYp$|9m;@XNG^ z`V1>uxiyPdU_R$atrvui+76b>S7H9DU)8n+R{ZddU8MRy=T1(cEDA;N3OA4MDhPKT zpQsIdiTe6ARj!2}Bo+piyu$kC@+FNKp5-m0Xm!{R5$fG2%4c_?xWxyySp6*ZIcydA zI@bk0#q<758Z2CK%s3CWIr&iHCj8y;>B1fOp9|d=ec;58Pu}Fh885TmIKxarU!D75 zxw7hWHt_G~i~d!7o5gj`b&{vRr5t= z@bcns+D~fH-`V+zjQzt(<7TF<@WG0E#iN)nKUPU!&PMwreSKb@54Q;(-cE;i?Z2&X z4u0HpTet%4dFg|R;a+%3t8dB)zT$d!n6ds8)%yA$g)_|uRM*3EFO&Wpfq%JN7~zDq zL+;;R4nGl!3u1;Tg-?EL8?u5`dJcQ$!IEN;V=MOKavKcNVIFpU z_fZm-tcQy=)H=jb-_q}T?M3kJ(N(Fk@JT7tbp>#@+Oe)bh#y=jZ+ssP)fTaxgR5?+ zvBkr#t7GD(;GZ0B6=Co;!TJ;5V9O&?gN*YIds$6|9$2<`-7i~MIxu^)1k!)LhQ7iA zPXF25_Z{KMvKDnZaD(pgq6hHTP2mL!@Rmy63@=!E`X-A6oZBn3!x-k?>#;}_o-G)o zX3$l}6>zl0>!)y-Tzs+FlrQ)nVaUSzaHm>s^+9Pr5z|s{6kN>+t zqX|A&cCUI0;pUZZ_cO+?$h3>t7g&@QeWDxYd6MB&1rH3*($kUu+<0c!BUqsmy^ERPfcp^poa?5@DUR zs7%Q(7>|+$88_kPqwDXThK=(1XmPO1(^Sh{aOATD-)nHr@~%l5Y$mdARX7}8b7PPn zUdpRs?guMcUgpe#*A-?)T!4E5ns@OIU_Vy1TZ>_JE2*!C;Ke5!K6}G)_Yy96!iftV z?E!H6)4}p`nAv2rhc9d-KW`a7NRc6WMGC`yI+^l!;c5FoUPgKkAF^k$z;AR$!kl4y z{%hgNxPI5}&L5`m1Cv1d3Y14|ce1}StfOM2a1QmaeAD=hah^G$xIR<_zP&^=c^%x4 zcXG`MwC~edrt1qh|72U8*tG=~8!$T24~Hq~)b^r3Hh-{mFM$PBp7X@R*39=@6JWV0 z-9dX;yw|VWAAZrH-LwKWFFtE(4sT!Vkogt;E7D|Vq63%kp8Mx7!drvarmDhDg(qKH zBER-1v$h@ZHr9=aW$?C%pz}(wpa=7v8z^t>tIRia*g*ADq&n)S-MKqc82%HKK;~eY zsFgMk>{He|sxyT1RDqf2jPql=AlJ3eM=0`oq}p~39A$N2>+l%PN7ZE28P}&W6`ykb zhUcaE5bupJ-${AVc34ekteX$k^eJ5aWt<`db)PRW&Zl3?Y42*MluTN%Euw^@156!yo~a?j>)9^X^r8RayM z^A7#@H-Ewd9`D=zf8so0>VDD>c#Fsdjt}soVvXw)@YRT`3KGAtzIN3QFyd?KOt<>O z#Y&xrTjA#6)0!_}?UA)l%iw?CgLde&$L7KuQeIwh2wy73<#ivPsw5>fud|G#tQ#5?Oro572YW)7U3-B9z1*Uj-@0VCdYuG-*sUR3GxuPPc26Mjg>gt=p zelk~fiw1m66vw!5?eQby>TrOx@0b?MGqW*_z{UJK3$~+vB2Kc#(|Es;wX<>X4cdci z(b!-sY#i0|tPSlY?{8oe1CK_;hc1GvhP-?a!1Co83w0A%KO+t5|Kk10%{_xc!|;!R zb#*haUtL~Z1lpfnS%|L|{--%#H2~MM?|RuC0KYOnRhNeFXrCNze^^mxchz(BXRhnR z59i?w-c9i%@TMC|#=GIb7i`Y6@KhM<2PHTzYTe8{##cweHJU8EXW@@Z8^&MEp@zmy z@QL5iDp?q>DZ)-n67Z<&U30ckobUKd8S=pY{Lzq*`ik>7K`B*kIFRc|=c!>l&tBwq z;)I!`yMz*PKX^;8_fa$U@442%64aNmUU-qr34SHy&+j$C zUjehdO*Rce{_10M3fJJb<})=vk^ix+5&aJESIz@k1IRx)bbI$fxOTy~^E#Z)PP?KH zo5*b0cL(M9M~w1Z53jNqD(QsPH*?ss!+|y?UNx|}?t;uGyl=bapROPW^9kkHHo#op zXfsYIzh?!<)=YTk`cN;V*7hvD)Q0zkyUp36zhHhTCp;@3!8Un`pOfLyz*PZmaB;C+ ziv&FKdqbTPTra*T%LTrkbmbT;oUlxTyAA2D`S{E00p4G#O z=)l72JMGuN=b3aR?;yVChKZIbyx%qB=8a{BCBr|y7N@ho zik0v7T!pu##9n)X`LXs#y{+hJ*6o>oL zJjz$Xw#<{EkudWV;OKxZVVZr|4dDZ<^dALiVV(S$4 zA6g4W_Mhm>IXJ*ZN%J-KJ1pE!3WeeB714hB@H@{r>D4fwn)_W|_^ii4 z?~yW7vhlm)?O)h0SuOjxr3QXQTOMDE{4G8_Th|WHw?9;!LiwW#%56K~C$`VudSbs* z*z~)w4elu3abpf%wAXgJ0T!A2WA2CcaC=IR^{wu>d%>*D)|fEz@_1O0n=eJz_TeDCzFm76g>jV}D?=YW&)cUUFE?1qIdKk&W9 zrtz}PWw6Mbc$?QSoBO?0b+CBj-mP_TKgZcg#{Q$CQ20|ST-|OHHHP$GYRpKcz)TVO z8yV}Ve$xDKEc{U*UeO1(`%bsG08jf&4#&WyuGZ;p@b4bwImZ4;`JATmak%K~u_+DY zw`63n#u7H{WagZL4^oF4_ru}kCln2kf5)Wxs2Y5yws))qX0_k>lkt6tb)S_G6YhuU z;{|hau(o>Zv1x=;b86S6;LYoMI%N=^dvFd)&*n=?YA%Gv_ zkHc|(VzmLzi&FX42V*~A;a=^S=ZN{FmH8hv#Em$Y+dAy>pKIB}45O4zqyJ~W&okb? z*PVT(wcLv$w{{;MW$Yg$blNlY&tg5a`dDWOd%nvlwe`ULHM-6-6YcUP%=+mmABt=U zm=F2_|64ZAVFQg_|08^ z@l&LoEzjBhr>&I6dZZmKu^$d@O&>?wEwHo7cbnn)X@^6x58|)SQ`)0%i23H9*t7gd z?_%KYtm|mMnv=v+X1{C9h!3zpz_lhJQFnm!4+ zf_PTnV7Dy>bLF4Q6`ou3aF#0ky5$d^of-Ycfgj^fY0DO#%)_Yny^6A8#MO)YtTApv zk#8j{y|-ar7L1;5da8$W8Q-OEYq743E*4lkD}{5X*KYCJs7H0yqI7#9tTUnSgBMWl zfAiK6^GadtL#?FONM8`gK5t{n?`3%I%3AYr)Z!S{{TVH(Hk2jc%&OR3G69(Dg3=G0*KzarMj-M2o literal 0 HcmV?d00001 diff --git a/src/main/java/org/matsim/run/DrtOptions.java b/src/main/java/org/matsim/run/DrtOptions.java new file mode 100644 index 0000000..e29b319 --- /dev/null +++ b/src/main/java/org/matsim/run/DrtOptions.java @@ -0,0 +1,140 @@ +package org.matsim.run; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.contrib.drt.optimizer.constraints.DefaultDrtOptimizationConstraintsSet; +import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsParams; +import org.matsim.contrib.drt.optimizer.insertion.extensive.ExtensiveInsertionSearchParams; +import org.matsim.contrib.drt.routing.DrtRoute; +import org.matsim.contrib.drt.routing.DrtRouteFactory; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.run.DrtConfigs; +import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; +import org.matsim.contrib.dvrp.run.DvrpConfigGroup; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.config.groups.QSimConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; +import org.matsim.run.prepare.PrepareNetwork; +import org.matsim.vehicles.Vehicle; +import org.matsim.vehicles.VehicleCapacity; +import org.matsim.vehicles.VehicleType; +import org.matsim.vehicles.VehicleUtils; +import picocli.CommandLine; + +import java.util.Set; + +/** + * This class bundles some run parameter options and functionalities connected to drt-scenarios. + */ +public class DrtOptions { + @CommandLine.Option(names = "--drt-shp", description = "Path to shp file for adding drt not network links as an allowed mode.", defaultValue = "./input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.shp") + private String drtAreaShp; + + @CommandLine.Option(names = "--typ-wt", description = "typical waiting time", defaultValue = "300") + protected double typicalWaitTime; + + @CommandLine.Option(names = "--wt-std", description = "waiting time standard deviation", defaultValue = "0.3") + protected double waitTimeStd; + + @CommandLine.Option(names = "--ride-time-alpha", description = "ride time estimator alpha", defaultValue = "1.25") + protected double rideTimeAlpha; + + @CommandLine.Option(names = "--ride-time-beta", description = "ride time estimator beta", defaultValue = "300") + protected double rideTimeBeta; + + @CommandLine.Option(names = "--ride-time-std", description = "ride duration standard deviation", defaultValue = "0.3") + protected double rideTimeStd; + + /** + * a helper method, which makes all necessary config changes to simulate drt. + */ + void configureDrtConfig(Config config) { + DvrpConfigGroup dvrpConfigGroup = ConfigUtils.addOrGetModule(config, DvrpConfigGroup.class); + dvrpConfigGroup.networkModes = Set.of(TransportMode.drt); + + MultiModeDrtConfigGroup multiModeDrtConfigGroup = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); + + if (multiModeDrtConfigGroup.getModalElements().isEmpty()) { + DrtConfigGroup drtConfigGroup = new DrtConfigGroup(); + drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.serviceAreaBased; + drtConfigGroup.stopDuration = 60.; + drtConfigGroup.drtServiceAreaShapeFile = getDrtAreaShp(); + +// optimization params now are in its own paramSet, hence the below lines + DrtOptimizationConstraintsParams optimizationConstraints = new DrtOptimizationConstraintsParams(); + DefaultDrtOptimizationConstraintsSet optimizationConstraintsSet = new DefaultDrtOptimizationConstraintsSet(); + optimizationConstraintsSet.maxWaitTime = 1200.; + optimizationConstraintsSet.maxTravelTimeBeta = 1200.; + optimizationConstraintsSet.maxTravelTimeAlpha = 1.5; + optimizationConstraints.addParameterSet(optimizationConstraintsSet); + drtConfigGroup.addParameterSet(optimizationConstraints); + drtConfigGroup.addParameterSet(new ExtensiveInsertionSearchParams()); + multiModeDrtConfigGroup.addParameterSet(drtConfigGroup); + } + + // set to drt estimate and teleport +// this enables the usage of the DrtEstimator by CL + for (DrtConfigGroup drtConfigGroup : multiModeDrtConfigGroup.getModalElements()) { + drtConfigGroup.simulationType = DrtConfigGroup.SimulationType.estimateAndTeleport; + } + +// this is needed for DynAgents for DVRP + config.qsim().setSimStarttimeInterpretation(QSimConfigGroup.StarttimeInterpretation.onlyUseStarttime); + + ScoringConfigGroup scoringConfigGroup = ConfigUtils.addOrGetModule(config, ScoringConfigGroup.class); + + if (!scoringConfigGroup.getModes().containsKey(TransportMode.drt)) { +// ASC drt = ASC pt as discussed in PHD seminar24 +// add mode params for drt if missing and set ASC + marg utility of traveling = 0 + scoringConfigGroup.addModeParams(new ScoringConfigGroup.ModeParams(TransportMode.drt) + .setConstant(scoringConfigGroup.getModes().get(TransportMode.pt).getConstant()) + .setMarginalUtilityOfTraveling(-0.)); + } + +// creates a drt staging activity and adds it to the scoring params + DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfigGroup, config.scoring(), config.routing()); + } + + /** + * a helper method, which makes all necessary scenario changes to simulate drt. + */ + void configureDrtScenario(Scenario scenario) { + + // drt route factory has to be added as factory for drt routes, as there were no drt routes before. + scenario.getPopulation() + .getFactory() + .getRouteFactories() + .setRouteFactory(DrtRoute.class, new DrtRouteFactory()); + +// prepare network for drt + PrepareNetwork.prepareDrtNetwork(scenario.getNetwork(), getDrtAreaShp()); + // add drt veh type if not already existing + Id drtTypeId = Id.create(TransportMode.drt, VehicleType.class); + if (!scenario.getVehicles().getVehicleTypes().containsKey(drtTypeId)) { +// drt veh type = car veh type, but capacity 1 passenger + VehicleType drtType = VehicleUtils.createVehicleType(drtTypeId); + + VehicleUtils.copyFromTo(scenario.getVehicles().getVehicleTypes().get(Id.create(TransportMode.car, VehicleType.class)), drtType); + drtType.setDescription("drt vehicle copied from car vehicle type"); + VehicleCapacity capacity = drtType.getCapacity(); + capacity.setSeats(1); + + scenario.getVehicles().addVehicleType(drtType); + + Vehicle drtDummy = VehicleUtils.createVehicle(Id.createVehicleId("drtDummy"), drtType); + drtDummy.getAttributes().putAttribute("dvrpMode", TransportMode.drt); + drtDummy.getAttributes().putAttribute("startLink", "706048410#0"); + drtDummy.getAttributes().putAttribute("serviceBeginTime", 0.); + drtDummy.getAttributes().putAttribute("serviceEndTime", 86400.); + + scenario.getVehicles().addVehicle(drtDummy); + } + } + + public String getDrtAreaShp() { + return drtAreaShp; + } + +} diff --git a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java index 0df586c..8b0c2fb 100644 --- a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java +++ b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java @@ -1,76 +1,44 @@ package org.matsim.run; -import org.locationtech.jts.geom.Geometry; -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.application.MATSimApplication; -import org.matsim.application.options.ShpOptions; import org.matsim.contrib.drt.estimator.DrtEstimatorModule; import org.matsim.contrib.drt.estimator.impl.DirectTripBasedDrtEstimator; import org.matsim.contrib.drt.estimator.impl.distribution.NormalDistributionGenerator; import org.matsim.contrib.drt.estimator.impl.trip_estimation.ConstantRideDurationEstimator; import org.matsim.contrib.drt.estimator.impl.waiting_time_estimation.ConstantWaitingTimeEstimator; -import org.matsim.contrib.drt.optimizer.constraints.DefaultDrtOptimizationConstraintsSet; -import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsParams; -import org.matsim.contrib.drt.optimizer.insertion.extensive.ExtensiveInsertionSearchParams; -import org.matsim.contrib.drt.routing.DrtRoute; -import org.matsim.contrib.drt.routing.DrtRouteFactory; import org.matsim.contrib.drt.run.DrtConfigGroup; -import org.matsim.contrib.drt.run.DrtConfigs; import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; import org.matsim.contrib.drt.run.MultiModeDrtModule; -import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.dvrp.run.DvrpModule; import org.matsim.contrib.dvrp.run.DvrpQSimComponents; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.QSimConfigGroup; -import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; -import org.matsim.core.network.algorithms.MultimodalNetworkCleaner; -import org.matsim.core.utils.geometry.geotools.MGC; -import org.matsim.vehicles.Vehicle; -import org.matsim.vehicles.VehicleCapacity; -import org.matsim.vehicles.VehicleType; -import org.matsim.vehicles.VehicleUtils; import picocli.CommandLine; import javax.annotation.Nullable; -import java.util.*; /** * Run the Lausitz scenario including a regional DRT service. * All necessary configs will be made in this class. */ public final class RunLausitzDrtScenario extends MATSimApplication { -// TODO: upload correct service area shp file to git - @CommandLine.Option(names = "--drt-shp", description = "Path to shp file for adding drt not network links as an allowed mode.", defaultValue = "./input/shp/lausitz.shp") - private String drtAreaShp; - @CommandLine.Option(names = "--typ-wt", description = "typical waiting time", defaultValue = "300") - private double typicalWaitTime; - - @CommandLine.Option(names = "--wt-std", description = "waiting time standard deviation", defaultValue = "0.3") - private double waitTimeStd; - - @CommandLine.Option(names = "--ride-time-alpha", description = "ride time estimator alpha", defaultValue = "1.25") - private double rideTimeAlpha; - - @CommandLine.Option(names = "--ride-time-beta", description = "ride time estimator beta", defaultValue = "300") - private double rideTimeBeta; - - @CommandLine.Option(names = "--ride-time-std", description = "ride duration standard deviation", defaultValue = "0.3") - private double rideTimeStd; +// run params re drt are contained in separate class DrtOptions + @CommandLine.ArgGroup(heading = "%nDrt options%n", exclusive = false, multiplicity = "0..1") + private final DrtOptions drtOpt = new DrtOptions(); private final LausitzScenario baseScenario = new LausitzScenario(); +// this constructor is needed when this class is to be called from external classes with a given Config (e.g. for testing). + public RunLausitzDrtScenario(Config config) { + super(config); + } + public RunLausitzDrtScenario() { -// TODO: change this back to "automagic" version loading of config -// super(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION)); - super("input/v1.1/lausitz-v1.1-10pct.config.xml"); + super(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION)); } public static void main(String[] args) { @@ -83,49 +51,8 @@ protected Config prepareConfig(Config config) { // apply all config changes from base scenario class baseScenario.prepareConfig(config); - DvrpConfigGroup dvrpConfigGroup = ConfigUtils.addOrGetModule(config, DvrpConfigGroup.class); - dvrpConfigGroup.networkModes = Set.of(TransportMode.drt); - - MultiModeDrtConfigGroup multiModeDrtConfigGroup = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); - - if (multiModeDrtConfigGroup.getModalElements().isEmpty()) { - DrtConfigGroup drtConfigGroup = new DrtConfigGroup(); - drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.serviceAreaBased; - drtConfigGroup.stopDuration = 60.; - drtConfigGroup.drtServiceAreaShapeFile = drtAreaShp; - -// optimization params now are in its own paramSet, hence the below lines - DrtOptimizationConstraintsParams optimizationConstraints = new DrtOptimizationConstraintsParams(); - DefaultDrtOptimizationConstraintsSet optimizationConstraintsSet = new DefaultDrtOptimizationConstraintsSet(); - optimizationConstraintsSet.maxWaitTime = 1200.; - optimizationConstraintsSet.maxTravelTimeBeta = 1200.; - optimizationConstraintsSet.maxTravelTimeAlpha = 1.5; - optimizationConstraints.addParameterSet(optimizationConstraintsSet); - drtConfigGroup.addParameterSet(optimizationConstraints); - drtConfigGroup.addParameterSet(new ExtensiveInsertionSearchParams()); - multiModeDrtConfigGroup.addParameterSet(drtConfigGroup); - } - - // set to drt estimate and teleport - for (DrtConfigGroup drtConfigGroup : multiModeDrtConfigGroup.getModalElements()) { - drtConfigGroup.simulationType = DrtConfigGroup.SimulationType.estimateAndTeleport; - } - -// this is needed for DynAgents for DVRP - config.qsim().setSimStarttimeInterpretation(QSimConfigGroup.StarttimeInterpretation.onlyUseStarttime); - - ScoringConfigGroup scoringConfigGroup = ConfigUtils.addOrGetModule(config, ScoringConfigGroup.class); - - if (!scoringConfigGroup.getModes().containsKey(TransportMode.drt)) { -// ASC drt = ASC pt as discussed in PHD seminar24 -// add mode params for drt if missing and set ASC + marg utility of traveling = 0 - scoringConfigGroup.addModeParams(new ScoringConfigGroup.ModeParams(TransportMode.drt) - .setConstant(scoringConfigGroup.getModes().get(TransportMode.pt).getConstant()) - .setMarginalUtilityOfTraveling(-0.)); - } - -// creates a drt staging activity and adds it to the scoring params - DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfigGroup, config.scoring(), config.routing()); +// apply all necessary config changes for drt simulation + drtOpt.configureDrtConfig(config); return config; } @@ -135,54 +62,8 @@ protected void prepareScenario(Scenario scenario) { // apply all scenario changes from base scenario class baseScenario.prepareScenario(scenario); -// drt route factory has to be added as factory for drt routes, as there were no drt routes before. - scenario.getPopulation() - .getFactory() - .getRouteFactories() - .setRouteFactory(DrtRoute.class, new DrtRouteFactory()); - -// add drt as allowed mode for whole Lausitz region - Geometry geometry = new ShpOptions(drtAreaShp, null, null).getGeometry(); - -// with the estimator, drt is teleported, but we may need drt as an allowed mode for -// separate drt post simulation - for (Link link : scenario.getNetwork().getLinks().values()) { - if (link.getAllowedModes().contains(TransportMode.car)) { - boolean isInside = MGC.coord2Point(link.getFromNode().getCoord()).within(geometry) || - MGC.coord2Point(link.getToNode().getCoord()).within(geometry); - - if (isInside) { - Set modes = new HashSet<>(); - modes.add(TransportMode.drt); - modes.addAll(link.getAllowedModes()); - link.setAllowedModes(modes); - } - } - } - new MultimodalNetworkCleaner(scenario.getNetwork()).run(Set.of(TransportMode.drt)); - - Id drtTypeId = Id.create(TransportMode.drt, VehicleType.class); - -// add drt veh type if not already existing - if (!scenario.getVehicles().getVehicleTypes().containsKey(drtTypeId)) { -// drt veh type = car veh type, but capacity 1 passenger - VehicleType drtType = VehicleUtils.createVehicleType(drtTypeId); - - VehicleUtils.copyFromTo(scenario.getVehicles().getVehicleTypes().get(Id.create(TransportMode.car, VehicleType.class)), drtType); - drtType.setDescription("drt vehicle copied from car vehicle type"); - VehicleCapacity capacity = drtType.getCapacity(); - capacity.setSeats(1); - - scenario.getVehicles().addVehicleType(drtType); - - Vehicle drtDummy = VehicleUtils.createVehicle(Id.createVehicleId("drtDummy"), drtType); - drtDummy.getAttributes().putAttribute("dvrpMode", TransportMode.drt); - drtDummy.getAttributes().putAttribute("startLink", "706048410#0"); - drtDummy.getAttributes().putAttribute("serviceBeginTime", 0.); - drtDummy.getAttributes().putAttribute("serviceEndTime", 86400.); - - scenario.getVehicles().addVehicle(drtDummy); - } +// apply all necessary scenario changes for drt simulation + drtOpt.configureDrtScenario(scenario); } @Override @@ -207,10 +88,10 @@ protected void prepareControler(Controler controler) { public void install() { DrtEstimatorModule.bindEstimator(binder(), drtConfigGroup.mode).toInstance( new DirectTripBasedDrtEstimator.Builder() - .setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(typicalWaitTime)) - .setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, waitTimeStd)) - .setRideDurationEstimator(new ConstantRideDurationEstimator(rideTimeAlpha, rideTimeBeta)) - .setRideDurationDistributionGenerator(new NormalDistributionGenerator(2, rideTimeStd)) + .setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(drtOpt.typicalWaitTime)) + .setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, drtOpt.waitTimeStd)) + .setRideDurationEstimator(new ConstantRideDurationEstimator(drtOpt.rideTimeAlpha, drtOpt.rideTimeBeta)) + .setRideDurationDistributionGenerator(new NormalDistributionGenerator(2, drtOpt.rideTimeStd)) .build() ); } diff --git a/src/main/java/org/matsim/run/prepare/PrepareNetwork.java b/src/main/java/org/matsim/run/prepare/PrepareNetwork.java index 9b292c5..fbbaf52 100644 --- a/src/main/java/org/matsim/run/prepare/PrepareNetwork.java +++ b/src/main/java/org/matsim/run/prepare/PrepareNetwork.java @@ -3,16 +3,21 @@ import com.google.common.collect.Sets; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.locationtech.jts.geom.Geometry; 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.application.MATSimAppCommand; +import org.matsim.application.options.ShpOptions; import org.matsim.contrib.emissions.HbefaRoadTypeMapping; import org.matsim.contrib.emissions.OsmHbefaMapping; import org.matsim.core.network.NetworkUtils; import org.matsim.core.network.algorithms.MultimodalNetworkCleaner; +import org.matsim.core.utils.geometry.geotools.MGC; +import org.matsim.run.DrtOptions; import picocli.CommandLine; +import java.util.HashSet; import java.util.Set; import static org.matsim.run.LausitzScenario.*; @@ -31,6 +36,9 @@ public class PrepareNetwork implements MATSimAppCommand { @CommandLine.Option(names = "--output", description = "Output path of the prepared network", required = true) private String outputPath; + @CommandLine.ArgGroup(heading = "%nDrt options%n", exclusive = false, multiplicity = "0..1") + private final DrtOptions drtOpt = new DrtOptions(); + public static void main(String[] args) { new PrepareNetwork().execute(args); } @@ -42,6 +50,7 @@ public Integer call() throws Exception { prepareFreightNetwork(network); prepareEmissionsAttributes(network); + prepareDrtNetwork(network, drtOpt.getDrtAreaShp()); NetworkUtils.writeNetwork(network, outputPath); @@ -92,4 +101,30 @@ public static void prepareEmissionsAttributes(Network network) { } roadTypeMapping.addHbefaMappings(network); } + + /** + * add drt as allowed mode on links within given shape. + */ + public static void prepareDrtNetwork(Network network, String drtAreaShp) { + // add drt as allowed mode for whole Lausitz region + Geometry geometry = new ShpOptions(drtAreaShp, null, null).getGeometry(); + +// with the estimator, drt is teleported, but we may need drt as an allowed mode for +// separate drt post simulation + for (Link link : network.getLinks().values()) { + if (link.getAllowedModes().contains(TransportMode.car)) { + boolean isInside = MGC.coord2Point(link.getFromNode().getCoord()).within(geometry) || + MGC.coord2Point(link.getToNode().getCoord()).within(geometry); + + if (isInside) { + Set modes = new HashSet<>(); + modes.add(TransportMode.drt); + modes.addAll(link.getAllowedModes()); + link.setAllowedModes(modes); + } + } + } + new MultimodalNetworkCleaner(network).run(Set.of(TransportMode.drt)); + + } } From ff66b9a5c7199b4d5e169e8d1480ea520381e775 Mon Sep 17 00:00:00 2001 From: sime94 Date: Tue, 3 Sep 2024 16:53:35 +0200 Subject: [PATCH 12/34] complete drt test --- src/main/java/org/matsim/run/DrtOptions.java | 6 ++-- .../matsim/run/prepare/PrepareNetwork.java | 1 - .../org/matsim/run/RunIntegrationTest.java | 35 ++++++++++++++----- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/matsim/run/DrtOptions.java b/src/main/java/org/matsim/run/DrtOptions.java index e29b319..400a69a 100644 --- a/src/main/java/org/matsim/run/DrtOptions.java +++ b/src/main/java/org/matsim/run/DrtOptions.java @@ -16,6 +16,7 @@ import org.matsim.core.config.ConfigUtils; import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.config.groups.ScoringConfigGroup; +import org.matsim.core.utils.io.IOUtils; import org.matsim.run.prepare.PrepareNetwork; import org.matsim.vehicles.Vehicle; import org.matsim.vehicles.VehicleCapacity; @@ -29,7 +30,7 @@ * This class bundles some run parameter options and functionalities connected to drt-scenarios. */ public class DrtOptions { - @CommandLine.Option(names = "--drt-shp", description = "Path to shp file for adding drt not network links as an allowed mode.", defaultValue = "./input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.shp") + @CommandLine.Option(names = "--drt-shp", description = "Path to shp file for adding drt not network links as an allowed mode.", defaultValue = "./drt-area/nord-bautzen-waiting-times_utm32N.shp") private String drtAreaShp; @CommandLine.Option(names = "--typ-wt", description = "typical waiting time", defaultValue = "300") @@ -109,7 +110,8 @@ void configureDrtScenario(Scenario scenario) { .setRouteFactory(DrtRoute.class, new DrtRouteFactory()); // prepare network for drt - PrepareNetwork.prepareDrtNetwork(scenario.getNetwork(), getDrtAreaShp()); +// preparation needs to be done with lausitz shp not service area shp + PrepareNetwork.prepareDrtNetwork(scenario.getNetwork(), IOUtils.extendUrl(scenario.getConfig().getContext(), "../shp/lausitz.shp").toString()); // add drt veh type if not already existing Id drtTypeId = Id.create(TransportMode.drt, VehicleType.class); if (!scenario.getVehicles().getVehicleTypes().containsKey(drtTypeId)) { diff --git a/src/main/java/org/matsim/run/prepare/PrepareNetwork.java b/src/main/java/org/matsim/run/prepare/PrepareNetwork.java index fbbaf52..ade17b5 100644 --- a/src/main/java/org/matsim/run/prepare/PrepareNetwork.java +++ b/src/main/java/org/matsim/run/prepare/PrepareNetwork.java @@ -125,6 +125,5 @@ public static void prepareDrtNetwork(Network network, String drtAreaShp) { } } new MultimodalNetworkCleaner(network).run(Set.of(TransportMode.drt)); - } } diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java index 7824a4b..30e2941 100644 --- a/src/test/java/org/matsim/run/RunIntegrationTest.java +++ b/src/test/java/org/matsim/run/RunIntegrationTest.java @@ -1,5 +1,6 @@ package org.matsim.run; +import com.univocity.parsers.common.input.EOFException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -12,11 +13,12 @@ import org.matsim.api.core.v01.events.handler.PersonEntersVehicleEventHandler; import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.population.*; +import org.matsim.application.ApplicationUtils; import org.matsim.application.MATSimApplication; +import org.matsim.application.options.CsvOptions; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.SubtourModeChoiceConfigGroup; import org.matsim.core.events.EventsUtils; import org.matsim.core.network.NetworkUtils; import org.matsim.core.population.PersonUtils; @@ -25,7 +27,12 @@ import org.matsim.pt.transitSchedule.api.*; import org.matsim.simwrapper.SimWrapperConfigGroup; import org.matsim.testcases.MatsimTestUtils; +import tech.tablesaw.api.ColumnType; +import tech.tablesaw.api.DoubleColumn; +import tech.tablesaw.api.Table; +import tech.tablesaw.io.csv.CsvReadOptions; +import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; @@ -57,26 +64,38 @@ void runScenario() { @Test void runScenarioIncludingDrt() { - Config config = ConfigUtils.loadConfig(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION)); ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class).defaultDashboards = SimWrapperConfigGroup.Mode.disabled; - SubtourModeChoiceConfigGroup smc = ConfigUtils.addOrGetModule(config, SubtourModeChoiceConfigGroup.class); - smc.setModes(new String[]{TransportMode.drt}); - - config.replanning().setFractionOfIterationsToDisableInnovation(1.); - Path inputPath = p.resolve("drt-test-population.xml.gz"); createTestPopulation(config, inputPath, TransportMode.drt, new Coord(838300.95,5711890.36)); assert MATSimApplication.execute(RunLausitzDrtScenario.class, config, "--1pct", - "--drt-shp", "C:/Users/Simon/Documents/vsp-projects/matsim-lausitz/input/shp/lausitz.shp", "--iterations", "1", "--config:plans.inputPlansFile", inputPath.toString(), "--output", utils.getOutputDirectory(), "--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code"; + + //read customer stats + Path customerStatsPath = ApplicationUtils.matchInput("drt_customer_stats_" + TransportMode.drt + ".csv", Path.of(utils.getOutputDirectory())); + try { + Table customerStats = Table.read() + .csv(CsvReadOptions.builder(customerStatsPath.toFile()) + .columnTypes(columnHeader -> columnHeader.equals("runId") ? ColumnType.STRING : ColumnType.DOUBLE) + .separator(CsvOptions.detectDelimiter(customerStatsPath.toString())) + .build()); + + Assertions.assertEquals(2, customerStats.rowCount()); + + DoubleColumn rideCol = customerStats.doubleColumn("rides"); + +// there should be exactly 2 drt rides + Assertions.assertEquals(2, rideCol.get(rideCol.size() - 1)); + } catch (IOException e) { + throw new EOFException(); + } } @Test From e26c8b170c7c1b97591fc5d89e115b6655594be6 Mon Sep 17 00:00:00 2001 From: Chengqi Lu <43133404+luchengqi7@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:35:22 +0200 Subject: [PATCH 13/34] Add intermodal stuff --- pom.xml | 29 ++++++++ src/main/java/org/matsim/run/DrtOptions.java | 9 +++ .../run/prepare/PrepareTransitSchedule.java | 70 +++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 src/main/java/org/matsim/run/prepare/PrepareTransitSchedule.java diff --git a/pom.xml b/pom.xml index e6f09d2..65775f2 100644 --- a/pom.xml +++ b/pom.xml @@ -77,6 +77,35 @@ ${matsim.version} + + com.github.matsim-vsp + pt-extensions + ceef00ef6e + + + + org.matsim.contrib + drt + + + org.matsim + matsim + + + org.matsim + matsim-examples + + + org.matsim.contrib + vsp + + + org.openjfx + javafx-graphics + + + + diff --git a/src/main/java/org/matsim/run/DrtOptions.java b/src/main/java/org/matsim/run/DrtOptions.java index 400a69a..6eec1bc 100644 --- a/src/main/java/org/matsim/run/DrtOptions.java +++ b/src/main/java/org/matsim/run/DrtOptions.java @@ -17,6 +17,7 @@ import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.utils.io.IOUtils; +import org.matsim.extensions.pt.routing.ptRoutingModes.PtIntermodalRoutingModesConfigGroup; import org.matsim.run.prepare.PrepareNetwork; import org.matsim.vehicles.Vehicle; import org.matsim.vehicles.VehicleCapacity; @@ -48,6 +49,10 @@ public class DrtOptions { @CommandLine.Option(names = "--ride-time-std", description = "ride duration standard deviation", defaultValue = "0.3") protected double rideTimeStd; + @CommandLine.Option(names = "--intermodal", defaultValue = "false", description = "enable intermodality for DRT service") + private boolean intermodal; + + /** * a helper method, which makes all necessary config changes to simulate drt. */ @@ -96,6 +101,10 @@ void configureDrtConfig(Config config) { // creates a drt staging activity and adds it to the scoring params DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfigGroup, config.scoring(), config.routing()); + + if (intermodal) { + ConfigUtils.addOrGetModule(config, PtIntermodalRoutingModesConfigGroup.class); + } } /** diff --git a/src/main/java/org/matsim/run/prepare/PrepareTransitSchedule.java b/src/main/java/org/matsim/run/prepare/PrepareTransitSchedule.java new file mode 100644 index 0000000..185e597 --- /dev/null +++ b/src/main/java/org/matsim/run/prepare/PrepareTransitSchedule.java @@ -0,0 +1,70 @@ +package org.matsim.run.prepare; + +import org.geotools.api.feature.simple.SimpleFeature; +import org.locationtech.jts.geom.Geometry; +import org.matsim.api.core.v01.Scenario; +import org.matsim.application.MATSimAppCommand; +import org.matsim.application.options.ShpOptions; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.scenario.ProjectionUtils; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.core.utils.geometry.geotools.MGC; +import org.matsim.pt.transitSchedule.api.TransitSchedule; +import org.matsim.pt.transitSchedule.api.TransitScheduleWriter; +import org.matsim.pt.transitSchedule.api.TransitStopFacility; +import picocli.CommandLine; + +import java.util.List; + +@CommandLine.Command( + name = "prepare-transit-schedule", + description = "Tag transit stops for Intermodal trips" +) +public class PrepareTransitSchedule implements MATSimAppCommand { + @CommandLine.Mixin + private ShpOptions shp = new ShpOptions(); + + @CommandLine.Option(names = "--input", description = "input transit schedule", required = true) + private String input; + + @CommandLine.Option(names = "--output", description = "output path of the transit schedule", required = true) + private String output; + + public static void main(String[] args) { + new PrepareTransitSchedule().execute(args); + } + + @Override + public Integer call() throws Exception { + Geometry intermodalArea = null; + List features = shp.readFeatures(); + for (SimpleFeature feature : features) { + if (intermodalArea == null) { + intermodalArea = (Geometry) feature.getDefaultGeometry(); + } else { + intermodalArea = intermodalArea.union((Geometry) feature.getDefaultGeometry()); + } + } + + Config config = ConfigUtils.createConfig(); + config.transit().setTransitScheduleFile(input); + config.global().setCoordinateSystem("EPSG:25832"); + Scenario scenario = ScenarioUtils.loadScenario(config); + TransitSchedule transitSchedule = scenario.getTransitSchedule(); + + for (TransitStopFacility stop : transitSchedule.getFacilities().values()) { + if (MGC.coord2Point(stop.getCoord()).within(intermodalArea)) { + // TODO maybe add another filter (e.g. only train station, long distance bus stop...) + stop.getAttributes().putAttribute("allowDrtAccessEgress", "true"); + } + } + + ProjectionUtils.putCRS(transitSchedule, "EPSG:25832"); + + TransitScheduleWriter writer = new TransitScheduleWriter(transitSchedule); + writer.writeFile(output); + + return 0; + } +} From 617d47d23afb48c95f1ec417ee518cf9154b2555 Mon Sep 17 00:00:00 2001 From: Chengqi Lu <43133404+luchengqi7@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:30:41 +0200 Subject: [PATCH 14/34] Update DrtOptions.java --- src/main/java/org/matsim/run/DrtOptions.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/matsim/run/DrtOptions.java b/src/main/java/org/matsim/run/DrtOptions.java index 6eec1bc..7cecc5e 100644 --- a/src/main/java/org/matsim/run/DrtOptions.java +++ b/src/main/java/org/matsim/run/DrtOptions.java @@ -1,5 +1,6 @@ package org.matsim.run; +import ch.sbb.matsim.config.SwissRailRaptorConfigGroup; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.TransportMode; @@ -103,7 +104,22 @@ void configureDrtConfig(Config config) { DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfigGroup, config.scoring(), config.routing()); if (intermodal) { - ConfigUtils.addOrGetModule(config, PtIntermodalRoutingModesConfigGroup.class); + SwissRailRaptorConfigGroup srrConfig = ConfigUtils.addOrGetModule(config, SwissRailRaptorConfigGroup.class); + srrConfig.setUseIntermodalAccessEgress(true); + srrConfig.setIntermodalAccessEgressModeSelection(SwissRailRaptorConfigGroup.IntermodalAccessEgressModeSelection.CalcLeastCostModePerStop); + + SwissRailRaptorConfigGroup.IntermodalAccessEgressParameterSet accessEgressDrtParam = new SwissRailRaptorConfigGroup.IntermodalAccessEgressParameterSet(); + accessEgressDrtParam.setMode(TransportMode.drt); + // Euclidean distance from Hoyerswerda to Ruhland: 20-30 km + accessEgressDrtParam.setInitialSearchRadius(20000); + accessEgressDrtParam.setMaxRadius(30000); + accessEgressDrtParam.setSearchExtensionRadius(1000); + accessEgressDrtParam.setStopFilterAttribute("allowDrtAccessEgress"); + accessEgressDrtParam.setStopFilterValue("true"); + srrConfig.addIntermodalAccessEgress(accessEgressDrtParam); + + // Note: I do not include "walk" as access/egress for intermodal trips, as it should be already taken care of in the transit router. + // If it complains, we can add it back here } } From 076f02827268645a15776a6bf46ccea7136c2295 Mon Sep 17 00:00:00 2001 From: Chengqi Lu <43133404+luchengqi7@users.noreply.github.com> Date: Thu, 19 Sep 2024 15:13:16 +0200 Subject: [PATCH 15/34] Create PrepareIntermodalTestingPlans.java --- .../PrepareIntermodalTestingPlans.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/main/java/org/matsim/run/prepare/testing/PrepareIntermodalTestingPlans.java diff --git a/src/main/java/org/matsim/run/prepare/testing/PrepareIntermodalTestingPlans.java b/src/main/java/org/matsim/run/prepare/testing/PrepareIntermodalTestingPlans.java new file mode 100644 index 0000000..56f5e64 --- /dev/null +++ b/src/main/java/org/matsim/run/prepare/testing/PrepareIntermodalTestingPlans.java @@ -0,0 +1,55 @@ +package org.matsim.run.prepare.testing; + +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.population.*; +import org.matsim.application.MATSimAppCommand; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.scenario.ScenarioUtils; +import picocli.CommandLine; + +import java.util.Random; + +public class PrepareIntermodalTestingPlans implements MATSimAppCommand { + @CommandLine.Option(names = "--output", description = "Path to output population", required = true) + private String output; + + public static void main(String[] args) { + new PrepareIntermodalTestingPlans().execute(args); + } + + @Override + public Integer call() throws Exception { + Random random = new Random(1); + Config config = ConfigUtils.createConfig(); + Scenario scenario = ScenarioUtils.loadScenario(config); + Population population = scenario.getPopulation(); + PopulationFactory populationFactory = population.getFactory(); + + for (int i = 0; i < 500; i++) { + Person person = populationFactory.createPerson(Id.createPersonId("dummy_person_" + i)); + Plan plan = populationFactory.createPlan(); + // a random location in the Hoyerswerda town center + Activity fromAct = populationFactory.createActivityFromLinkId("dummy", Id.createLinkId("-203216578#2")); + // a random time between 6:00-9:00 + fromAct.setEndTime(21600 + random.nextInt(10800)); + // set the link to PT, such that agent could find a potential intermodal trip + Leg leg = populationFactory.createLeg(TransportMode.pt); + // a location close to Cottbus Hbf + Activity toAct = populationFactory.createActivityFromLinkId("dummy", Id.createLinkId("863043626#0")); + + plan.addActivity(fromAct); + plan.addLeg(leg); + plan.addActivity(toAct); + + person.addPlan(plan); + population.addPerson(person); + } + + new PopulationWriter(population).write(output); + + return 0; + } +} From 51d36f7bc212afd8d22f25174095c2c1565d1642 Mon Sep 17 00:00:00 2001 From: Chengqi Lu <43133404+luchengqi7@users.noreply.github.com> Date: Thu, 19 Sep 2024 19:02:35 +0200 Subject: [PATCH 16/34] Update intermodal setup --- src/main/java/org/matsim/run/DrtOptions.java | 14 ++++-- .../org/matsim/run/RunIntegrationTest.java | 45 ++++++++++++++++++- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/matsim/run/DrtOptions.java b/src/main/java/org/matsim/run/DrtOptions.java index 7cecc5e..fe488b8 100644 --- a/src/main/java/org/matsim/run/DrtOptions.java +++ b/src/main/java/org/matsim/run/DrtOptions.java @@ -111,15 +111,21 @@ void configureDrtConfig(Config config) { SwissRailRaptorConfigGroup.IntermodalAccessEgressParameterSet accessEgressDrtParam = new SwissRailRaptorConfigGroup.IntermodalAccessEgressParameterSet(); accessEgressDrtParam.setMode(TransportMode.drt); // Euclidean distance from Hoyerswerda to Ruhland: 20-30 km - accessEgressDrtParam.setInitialSearchRadius(20000); - accessEgressDrtParam.setMaxRadius(30000); + accessEgressDrtParam.setInitialSearchRadius(50000); + accessEgressDrtParam.setMaxRadius(50000); accessEgressDrtParam.setSearchExtensionRadius(1000); accessEgressDrtParam.setStopFilterAttribute("allowDrtAccessEgress"); accessEgressDrtParam.setStopFilterValue("true"); srrConfig.addIntermodalAccessEgress(accessEgressDrtParam); - // Note: I do not include "walk" as access/egress for intermodal trips, as it should be already taken care of in the transit router. - // If it complains, we can add it back here + // TODO adjust the distance after test or make it configurable + SwissRailRaptorConfigGroup.IntermodalAccessEgressParameterSet accessEgressWalkParam = new SwissRailRaptorConfigGroup.IntermodalAccessEgressParameterSet(); + accessEgressWalkParam.setMode(TransportMode.walk); + accessEgressWalkParam.setInitialSearchRadius(300); + accessEgressWalkParam.setMaxRadius(300); + accessEgressWalkParam.setSearchExtensionRadius(0.1); + srrConfig.addIntermodalAccessEgress(accessEgressWalkParam); + } } diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java index 085cfaa..a172498 100644 --- a/src/test/java/org/matsim/run/RunIntegrationTest.java +++ b/src/test/java/org/matsim/run/RunIntegrationTest.java @@ -29,6 +29,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Random; import static org.matsim.application.ApplicationUtils.globFile; @@ -64,12 +65,18 @@ void runScenarioIncludingDrt() { Config config = ConfigUtils.loadConfig(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION)); ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class).defaultDashboards = SimWrapperConfigGroup.Mode.disabled; + Path inputPath = p.resolve("drt-test-population.xml.gz"); + + createDrtTestPopulation(inputPath); + assert MATSimApplication.execute(RunLausitzDrtScenario.class, config, "--1pct", "--iterations", "1", - "--config:plans.inputPlansFile", "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/lausitz/input/v1.1/lausitz-v1.1-1pct.plans-initial.xml.gz", + "--config:plans.inputPlansFile", inputPath.toString(), "--output", utils.getOutputDirectory(), - "--config:controller.overwriteFiles=deleteDirectoryIfExists", "--emissions", "DO_NOT_PERFORM_EMISSIONS_ANALYSIS") + "--config:controller.overwriteFiles=deleteDirectoryIfExists", "--emissions", "DO_NOT_PERFORM_EMISSIONS_ANALYSIS", + "--config:transit.transitScheduleFile", "../v1.0/lausitz-v1.0-transitSchedule-with-intermodal.xml.gz", + "--intermodal") == 0 : "Must return non error code"; Assertions.assertTrue(new File(utils.getOutputDirectory()).isDirectory()); @@ -149,6 +156,40 @@ void runScenarioIncludingAdditionalPtLine() { } + private void createDrtTestPopulation(Path inputPath) { + Random random = new Random(1); + Config config = ConfigUtils.createConfig(); + Scenario scenario = ScenarioUtils.loadScenario(config); + Population population = scenario.getPopulation(); + PopulationFactory populationFactory = population.getFactory(); + + for (int i = 0; i < 500; i++) { + Person person = populationFactory.createPerson(Id.createPersonId("dummy_person_" + i)); + PersonUtils.setIncome(person, 1000.); + Plan plan = populationFactory.createPlan(); + // a random location in the Hoyerswerda town center + Activity fromAct = populationFactory.createActivityFromCoord("home_2400", new Coord(863949.91, 5711547.75)); + // Somewhere near Ruhland Hbf +// Activity fromAct = populationFactory.createActivityFromCoord("home_2400", new Coord(838213.25, 5711776.54)); + // a random time between 6:00-9:00 + fromAct.setEndTime(21600 + random.nextInt(10800)); + // set the link to PT, such that agent could find a potential intermodal trip + Leg leg = populationFactory.createLeg(TransportMode.pt); + // a location close to Cottbus Hbf + Activity toAct = populationFactory.createActivityFromCoord("work_2400", new Coord(867341.75, 5746965.87)); +// somewhere near ruhland hbf +// Activity toAct = populationFactory.createActivityFromCoord("work_2400", new Coord(838646.6900000001, 5711749.89)); + + plan.addActivity(fromAct); + plan.addLeg(leg); + plan.addActivity(toAct); + + person.addPlan(plan); + population.addPerson(person); + } + new PopulationWriter(population).write(inputPath.toString()); + } + private static final class PersonEntersPtVehicleEventHandler implements PersonEntersVehicleEventHandler { static List enterEvents = new ArrayList<>(); From c4f16312f86d64ef8ceceae90d2f7b6922512690 Mon Sep 17 00:00:00 2001 From: sime94 Date: Thu, 19 Sep 2024 21:01:17 +0200 Subject: [PATCH 17/34] re-structure --- .../pt-intermodal-areas-ruhland.cpg | 1 + .../pt-intermodal-areas-ruhland.dbf | Bin 0 -> 77 bytes .../pt-intermodal-areas-ruhland.prj | 1 + .../pt-intermodal-areas-ruhland.shp | Bin 0 -> 236 bytes .../pt-intermodal-areas-ruhland.shx | Bin 0 -> 108 bytes src/main/java/org/matsim/run/DrtOptions.java | 31 ++++++++-- .../org/matsim/run/RunLausitzDrtScenario.java | 2 + .../run/prepare/PrepareTransitSchedule.java | 34 +++++------ .../PrepareIntermodalTestingPlans.java | 55 ------------------ 9 files changed, 44 insertions(+), 80 deletions(-) create mode 100644 input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.cpg create mode 100644 input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.dbf create mode 100644 input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.prj create mode 100644 input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.shp create mode 100644 input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.shx delete mode 100644 src/main/java/org/matsim/run/prepare/testing/PrepareIntermodalTestingPlans.java diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.cpg b/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.cpg new file mode 100644 index 0000000..3ad133c --- /dev/null +++ b/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.cpg @@ -0,0 +1 @@ +UTF-8 \ No newline at end of file diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.dbf b/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.dbf new file mode 100644 index 0000000000000000000000000000000000000000..011beba97d7d8cbbdb20ea0926babad595803053 GIT binary patch literal 77 mcmZRs;S^?MU|?`$;0BVIATtFn<_BVN!MP9yuL2wxN&x_Td;_Kc literal 0 HcmV?d00001 diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.prj b/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.prj new file mode 100644 index 0000000..bd846ae --- /dev/null +++ b/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.prj @@ -0,0 +1 @@ +PROJCS["ETRS_1989_UTM_Zone_32N",GEOGCS["GCS_ETRS_1989",DATUM["D_ETRS_1989",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] \ No newline at end of file diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.shp b/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.shp new file mode 100644 index 0000000000000000000000000000000000000000..3d1a62449ea50d092ff96ca07635a96c8543e09f GIT binary patch literal 236 zcmZQzQ0HR64$59IGcd3M features = shp.readFeatures(); - for (SimpleFeature feature : features) { - if (intermodalArea == null) { - intermodalArea = (Geometry) feature.getDefaultGeometry(); - } else { - intermodalArea = intermodalArea.union((Geometry) feature.getDefaultGeometry()); - } - } - Config config = ConfigUtils.createConfig(); config.transit().setTransitScheduleFile(input); config.global().setCoordinateSystem("EPSG:25832"); Scenario scenario = ScenarioUtils.loadScenario(config); TransitSchedule transitSchedule = scenario.getTransitSchedule(); - for (TransitStopFacility stop : transitSchedule.getFacilities().values()) { - if (MGC.coord2Point(stop.getCoord()).within(intermodalArea)) { - // TODO maybe add another filter (e.g. only train station, long distance bus stop...) - stop.getAttributes().putAttribute("allowDrtAccessEgress", "true"); - } - } + tagIntermodalStops(transitSchedule, shp); ProjectionUtils.putCRS(transitSchedule, "EPSG:25832"); @@ -67,4 +49,18 @@ public Integer call() throws Exception { return 0; } + + /** + * This method does the actual tagging of the intermodal pt stops. + */ + public static void tagIntermodalStops(TransitSchedule transitSchedule, ShpOptions shpOptions) { + Geometry intermodalArea = shpOptions.getGeometry(); + + for (TransitStopFacility stop : transitSchedule.getFacilities().values()) { + if (MGC.coord2Point(stop.getCoord()).within(intermodalArea)) { + //maybe add another filter (e.g. only train station, long distance bus stop...) + stop.getAttributes().putAttribute("allowDrtAccessEgress", "true"); + } + } + } } diff --git a/src/main/java/org/matsim/run/prepare/testing/PrepareIntermodalTestingPlans.java b/src/main/java/org/matsim/run/prepare/testing/PrepareIntermodalTestingPlans.java deleted file mode 100644 index 56f5e64..0000000 --- a/src/main/java/org/matsim/run/prepare/testing/PrepareIntermodalTestingPlans.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.matsim.run.prepare.testing; - -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.population.*; -import org.matsim.application.MATSimAppCommand; -import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigUtils; -import org.matsim.core.scenario.ScenarioUtils; -import picocli.CommandLine; - -import java.util.Random; - -public class PrepareIntermodalTestingPlans implements MATSimAppCommand { - @CommandLine.Option(names = "--output", description = "Path to output population", required = true) - private String output; - - public static void main(String[] args) { - new PrepareIntermodalTestingPlans().execute(args); - } - - @Override - public Integer call() throws Exception { - Random random = new Random(1); - Config config = ConfigUtils.createConfig(); - Scenario scenario = ScenarioUtils.loadScenario(config); - Population population = scenario.getPopulation(); - PopulationFactory populationFactory = population.getFactory(); - - for (int i = 0; i < 500; i++) { - Person person = populationFactory.createPerson(Id.createPersonId("dummy_person_" + i)); - Plan plan = populationFactory.createPlan(); - // a random location in the Hoyerswerda town center - Activity fromAct = populationFactory.createActivityFromLinkId("dummy", Id.createLinkId("-203216578#2")); - // a random time between 6:00-9:00 - fromAct.setEndTime(21600 + random.nextInt(10800)); - // set the link to PT, such that agent could find a potential intermodal trip - Leg leg = populationFactory.createLeg(TransportMode.pt); - // a location close to Cottbus Hbf - Activity toAct = populationFactory.createActivityFromLinkId("dummy", Id.createLinkId("863043626#0")); - - plan.addActivity(fromAct); - plan.addLeg(leg); - plan.addActivity(toAct); - - person.addPlan(plan); - population.addPerson(person); - } - - new PopulationWriter(population).write(output); - - return 0; - } -} From c9a9e355f1638b7827f5fa4c645ff8361d42177c Mon Sep 17 00:00:00 2001 From: sime94 Date: Thu, 19 Sep 2024 21:01:46 +0200 Subject: [PATCH 18/34] class to create manual drt agents WIP --- .../run/prepare/PrepareDrtScenarioAgents.java | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java diff --git a/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java b/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java new file mode 100644 index 0000000..430c052 --- /dev/null +++ b/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java @@ -0,0 +1,143 @@ +package org.matsim.run.prepare; + +import com.google.common.collect.Lists; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.locationtech.jts.geom.Geometry; +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.population.*; +import org.matsim.application.MATSimAppCommand; +import org.matsim.application.options.ShpOptions; +import org.matsim.core.network.NetworkUtils; +import org.matsim.core.population.PopulationUtils; +import org.matsim.core.router.AnalysisMainModeIdentifier; +import org.matsim.core.router.DefaultAnalysisMainModeIdentifier; +import org.matsim.core.router.TripStructureUtils; +import org.matsim.core.utils.geometry.geotools.MGC; +import picocli.CommandLine; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +@CommandLine.Command( + name = "prepare-drt-agents", + description = "Manually create drt plans for agents with pt trips within the drt service area." +) +public class PrepareDrtScenarioAgents implements MATSimAppCommand { + private static final Logger log = LogManager.getLogger(PrepareDrtScenarioAgents.class); + + @CommandLine.Parameters(arity = "1", paramLabel = "INPUT", description = "Path to input population") + private Path input; + @CommandLine.Option(names = "--network", description = "Path to network", required = true) + private Path networkPath; + @CommandLine.Option(names = "--output", description = "Path to output population", required = true) + private Path output; + @CommandLine.Mixin + private final ShpOptions shp = new ShpOptions(); + + private static final String PLAN_TYPE = "drtPlan"; + + public static void main(String[] args) { + new PrepareDrtScenarioAgents().execute(args); + } + + @Override + public Integer call() throws Exception { + if (!Files.exists(input)) { + log.error("Input population does not exist: {}", input); + return 2; + } + + if (!shp.isDefined()) { + log.error("service area shape file is not defined: {}", shp); + return 2; + } + + Population population = PopulationUtils.readPopulation(input.toString()); + Network network = NetworkUtils.readNetwork(networkPath.toString()); + + convertPtToDrtTrips(population, network, shp); + + PopulationUtils.writePopulation(population, output.toString()); + + return 0; + } + + /** + * This is implemented as a separate method to be able to use it in a scenario run class. + * Additionally, it can be used to write a new output population by calling this class. + */ + public static void convertPtToDrtTrips(Population population, Network network, ShpOptions shp) { + Geometry serviceArea = shp.getGeometry(); + + AnalysisMainModeIdentifier identifier = new DefaultAnalysisMainModeIdentifier(); + + log.info("Starting to iterate through population."); + + int count = 0; + for (Person person : population.getPersons().values()) { + Plan selected = person.getSelectedPlan(); +// remove all unselected plans + for (Plan plan : Lists.newArrayList(person.getPlans())) { + if (plan != selected) + person.removePlan(plan); + } + + for (TripStructureUtils.Trip trip : TripStructureUtils.getTrips(selected)) { + + String tripMode = identifier.identifyMainMode(trip.getTripElements()); + + if (!tripMode.equals(TransportMode.pt)) { + continue; + } + + boolean startInside = isInside(network.getLinks().get(trip.getLegsOnly().getFirst().getRoute().getStartLinkId()), serviceArea); + boolean endInside = isInside(network.getLinks().get(trip.getLegsOnly().getLast().getRoute().getEndLinkId()), serviceArea); + +// we only need to change the mode for trips within the drt service area. +// All others will be handled by intermodal trips between drt and pt. +// "other" would be ending in service area but not starting and vice versa + if (startInside && endInside) { + int oldIndex = selected.getPlanElements().indexOf(trip.getLegsOnly().stream().filter(l -> l.getMode().equals(TransportMode.pt)).toList().getFirst()); + + int index = convertPtTripToLeg(trip, selected, identifier); + +// copy pt plan and create drt plan. Tag it as drtPlan + Plan drtCopy = person.createCopyOfSelectedPlanAndMakeSelected(); + ((Leg) drtCopy.getPlanElements().get(index)).setMode(TransportMode.drt); + drtCopy.setType(PLAN_TYPE); + count++; + } + } + } + log.info("For {} trips, a copy of the selected plan with a drt trip has been created.", count); + } + + private static int convertPtTripToLeg(TripStructureUtils.Trip trip, Plan selected, AnalysisMainModeIdentifier identifier) { + final List planElements = selected.getPlanElements(); + +// TODO: test if new leg is pasted at correct index. +// TODO: index in this method is always -1. fix this + + final List fullTrip = + planElements.subList( + planElements.indexOf(trip.getOriginActivity()) + 1, + planElements.indexOf(trip.getDestinationActivity())); + final String mode = identifier.identifyMainMode(fullTrip); + fullTrip.clear(); + Leg leg = PopulationUtils.createLeg(mode); + TripStructureUtils.setRoutingMode(leg, mode); + int index = planElements.indexOf(leg); + fullTrip.add(leg); + if ( fullTrip.size() != 1 ) throw new IllegalArgumentException(fullTrip.toString()); + return index; + } + + private static boolean isInside(Link link, Geometry geometry) { + return MGC.coord2Point(link.getFromNode().getCoord()).within(geometry) || + MGC.coord2Point(link.getToNode().getCoord()).within(geometry); + } +} From db8271472d4f0f5fcc7d6b1500b654e4f819ae46 Mon Sep 17 00:00:00 2001 From: sime94 Date: Mon, 23 Sep 2024 16:41:03 +0200 Subject: [PATCH 19/34] re-structuring --- .../org/matsim/run/LausitzDrtScenario.java | 102 ++++++++++++++++++ .../org/matsim/run/RunLausitzDrtScenario.java | 95 +--------------- .../org/matsim/run/RunIntegrationTest.java | 2 +- 3 files changed, 107 insertions(+), 92 deletions(-) create mode 100644 src/main/java/org/matsim/run/LausitzDrtScenario.java diff --git a/src/main/java/org/matsim/run/LausitzDrtScenario.java b/src/main/java/org/matsim/run/LausitzDrtScenario.java new file mode 100644 index 0000000..b2153c2 --- /dev/null +++ b/src/main/java/org/matsim/run/LausitzDrtScenario.java @@ -0,0 +1,102 @@ +package org.matsim.run; + +import org.matsim.api.core.v01.Scenario; +import org.matsim.application.MATSimApplication; +import org.matsim.contrib.drt.estimator.DrtEstimatorModule; +import org.matsim.contrib.drt.estimator.impl.DirectTripBasedDrtEstimator; +import org.matsim.contrib.drt.estimator.impl.distribution.NormalDistributionGenerator; +import org.matsim.contrib.drt.estimator.impl.trip_estimation.ConstantRideDurationEstimator; +import org.matsim.contrib.drt.estimator.impl.waiting_time_estimation.ConstantWaitingTimeEstimator; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; +import org.matsim.contrib.drt.run.MultiModeDrtModule; +import org.matsim.contrib.dvrp.run.DvrpModule; +import org.matsim.contrib.dvrp.run.DvrpQSimComponents; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.controler.AbstractModule; +import org.matsim.core.controler.Controler; +import picocli.CommandLine; + +import javax.annotation.Nullable; + +/** + * Run the Lausitz scenario including a regional DRT service. + * All necessary configs will be made in this class. + */ +public final class LausitzDrtScenario extends LausitzScenario { + +// run params re drt are contained in separate class DrtOptions + @CommandLine.ArgGroup(heading = "%nDrt options%n", exclusive = false, multiplicity = "0..1") + private final DrtOptions drtOpt = new DrtOptions(); + + private final LausitzScenario baseScenario = new LausitzScenario(sample, emissions); + +// this constructor is needed when this class is to be called from external classes with a given Config (e.g. for testing). + public LausitzDrtScenario(Config config) { + super(config); + } + + public LausitzDrtScenario() { + super(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION)); + } + + public static void main(String[] args) { + MATSimApplication.run(LausitzDrtScenario.class, args); + } + + @Nullable + @Override + protected Config prepareConfig(Config config) { +// apply all config changes from base scenario class + baseScenario.prepareConfig(config); + +// apply all necessary config changes for drt simulation + drtOpt.configureDrtConfig(config); + + return config; + } + + @Override + protected void prepareScenario(Scenario scenario) { +// apply all scenario changes from base scenario class + baseScenario.prepareScenario(scenario); + +// apply all necessary scenario changes for drt simulation + drtOpt.configureDrtScenario(scenario); + } + + @Override + protected void prepareControler(Controler controler) { + Config config = controler.getConfig(); + +// apply all controller changes from base scenario class + baseScenario.prepareControler(controler); + + controler.addOverridingModule(new DvrpModule()); + controler.addOverridingModule(new MultiModeDrtModule()); + +// the following cannot be "experts only" (like requested from KN) because without it DRT would not work +// here, the DynActivityEngine, PreplanningEngine + DvrpModule for each drt mode are added to the qsim components +// this is necessary for drt / dvrp to work! + controler.configureQSimComponents(DvrpQSimComponents.activateAllModes(ConfigUtils.addOrGetModule(controler.getConfig(), MultiModeDrtConfigGroup.class))); + + MultiModeDrtConfigGroup multiModeDrtConfigGroup = MultiModeDrtConfigGroup.get(config); + for (DrtConfigGroup drtConfigGroup : multiModeDrtConfigGroup.getModalElements()) { + controler.addOverridingModule(new AbstractModule() { + @Override + public void install() { + DrtEstimatorModule.bindEstimator(binder(), drtConfigGroup.mode).toInstance( + new DirectTripBasedDrtEstimator.Builder() + .setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(drtOpt.typicalWaitTime)) + .setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, drtOpt.waitTimeStd)) + .setRideDurationEstimator(new ConstantRideDurationEstimator(drtOpt.rideTimeAlpha, drtOpt.rideTimeBeta)) + .setRideDurationDistributionGenerator(new NormalDistributionGenerator(2, drtOpt.rideTimeStd)) + .build() + ); + } + }); + } + + } +} diff --git a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java index 0a914f2..0d06f83 100644 --- a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java +++ b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java @@ -1,104 +1,17 @@ package org.matsim.run; -import org.matsim.api.core.v01.Scenario; import org.matsim.application.MATSimApplication; -import org.matsim.contrib.drt.estimator.DrtEstimatorModule; -import org.matsim.contrib.drt.estimator.impl.DirectTripBasedDrtEstimator; -import org.matsim.contrib.drt.estimator.impl.distribution.NormalDistributionGenerator; -import org.matsim.contrib.drt.estimator.impl.trip_estimation.ConstantRideDurationEstimator; -import org.matsim.contrib.drt.estimator.impl.waiting_time_estimation.ConstantWaitingTimeEstimator; -import org.matsim.contrib.drt.run.DrtConfigGroup; -import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; -import org.matsim.contrib.drt.run.MultiModeDrtModule; -import org.matsim.contrib.dvrp.run.DvrpModule; -import org.matsim.contrib.dvrp.run.DvrpQSimComponents; -import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigUtils; -import org.matsim.core.controler.AbstractModule; -import org.matsim.core.controler.Controler; -import picocli.CommandLine; - -import javax.annotation.Nullable; /** - * Run the Lausitz scenario including a regional DRT service. - * All necessary configs will be made in this class. + * Run the Lausitz DRT scenario policy case. */ -public final class RunLausitzDrtScenario extends MATSimApplication { - -// TODO: re-structure like pt scenario run class - -// run params re drt are contained in separate class DrtOptions - @CommandLine.ArgGroup(heading = "%nDrt options%n", exclusive = false, multiplicity = "0..1") - private final DrtOptions drtOpt = new DrtOptions(); - - private final LausitzScenario baseScenario = new LausitzScenario(); - -// this constructor is needed when this class is to be called from external classes with a given Config (e.g. for testing). - public RunLausitzDrtScenario(Config config) { - super(config); - } +public final class RunLausitzDrtScenario { - public RunLausitzDrtScenario() { - super(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION)); + private RunLausitzDrtScenario() { } public static void main(String[] args) { - MATSimApplication.run(RunLausitzDrtScenario.class, args); - } - - @Nullable - @Override - protected Config prepareConfig(Config config) { -// apply all config changes from base scenario class - baseScenario.prepareConfig(config); - -// apply all necessary config changes for drt simulation - drtOpt.configureDrtConfig(config); - - return config; + MATSimApplication.execute(LausitzDrtScenario.class, args); } - @Override - protected void prepareScenario(Scenario scenario) { -// apply all scenario changes from base scenario class - baseScenario.prepareScenario(scenario); - -// apply all necessary scenario changes for drt simulation - drtOpt.configureDrtScenario(scenario); - } - - @Override - protected void prepareControler(Controler controler) { - Config config = controler.getConfig(); - -// apply all controller changes from base scenario class - baseScenario.prepareControler(controler); - - controler.addOverridingModule(new DvrpModule()); - controler.addOverridingModule(new MultiModeDrtModule()); - -// the following cannot be "experts only" (like requested from KN) because without it DRT would not work -// here, the DynActivityEngine, PreplanningEngine + DvrpModule for each drt mode are added to the qsim components -// this is necessary for drt / dvrp to work! - controler.configureQSimComponents(DvrpQSimComponents.activateAllModes(ConfigUtils.addOrGetModule(controler.getConfig(), MultiModeDrtConfigGroup.class))); - - MultiModeDrtConfigGroup multiModeDrtConfigGroup = MultiModeDrtConfigGroup.get(config); - for (DrtConfigGroup drtConfigGroup : multiModeDrtConfigGroup.getModalElements()) { - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { - DrtEstimatorModule.bindEstimator(binder(), drtConfigGroup.mode).toInstance( - new DirectTripBasedDrtEstimator.Builder() - .setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(drtOpt.typicalWaitTime)) - .setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, drtOpt.waitTimeStd)) - .setRideDurationEstimator(new ConstantRideDurationEstimator(drtOpt.rideTimeAlpha, drtOpt.rideTimeBeta)) - .setRideDurationDistributionGenerator(new NormalDistributionGenerator(2, drtOpt.rideTimeStd)) - .build() - ); - } - }); - } - - } } diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java index 10f2f79..c6cce20 100644 --- a/src/test/java/org/matsim/run/RunIntegrationTest.java +++ b/src/test/java/org/matsim/run/RunIntegrationTest.java @@ -69,7 +69,7 @@ void runScenarioIncludingDrt() { createDrtTestPopulation(inputPath); - assert MATSimApplication.execute(RunLausitzDrtScenario.class, config, + assert MATSimApplication.execute(LausitzDrtScenario.class, config, "--1pct", "--iterations", "1", "--config:plans.inputPlansFile", inputPath.toString(), From 00d05216f6ac48d88042a5c2b4be95b4344eda25 Mon Sep 17 00:00:00 2001 From: sime94 Date: Mon, 23 Sep 2024 17:43:12 +0200 Subject: [PATCH 20/34] max drt walk distance 1km --- src/main/java/org/matsim/run/DrtOptions.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/matsim/run/DrtOptions.java b/src/main/java/org/matsim/run/DrtOptions.java index 0277c50..1269bcc 100644 --- a/src/main/java/org/matsim/run/DrtOptions.java +++ b/src/main/java/org/matsim/run/DrtOptions.java @@ -19,7 +19,7 @@ import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.utils.io.IOUtils; -import org.matsim.run.prepare.PrepareDrtScenarioAgents; +import org.matsim.pt.config.TransitRouterConfigGroup; import org.matsim.run.prepare.PrepareNetwork; import org.matsim.run.prepare.PrepareTransitSchedule; import org.matsim.vehicles.Vehicle; @@ -81,6 +81,8 @@ void configureDrtConfig(Config config) { optimizationConstraintsSet.maxTravelTimeBeta = 1200.; optimizationConstraintsSet.maxTravelTimeAlpha = 1.5; optimizationConstraints.addParameterSet(optimizationConstraintsSet); +// set maxwalk distance to transit search radius. Drt is feeder for Pt. + optimizationConstraintsSet.maxWalkDistance = ConfigUtils.addOrGetModule(config, TransitRouterConfigGroup.class).getSearchRadius(); drtConfigGroup.addParameterSet(optimizationConstraints); drtConfigGroup.addParameterSet(new ExtensiveInsertionSearchParams()); multiModeDrtConfigGroup.addParameterSet(drtConfigGroup); @@ -128,8 +130,8 @@ void configureDrtConfig(Config config) { // walk also needs to be added as access egress mode SwissRailRaptorConfigGroup.IntermodalAccessEgressParameterSet accessEgressWalkParam = new SwissRailRaptorConfigGroup.IntermodalAccessEgressParameterSet(); accessEgressWalkParam.setMode(TransportMode.walk); - accessEgressWalkParam.setInitialSearchRadius(300); - accessEgressWalkParam.setMaxRadius(300); + accessEgressWalkParam.setInitialSearchRadius(1000); + accessEgressWalkParam.setMaxRadius(1000); accessEgressWalkParam.setSearchExtensionRadius(0.1); srrConfig.addIntermodalAccessEgress(accessEgressWalkParam); @@ -171,8 +173,6 @@ void configureDrtScenario(Scenario scenario) { scenario.getVehicles().addVehicle(drtDummy); - PrepareDrtScenarioAgents.convertPtToDrtTrips(scenario.getPopulation(), scenario.getNetwork(), new ShpOptions(drtAreaShp, null, null)); - // tag intermodal pt stops for intermodality between pt and drt if (intermodal == IntermodalityHandling.INTERMODALITY_ACTIVE) { PrepareTransitSchedule.tagIntermodalStops(scenario.getTransitSchedule(), new ShpOptions(intermodalAreaShp, null, null)); From 7288adcea9209499bbe92473e1d6301ef1604601 Mon Sep 17 00:00:00 2001 From: sime94 Date: Mon, 23 Sep 2024 18:02:11 +0200 Subject: [PATCH 21/34] add TODOs --- .../java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java b/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java index 430c052..61ba812 100644 --- a/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java +++ b/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java @@ -103,6 +103,7 @@ public static void convertPtToDrtTrips(Population population, Network network, S if (startInside && endInside) { int oldIndex = selected.getPlanElements().indexOf(trip.getLegsOnly().stream().filter(l -> l.getMode().equals(TransportMode.pt)).toList().getFirst()); +// TODO: erst plan kopieren dann converten int index = convertPtTripToLeg(trip, selected, identifier); // copy pt plan and create drt plan. Tag it as drtPlan @@ -122,6 +123,7 @@ private static int convertPtTripToLeg(TripStructureUtils.Trip trip, Plan selecte // TODO: test if new leg is pasted at correct index. // TODO: index in this method is always -1. fix this +// TODO: rather use trips2LegsALgo instead of copy paste final List fullTrip = planElements.subList( planElements.indexOf(trip.getOriginActivity()) + 1, From 8c6f4ffbc87ca1a69b2722483e1ea20a205efbcd Mon Sep 17 00:00:00 2001 From: sime94 Date: Tue, 1 Oct 2024 15:25:58 +0200 Subject: [PATCH 22/34] add intermodal area incl spremberg --- .../pt-intermodal-areas-ruhland-spremberg.cpg | 1 + .../pt-intermodal-areas-ruhland-spremberg.dbf | Bin 0 -> 88 bytes .../pt-intermodal-areas-ruhland-spremberg.prj | 1 + .../pt-intermodal-areas-ruhland-spremberg.shp | Bin 0 -> 372 bytes .../pt-intermodal-areas-ruhland-spremberg.shx | Bin 0 -> 116 bytes 5 files changed, 2 insertions(+) create mode 100644 input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.cpg create mode 100644 input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.dbf create mode 100644 input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.prj create mode 100644 input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shp create mode 100644 input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shx diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.cpg b/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.cpg new file mode 100644 index 0000000..3ad133c --- /dev/null +++ b/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.cpg @@ -0,0 +1 @@ +UTF-8 \ No newline at end of file diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.dbf b/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.dbf new file mode 100644 index 0000000000000000000000000000000000000000..86dcf5be8d75ad1b3654a3de5949f581b07507af GIT binary patch literal 88 pcmZRs;S^_LU|?`$;0BVIATtFn<_BVN!MP9yuL2wx!dVK&QUI>*1s(tZ literal 0 HcmV?d00001 diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.prj b/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.prj new file mode 100644 index 0000000..bd846ae --- /dev/null +++ b/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.prj @@ -0,0 +1 @@ +PROJCS["ETRS_1989_UTM_Zone_32N",GEOGCS["GCS_ETRS_1989",DATUM["D_ETRS_1989",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] \ No newline at end of file diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shp b/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shp new file mode 100644 index 0000000000000000000000000000000000000000..7ae8a668c935a62f1e9ef9886bac9b835792863d GIT binary patch literal 372 zcmZQzQ0HR64tBj@W?*0i%2^!RX0~gxrlX{zkI~wbp^m@)7_(`t)p9J;xU;48W~d`} z?I@y*K%N6Ov$|exIps4$)A8iPfNiR$LLEU0LFzyNW^YgP)LWN;_R1_^oZc`6p%$ih zWvk#(CZJy9O6{*Fry<;lt{-S56A**lp&*j$HgTnvH?^g65#x#0|yFYpwW`>+aOHoATQ4Dor8 literal 0 HcmV?d00001 diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shx b/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shx new file mode 100644 index 0000000000000000000000000000000000000000..396aee7832499711666314471eb50e621f5cd220 GIT binary patch literal 116 zcmZQzQ0HR64y;}$3s4Z2 literal 0 HcmV?d00001 From 512777d691a12bc669e2b410594250cea4670ff4 Mon Sep 17 00:00:00 2001 From: sime94 Date: Wed, 2 Oct 2024 20:30:01 +0200 Subject: [PATCH 23/34] make drt test runnable --- src/main/java/org/matsim/run/DrtOptions.java | 2 +- .../org/matsim/run/RunIntegrationTest.java | 26 ++++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/matsim/run/DrtOptions.java b/src/main/java/org/matsim/run/DrtOptions.java index 1269bcc..74f4b84 100644 --- a/src/main/java/org/matsim/run/DrtOptions.java +++ b/src/main/java/org/matsim/run/DrtOptions.java @@ -175,7 +175,7 @@ void configureDrtScenario(Scenario scenario) { // tag intermodal pt stops for intermodality between pt and drt if (intermodal == IntermodalityHandling.INTERMODALITY_ACTIVE) { - PrepareTransitSchedule.tagIntermodalStops(scenario.getTransitSchedule(), new ShpOptions(intermodalAreaShp, null, null)); + PrepareTransitSchedule.tagIntermodalStops(scenario.getTransitSchedule(), new ShpOptions(IOUtils.extendUrl(scenario.getConfig().getContext(), intermodalAreaShp).toString(), null, null)); } } } diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java index c6cce20..5781126 100644 --- a/src/test/java/org/matsim/run/RunIntegrationTest.java +++ b/src/test/java/org/matsim/run/RunIntegrationTest.java @@ -71,12 +71,10 @@ void runScenarioIncludingDrt() { assert MATSimApplication.execute(LausitzDrtScenario.class, config, "--1pct", - "--iterations", "1", + "--iterations", "0", "--config:plans.inputPlansFile", inputPath.toString(), "--output", utils.getOutputDirectory(), - "--config:controller.overwriteFiles=deleteDirectoryIfExists", "--emissions", "DO_NOT_PERFORM_EMISSIONS_ANALYSIS", - "--config:transit.transitScheduleFile", "../v1.0/lausitz-v1.0-transitSchedule-with-intermodal.xml.gz", - "--intermodal") + "--config:controller.overwriteFiles=deleteDirectoryIfExists", "--emissions", "DO_NOT_PERFORM_EMISSIONS_ANALYSIS") == 0 : "Must return non error code"; Assertions.assertTrue(new File(utils.getOutputDirectory()).isDirectory()); @@ -187,6 +185,26 @@ private void createDrtTestPopulation(Path inputPath) { person.addPlan(plan); population.addPerson(person); } + + Person drtOnly = populationFactory.createPerson(Id.createPersonId("drtOnly")); + PersonUtils.setIncome(drtOnly, 1000.); + Plan plan = populationFactory.createPlan(); + // a random location in the Hoyerswerda town center + Activity fromAct = populationFactory.createActivityFromCoord("home_2400", new Coord(863949.91, 5711547.75)); + // a random time between 6:00-9:00 + fromAct.setEndTime(21600 + random.nextInt(10800)); + Leg leg = populationFactory.createLeg(TransportMode.drt); + // a location in Wittichenau + Activity toAct = populationFactory.createActivityFromCoord("work_2400", new Coord(864808.3,5705774.7)); + + plan.addActivity(fromAct); + plan.addLeg(leg); + plan.addActivity(toAct); + + drtOnly.addPlan(plan); + population.addPerson(drtOnly); + + new PopulationWriter(population).write(inputPath.toString()); } From cfe5e071032567703a28fccd72747deae36bdb10 Mon Sep 17 00:00:00 2001 From: sime94 Date: Wed, 2 Oct 2024 20:39:12 +0200 Subject: [PATCH 24/34] further improvement --- .../run/prepare/PrepareDrtScenarioAgents.java | 110 +++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java b/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java index 61ba812..f59cbdf 100644 --- a/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java +++ b/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java @@ -10,7 +10,9 @@ import org.matsim.api.core.v01.population.*; import org.matsim.application.MATSimAppCommand; import org.matsim.application.options.ShpOptions; +import org.matsim.core.config.groups.NetworkConfigGroup; import org.matsim.core.network.NetworkUtils; +import org.matsim.core.network.filter.NetworkFilterManager; import org.matsim.core.population.PopulationUtils; import org.matsim.core.router.AnalysisMainModeIdentifier; import org.matsim.core.router.DefaultAnalysisMainModeIdentifier; @@ -39,6 +41,7 @@ public class PrepareDrtScenarioAgents implements MATSimAppCommand { private final ShpOptions shp = new ShpOptions(); private static final String PLAN_TYPE = "drtPlan"; + private static final String PT_INTERACTION = "pt interaction"; public static void main(String[] args) { new PrepareDrtScenarioAgents().execute(args); @@ -59,13 +62,118 @@ public Integer call() throws Exception { Population population = PopulationUtils.readPopulation(input.toString()); Network network = NetworkUtils.readNetwork(networkPath.toString()); - convertPtToDrtTrips(population, network, shp); +// convertPtToDrtTrips(population, network, shp); + +// TODO: try if for 3 and 5 it is enough to delete act locations instead of searching for nearest drt link + convertVspRegionalTrainLegsToDrt(population, network); PopulationUtils.writePopulation(population, output.toString()); return 0; } + private void convertVspRegionalTrainLegsToDrt(Population population, Network network) { +// shp needs to include all locations, where the new pt line (from pt policy case) has a station +// thus, lausitz.shp should be chosen as an input + PrepareNetwork.prepareDrtNetwork(network, shp.getShapeFile()); + + NetworkFilterManager manager = new NetworkFilterManager(network, new NetworkConfigGroup()); + manager.addLinkFilter(l -> l.getAllowedModes().contains(TransportMode.drt)); + Network filtered = manager.applyFilters(); + + for (Person person : population.getPersons().values()) { +// TODO: replace with static call of CleanPopulation method + Plan selected = person.getSelectedPlan(); + for (Plan plan : Lists.newArrayList(person.getPlans())) { + if (plan != selected) + person.removePlan(plan); + } + +// get indexes of pt legs with new pt line + List indexes = TripStructureUtils.getLegs(selected).stream() + .filter(l -> l.getRoute().getStartLinkId().toString().contains("pt_vsp_") + && l.getRoute().getEndLinkId().toString().contains("pt_vsp_")) + .map(l -> selected.getPlanElements().indexOf(l)).toList(); + + for (Integer index : indexes) { + for (int i = 0; i < selected.getPlanElements().size(); i++) { + if ((i == index - 2 || i == index + 2) && selected.getPlanElements().get(i) instanceof Leg leg) { +// access / egress walk leg + if (!(leg.getMode().equals(TransportMode.walk) && leg.getRoutingMode().equals(TransportMode.pt))) { + log.fatal("For selected plan of person {} mode {} and routing mode {} expected for leg at index {}. " + + "Leg has mode {} and routing mode {} instead. Abort.", + person.getId(), TransportMode.walk, TransportMode.pt, i, leg.getMode(), leg.getRoutingMode()); + throw new IllegalStateException(); + } + leg.setRoute(null); + leg.setRoutingMode(TransportMode.drt); + continue; + } + + if (i == index - 1 && selected.getPlanElements().get(i) instanceof Activity act) { +// interaction act before leg + if (!act.getType().equals(PT_INTERACTION)) { + logNotPtInteractionAct(person, act, i); + throw new IllegalStateException(); + } + + if (selected.getPlanElements().get(i - 2) instanceof Activity prev) { + convertToDrtInteraction(act, prev, network, filtered); + } else { + logWrongPlanElementType(person, i); + throw new IllegalStateException(); + } + continue; + } + + if (i == index && selected.getPlanElements().get(i) instanceof Leg leg) { +// pt leg with new pt line + leg.setRoute(null); + leg.setMode(TransportMode.drt); + continue; + } + + if (i == index + 1 && selected.getPlanElements().get(i) instanceof Activity act) { +// interaction act before leg + if (!act.getType().equals(PT_INTERACTION)) { + logNotPtInteractionAct(person, act, i); + throw new IllegalStateException(); + } + if (selected.getPlanElements().get(i + 2) instanceof Activity prev) { + convertToDrtInteraction(act, prev, network, filtered); + } else { + logWrongPlanElementType(person, i); + throw new IllegalStateException(); + } + } + } + } + } + } + + private static void logNotPtInteractionAct(Person person, Activity act, int i) { + log.fatal("For selected plan of person {} type {} expected for activity at index {}. Activity has type {} instead. Abort.", + person.getId(), PT_INTERACTION, i, act.getType()); + } + + private static void logWrongPlanElementType(Person person, int i) { + log.fatal("For the selected plan of person {} the plan element with index {} was expected to be an activity." + + "It seems to be a leg. Abort.", person.getId(), i); + } + + private static void convertToDrtInteraction(Activity act, Activity previous, Network fullNetwork, Network filtered) { +// TODO: test if it is enough to delete link and facility, but keep coord. Correct link shoulb be found automatically then + + if (filtered.getLinks().containsKey(previous.getLinkId())) { + act.setLinkId(previous.getLinkId()); + } else { + act.setLinkId(NetworkUtils.getNearestLink(filtered, fullNetwork.getLinks().get(previous.getLinkId()).getToNode().getCoord()).getId()); + } + act.setFacilityId(null); + act.setCoord(null); + act.setType("drt interaction"); + } + /** * This is implemented as a separate method to be able to use it in a scenario run class. * Additionally, it can be used to write a new output population by calling this class. From 0c01bd410e02d3bf1cd797ef1f913b9cc5d50ad0 Mon Sep 17 00:00:00 2001 From: sime94 Date: Wed, 2 Oct 2024 20:42:21 +0200 Subject: [PATCH 25/34] analyze waiting event and link leave event --- .../matsim/run/analysis/PtLineAnalysis.java | 79 +++++++++++++++---- 1 file changed, 65 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/matsim/run/analysis/PtLineAnalysis.java b/src/main/java/org/matsim/run/analysis/PtLineAnalysis.java index b527005..7a1cf21 100644 --- a/src/main/java/org/matsim/run/analysis/PtLineAnalysis.java +++ b/src/main/java/org/matsim/run/analysis/PtLineAnalysis.java @@ -2,20 +2,32 @@ import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; +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.handler.PersonEntersVehicleEventHandler; +import org.matsim.api.core.v01.events.handler.PersonLeavesVehicleEventHandler; import org.matsim.api.core.v01.population.Person; import org.matsim.application.MATSimAppCommand; +import org.matsim.core.api.experimental.events.AgentWaitingForPtEvent; import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.api.experimental.events.handler.AgentWaitingForPtEventHandler; +import org.matsim.core.config.ConfigUtils; import org.matsim.core.events.EventsUtils; import org.matsim.core.events.MatsimEventsReader; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.pt.transitSchedule.api.TransitSchedule; +import org.matsim.pt.transitSchedule.api.TransitScheduleReader; import picocli.CommandLine; import java.nio.file.Files; import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; + +import static org.matsim.application.ApplicationUtils.globFile; @CommandLine.Command( name = "pt-line", @@ -23,13 +35,14 @@ ) public class PtLineAnalysis implements MATSimAppCommand { - @CommandLine.Option(names = "--events", description = "Events to be analyzed.", required = true) - private String eventsFile; + @CommandLine.Option(names = "--dir", description = "Run directory with necessary data.", required = true) + private Path dir; @CommandLine.Option(names = "--output", description = "Output path", required = true) private String outputPath; - Map, Double> ptPersons = new HashMap<>(); + private final Set> ptPersons = new HashSet<>(); + private final Map, List> eventMap = new HashMap<>(); public static void main(String[] args) { new PtLineAnalysis().execute(args); @@ -37,34 +50,72 @@ public static void main(String[] args) { @Override public Integer call() throws Exception { + String eventsFile = globFile(dir, "*output_events.xml.gz").toString(); + String transitScheduleFile = globFile(dir, "*output_transitSchedule.xml.gz").toString(); + + Scenario scenario = ScenarioUtils.createScenario(ConfigUtils.createConfig()); + TransitScheduleReader transitScheduleReader = new TransitScheduleReader(scenario); + transitScheduleReader.readFile(transitScheduleFile); EventsManager manager = EventsUtils.createEventsManager(); - manager.addHandler(new PersonEntersPtVehicleEventHandler()); + manager.addHandler(new NewPtLineEventHandler(scenario.getTransitSchedule())); manager.initProcessing(); MatsimEventsReader reader = new MatsimEventsReader(manager); reader.readFile(eventsFile); manager.finishProcessing(); +// only keep agents which used new pt line + Map, List> relevantEvents = eventMap.entrySet().stream() + .filter(entry -> ptPersons.contains(entry.getKey())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + 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()); + printer.printRecord("person", "eventType", "time", "x", "y"); + for (Map.Entry, List> e : relevantEvents.entrySet()) { + for (EventData eventData : e.getValue()) { + printer.printRecord(e.getKey().toString(), eventData.eventType, eventData.time, eventData.coord.getX(), eventData.coord.getY()); + } } } - return 0; } - private final class PersonEntersPtVehicleEventHandler implements PersonEntersVehicleEventHandler { + private final class NewPtLineEventHandler implements PersonEntersVehicleEventHandler, PersonLeavesVehicleEventHandler, AgentWaitingForPtEventHandler { + TransitSchedule schedule; + NewPtLineEventHandler(TransitSchedule schedule) { + this.schedule = schedule; + } @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()); + if (event.getVehicleId().toString().contains("RE-VSP1") && !event.getPersonId().toString().contains("pt_")) { + eventMap.get(event.getPersonId()).add(new EventData(event.getEventType(), event.getTime(), new Coord(0, 0))); + ptPersons.add(event.getPersonId()); + } + } + + @Override + public void handleEvent(AgentWaitingForPtEvent event) { + if (!event.getPersonId().toString().contains("pt_")) { + if (!eventMap.containsKey(event.getPersonId())) { + eventMap.put(event.getPersonId(), new ArrayList<>()); } + eventMap.get(event.getPersonId()) + .add(new EventData(event.getEventType(), event.getTime(), new Coord( + schedule.getFacilities().get(event.waitingAtStopId).getCoord().getX(), + schedule.getFacilities().get(event.waitingAtStopId).getCoord().getY()))); + } + + } + + @Override + public void handleEvent(PersonLeavesVehicleEvent event) { + if (ptPersons.contains(event.getPersonId())) { + eventMap.get(event.getPersonId()).add(new EventData(event.getEventType(), event.getTime(), new Coord(0, 0))); } } } + + private record EventData(String eventType, double time, Coord coord) {} } From a2c61a78ead0d52520a8d430f4aa639a38bd3727 Mon Sep 17 00:00:00 2001 From: sime94 Date: Tue, 8 Oct 2024 16:25:39 +0200 Subject: [PATCH 26/34] re-structure --- .../org/matsim/run/RunLausitzDrtScenario.java | 33 +------------------ .../{ => scenarios}/LausitzDrtScenario.java | 17 +++++----- .../org/matsim/run/RunIntegrationTest.java | 5 +-- 3 files changed, 11 insertions(+), 44 deletions(-) rename src/main/java/org/matsim/run/{ => scenarios}/LausitzDrtScenario.java (90%) diff --git a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java index 3de7665..a77f547 100644 --- a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java +++ b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java @@ -1,38 +1,7 @@ package org.matsim.run; import org.matsim.application.MATSimApplication; -import org.matsim.application.options.ShpOptions; -import org.matsim.contrib.drt.optimizer.constraints.DefaultDrtOptimizationConstraintsSet; -import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsParams; -import org.matsim.contrib.drt.optimizer.insertion.extensive.ExtensiveInsertionSearchParams; -import org.matsim.contrib.drt.routing.DrtRoute; -import org.matsim.contrib.drt.routing.DrtRouteFactory; -import org.matsim.contrib.drt.run.DrtConfigGroup; -import org.matsim.contrib.drt.run.DrtConfigs; -import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; -import org.matsim.contrib.drt.run.MultiModeDrtModule; -import org.matsim.contrib.dvrp.run.DvrpConfigGroup; -import org.matsim.contrib.dvrp.run.DvrpModule; -import org.matsim.contrib.dvrp.run.DvrpQSimComponents; -import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.QSimConfigGroup; -import org.matsim.core.config.groups.ScoringConfigGroup; -import org.matsim.core.config.groups.SubtourModeChoiceConfigGroup; -import org.matsim.core.controler.Controler; -import org.matsim.core.network.algorithms.MultimodalNetworkCleaner; -import org.matsim.core.utils.geometry.geotools.MGC; -import org.matsim.run.scenarios.LausitzScenario; -import org.matsim.vehicles.Vehicle; -import org.matsim.vehicles.VehicleCapacity; -import org.matsim.vehicles.VehicleType; -import org.matsim.vehicles.VehicleUtils; -import picocli.CommandLine; - -import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import org.matsim.run.scenarios.LausitzDrtScenario; /** * Run the Lausitz DRT scenario policy case. diff --git a/src/main/java/org/matsim/run/LausitzDrtScenario.java b/src/main/java/org/matsim/run/scenarios/LausitzDrtScenario.java similarity index 90% rename from src/main/java/org/matsim/run/LausitzDrtScenario.java rename to src/main/java/org/matsim/run/scenarios/LausitzDrtScenario.java index b2153c2..f35639f 100644 --- a/src/main/java/org/matsim/run/LausitzDrtScenario.java +++ b/src/main/java/org/matsim/run/scenarios/LausitzDrtScenario.java @@ -1,4 +1,4 @@ -package org.matsim.run; +package org.matsim.run.scenarios; import org.matsim.api.core.v01.Scenario; import org.matsim.application.MATSimApplication; @@ -16,6 +16,7 @@ import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; +import org.matsim.run.DrtOptions; import picocli.CommandLine; import javax.annotation.Nullable; @@ -47,7 +48,7 @@ public static void main(String[] args) { @Nullable @Override - protected Config prepareConfig(Config config) { + public Config prepareConfig(Config config) { // apply all config changes from base scenario class baseScenario.prepareConfig(config); @@ -58,7 +59,7 @@ protected Config prepareConfig(Config config) { } @Override - protected void prepareScenario(Scenario scenario) { + public void prepareScenario(Scenario scenario) { // apply all scenario changes from base scenario class baseScenario.prepareScenario(scenario); @@ -67,7 +68,7 @@ protected void prepareScenario(Scenario scenario) { } @Override - protected void prepareControler(Controler controler) { + public void prepareControler(Controler controler) { Config config = controler.getConfig(); // apply all controller changes from base scenario class @@ -88,10 +89,10 @@ protected void prepareControler(Controler controler) { public void install() { DrtEstimatorModule.bindEstimator(binder(), drtConfigGroup.mode).toInstance( new DirectTripBasedDrtEstimator.Builder() - .setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(drtOpt.typicalWaitTime)) - .setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, drtOpt.waitTimeStd)) - .setRideDurationEstimator(new ConstantRideDurationEstimator(drtOpt.rideTimeAlpha, drtOpt.rideTimeBeta)) - .setRideDurationDistributionGenerator(new NormalDistributionGenerator(2, drtOpt.rideTimeStd)) + .setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(drtOpt.getTypicalWaitTime())) + .setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, drtOpt.getWaitTimeStd())) + .setRideDurationEstimator(new ConstantRideDurationEstimator(drtOpt.getRideTimeAlpha(), drtOpt.getRideTimeBeta())) + .setRideDurationDistributionGenerator(new NormalDistributionGenerator(2, drtOpt.getRideTimeStd())) .build() ); } diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java index e4a9f5b..b8da09c 100644 --- a/src/test/java/org/matsim/run/RunIntegrationTest.java +++ b/src/test/java/org/matsim/run/RunIntegrationTest.java @@ -25,10 +25,7 @@ import org.matsim.core.router.TripStructureUtils; import org.matsim.core.scenario.ScenarioUtils; import org.matsim.pt.transitSchedule.api.*; -import org.matsim.run.scenarios.LausitzPtScenario; -import org.matsim.run.scenarios.LausitzScenario; -import org.matsim.run.scenarios.LausitzSingleModeScenario; -import org.matsim.run.scenarios.LausitzSpeedReductionScenario; +import org.matsim.run.scenarios.*; import org.matsim.simwrapper.SimWrapperConfigGroup; import org.matsim.testcases.MatsimTestUtils; From f37c47acce3e14e23529bc599eacbf58f62a8b1f Mon Sep 17 00:00:00 2001 From: sime94 Date: Tue, 8 Oct 2024 16:26:11 +0200 Subject: [PATCH 27/34] add getters, add method to check and adapt service area shp file --- src/main/java/org/matsim/run/DrtOptions.java | 54 ++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/matsim/run/DrtOptions.java b/src/main/java/org/matsim/run/DrtOptions.java index 74f4b84..f92c6d9 100644 --- a/src/main/java/org/matsim/run/DrtOptions.java +++ b/src/main/java/org/matsim/run/DrtOptions.java @@ -1,6 +1,9 @@ package org.matsim.run; import ch.sbb.matsim.config.SwissRailRaptorConfigGroup; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.geotools.api.feature.simple.SimpleFeature; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.TransportMode; @@ -18,6 +21,7 @@ import org.matsim.core.config.ConfigUtils; import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.config.groups.ScoringConfigGroup; +import org.matsim.core.utils.gis.GeoFileWriter; import org.matsim.core.utils.io.IOUtils; import org.matsim.pt.config.TransitRouterConfigGroup; import org.matsim.run.prepare.PrepareNetwork; @@ -28,12 +32,15 @@ import org.matsim.vehicles.VehicleUtils; import picocli.CommandLine; +import java.util.List; import java.util.Set; /** * This class bundles some run parameter options and functionalities connected to drt-scenarios. */ public class DrtOptions { + private static final Logger log = LogManager.getLogger(DrtOptions.class); + @CommandLine.Option(names = "--drt-shp", description = "Path to shp file for adding drt not network links as an allowed mode.", defaultValue = "./drt-area/nord-bautzen-waiting-times_utm32N.shp") private String drtAreaShp; @@ -58,11 +65,12 @@ public class DrtOptions { @CommandLine.Option(names = "--intermodal", defaultValue = "INTERMODALITY_ACTIVE", description = "enable intermodality for DRT service") private IntermodalityHandling intermodal; - /** * a helper method, which makes all necessary config changes to simulate drt. */ - void configureDrtConfig(Config config) { + public void configureDrtConfig(Config config) { +// check if every feature of shp file has attr typ_wt for drt estimation. Add attr with standard value if not present. + checkServiceAreaShapeFile(config); DvrpConfigGroup dvrpConfigGroup = ConfigUtils.addOrGetModule(config, DvrpConfigGroup.class); dvrpConfigGroup.networkModes = Set.of(TransportMode.drt); @@ -141,7 +149,7 @@ void configureDrtConfig(Config config) { /** * a helper method, which makes all necessary scenario changes to simulate drt. */ - void configureDrtScenario(Scenario scenario) { + public void configureDrtScenario(Scenario scenario) { // drt route factory has to be added as factory for drt routes, as there were no drt routes before. scenario.getPopulation() @@ -180,10 +188,50 @@ void configureDrtScenario(Scenario scenario) { } } + private void checkServiceAreaShapeFile(Config config) { + ShpOptions shp = new ShpOptions(drtAreaShp, null, null); + List features = shp.readFeatures(); + boolean adapted = false; + for (SimpleFeature feature : features) { + if (feature.getAttribute("typ_wt") == null) { + feature.setAttribute("typ_wt", 10 * 60.); + adapted = true; + } + } + + if (adapted) { + log.warn("For drt service area shape file {}, at least one feature did not have the obligatory attribute typ_wt. " + + "The attribute is needed for drt estimation. The attribute was added with a standard value of 10min for those features.", drtAreaShp); + + GeoFileWriter.writeGeometries(features, IOUtils.extendUrl(config.getContext(), drtAreaShp).toString()); + log.warn("Adapted drt service area shp file written to {}.", drtAreaShp); + } + } + public String getDrtAreaShp() { return drtAreaShp; } + public double getTypicalWaitTime() { + return typicalWaitTime; + } + + public double getWaitTimeStd() { + return waitTimeStd; + } + + public double getRideTimeAlpha() { + return rideTimeAlpha; + } + + public double getRideTimeBeta() { + return rideTimeBeta; + } + + public double getRideTimeStd() { + return rideTimeStd; + } + /** * Defines if all necessary configs for intermodality between drt and pt should be made. */ From ead05fb860dd64fe999deb79d80862d7ed061163 Mon Sep 17 00:00:00 2001 From: sime94 Date: Tue, 8 Oct 2024 16:31:11 +0200 Subject: [PATCH 28/34] add test + feinschliff --- ...case-test_experienced_plans_1person.xml.gz | Bin 0 -> 1980 bytes .../run/prepare/PrepareDrtScenarioAgents.java | 43 ++++++---- .../matsim/run/scenarios/LausitzScenario.java | 4 +- .../prepare/PrepareDrtScenarioAgentsTest.java | 75 ++++++++++++++++++ 4 files changed, 106 insertions(+), 16 deletions(-) create mode 100644 input/v1.1/lausitz-pt-case-test_experienced_plans_1person.xml.gz create mode 100644 src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java diff --git a/input/v1.1/lausitz-pt-case-test_experienced_plans_1person.xml.gz b/input/v1.1/lausitz-pt-case-test_experienced_plans_1person.xml.gz new file mode 100644 index 0000000000000000000000000000000000000000..12097b49de657496c74a3ee0d7ae05d7abf4e79e GIT binary patch literal 1980 zcmV;t2SfNDiwFoVAO&Xx0Bm7(b7^#XEpT)#V_|b;Ep%mbbYEq7aAk67Wo~0-WM6P> zVQzC@F>qyab8l`gcx`L|?ONMz(?Ae?hOaQ@m2CEYu^M>bA|Zi5fRK2yOk#>5O(NSZ zREU3P)=9ka+9b}UP$Z&ARkog8&z#vaXU9H!^!;KQT%~!D&1a*KARGqiY&@T2v-44S zS$-Pm@X^D&XZN1Gdi?Ig>!-nDzPOwwC0rf6{qXkP)0aW`xhxmaaQN-pH*}GdMRtMa z`T6iuHcgA+q?`<$Nqi*{jD!#G-aT`p_Se0^AQ+wG6AT70;hnPu_yjkZO-7;Q6blNg z-htt1G7F0FJWofVp@;~^8Pmj2rL_rzBAuq=G6kdSw6GRnl8npjDl4yp@_GSQpXV28 z%%#Q~LY0!ex_rf$gxYr&>4wTUB}GjqSv?CSTvM%~g#4bJ#XZ zYuh1@d<{|x*Pr8g_$0N}A|f3TyRk!vcy0J!I`x-MmE2YIAhqiQsi5LFfD{on5taJ` zxib6@WPc!Uc%KS5l0=kLetBa%;jL-dGxUN{oqPU4csYS_tcdLLrvWZA!XUzM{W-qI z){C#PHBv!|C0a?PgC8T$DG7;l{4*^kx%9${0lgL&JzsgEiH?VXVq1IYAkf5d~^&>LF>tV7qy?M$t3$ z{U$tOC*O;wLh&~&yC`D>5GXdWc~LQ!6ev zjxQ8x_(;kH6)ivo^m~@Rcw;*OU6c+^XLcls4y)2d1Nlz0IhPF2~Y%(vv7A38(k-}Ej5M`sWs8f5@Y=Z zna@}ib#H8EF4yGb8Txot-~QQrQ;F9mCl^64>#mALj62=fOgoJ5(Nt8e^q25klzq@+ z62AS>+lPy&(B!sq(Gr+;T8Pg0G|qccVn~fn4tn!+@c!*<0yB3}4`m=jed=*mOUBvC zCp!KO>lB~o;2ren7!ol)nsus3tfed?u&@9v1RW{97DHSrt`Sf&w(^#?(w3VDJ5A)q z4(JiB3_W0MH0jA(fcxi|M>~E9U4kh|jbu=syBuk@{xF>OK^hY#4R8jPtS=9xIi%L4 zh>3d`>egLLA|*f}$Tg18rj$tg0P2b?*3APqc95uD8McpPH_*d95rB2jJc_Uh-|0s~ z(MrUb)RaNHKpEWsXzB0A#$?ob6^F!4HtL4WUYU9HDhgjwYUED2_OW8QbH- z%jShQwli^S>hTQ!v19ZyhF*@r6ASW3&e5>Y-@l(w>&GuISyV||)JH5>VcZ3Th%$mg3%y%rm} z2=;%q23+xz4>8H?E50%%I%f1v{y)->szBT>u&JDbh4U=!Y O^8E{=h(u(0E&u= indexes = TripStructureUtils.getLegs(selected).stream() - .filter(l -> l.getRoute().getStartLinkId().toString().contains("pt_vsp_") - && l.getRoute().getEndLinkId().toString().contains("pt_vsp_")) - .map(l -> selected.getPlanElements().indexOf(l)).toList(); + List indexes = getNewPtLineIndexes(selected); + +// only remove routes from legs if no legs with new vsp pt line + if (indexes.isEmpty()) { + TripStructureUtils.getLegs(selected).forEach(CleanPopulation::removeRouteFromLeg); + continue; + } for (Integer index : indexes) { for (int i = 0; i < selected.getPlanElements().size(); i++) { @@ -105,8 +106,10 @@ private void convertVspRegionalTrainLegsToDrt(Population population, Network net person.getId(), TransportMode.walk, TransportMode.pt, i, leg.getMode(), leg.getRoutingMode()); throw new IllegalStateException(); } - leg.setRoute(null); + CleanPopulation.removeRouteFromLeg(leg); leg.setRoutingMode(TransportMode.drt); + leg.setTravelTimeUndefined(); + leg.setDepartureTimeUndefined(); continue; } @@ -130,17 +133,20 @@ private void convertVspRegionalTrainLegsToDrt(Population population, Network net // pt leg with new pt line leg.setRoute(null); leg.setMode(TransportMode.drt); + leg.setTravelTimeUndefined(); + leg.setDepartureTimeUndefined(); + leg.getAttributes().removeAttribute("enterVehicleTime"); continue; } if (i == index + 1 && selected.getPlanElements().get(i) instanceof Activity act) { -// interaction act before leg +// interaction act after leg if (!act.getType().equals(PT_INTERACTION)) { logNotPtInteractionAct(person, act, i); throw new IllegalStateException(); } - if (selected.getPlanElements().get(i + 2) instanceof Activity prev) { - convertToDrtInteraction(act, prev, network, filtered); + if (selected.getPlanElements().get(i + 2) instanceof Activity next) { + convertToDrtInteraction(act, next, network, filtered); } else { logWrongPlanElementType(person, i); throw new IllegalStateException(); @@ -151,6 +157,13 @@ private void convertVspRegionalTrainLegsToDrt(Population population, Network net } } + public static @NotNull List getNewPtLineIndexes(Plan selected) { + return TripStructureUtils.getLegs(selected).stream() + .filter(l -> l.getRoute().getStartLinkId().toString().contains("pt_vsp_") + && l.getRoute().getEndLinkId().toString().contains("pt_vsp_")) + .map(l -> selected.getPlanElements().indexOf(l)).toList(); + } + private static void logNotPtInteractionAct(Person person, Activity act, int i) { log.fatal("For selected plan of person {} type {} expected for activity at index {}. Activity has type {} instead. Abort.", person.getId(), PT_INTERACTION, i, act.getType()); diff --git a/src/main/java/org/matsim/run/scenarios/LausitzScenario.java b/src/main/java/org/matsim/run/scenarios/LausitzScenario.java index d082bb2..30803be 100644 --- a/src/main/java/org/matsim/run/scenarios/LausitzScenario.java +++ b/src/main/java/org/matsim/run/scenarios/LausitzScenario.java @@ -34,6 +34,7 @@ import org.matsim.run.analysis.CommunityFilter; import org.matsim.run.analysis.CommuterAnalysis; import org.matsim.run.analysis.DistanceMatrix; +import org.matsim.run.prepare.PrepareDrtScenarioAgents; import org.matsim.run.prepare.PrepareNetwork; import org.matsim.run.prepare.PreparePopulation; import org.matsim.simwrapper.SimWrapperConfigGroup; @@ -54,7 +55,8 @@ CreateNetworkFromSumo.class, CreateTransitScheduleFromGtfs.class, TrajectoryToPlans.class, GenerateShortDistanceTrips.class, MergePopulations.class, ExtractRelevantFreightTrips.class, DownSamplePopulation.class, ExtractHomeCoordinates.class, CleanNetwork.class, CreateLandUseShp.class, ResolveGridCoordinates.class, FixSubtourModes.class, AdjustActivityToLinkDistances.class, XYToLinks.class, - SplitActivityTypesDuration.class, CreateCountsFromBAStData.class, PreparePopulation.class, CleanPopulation.class, PrepareNetwork.class + SplitActivityTypesDuration.class, CreateCountsFromBAStData.class, PreparePopulation.class, CleanPopulation.class, PrepareNetwork.class, + PrepareDrtScenarioAgents.class }) @MATSimApplication.Analysis({ LinkStats.class, CheckPopulation.class, CommuterAnalysis.class, CommunityFilter.class, DistanceMatrix.class diff --git a/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java b/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java new file mode 100644 index 0000000..61b690a --- /dev/null +++ b/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java @@ -0,0 +1,75 @@ +package org.matsim.run.prepare; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.api.core.v01.population.*; +import org.matsim.application.MATSimApplication; +import org.matsim.core.population.PopulationUtils; +import org.matsim.run.scenarios.LausitzScenario; +import org.matsim.testcases.MatsimTestUtils; + +import java.util.List; + +class PrepareDrtScenarioAgentsTest { + @RegisterExtension + private final MatsimTestUtils utils = new MatsimTestUtils(); + private static final String URL = String.format("https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/lausitz/input/v%s/", + LausitzScenario.VERSION); + private static final Id PERSON_ID = Id.createPersonId("642052"); + + @Test + void testPrepareDrtScenarioAgents() { + String inputPopulationPath = "./input/v1.1/lausitz-pt-case-test_experienced_plans_1person.xml.gz"; + Population in = PopulationUtils.readPopulation(inputPopulationPath); + String networkPath = URL + String.format("lausitz-v%s-network-with-pt.xml.gz", LausitzScenario.VERSION); + String outPath = utils.getOutputDirectory() + "/drt-test-population.xml.gz"; + + assert MATSimApplication.execute(LausitzScenario.class, "prepare", "prepare-drt-agents", + inputPopulationPath, + "--network", networkPath, + "--output", outPath, + "--shp", "./input/shp/lausitz.shp") + == 0 : "Must return non error code"; + + Population out = PopulationUtils.readPopulation(outPath); + List outSelectedPlanElements = out.getPersons().get(PERSON_ID).getSelectedPlan().getPlanElements(); + +// there is only 1 person in the population + for (int index : PrepareDrtScenarioAgents.getNewPtLineIndexes(in.getPersons().get(PERSON_ID).getSelectedPlan())) { +// access leg + Assertions.assertInstanceOf(Leg.class, outSelectedPlanElements.get(index - 2)); + Leg access = (Leg) outSelectedPlanElements.get(index - 2); + Assertions.assertNull(access.getRoute()); + Assertions.assertEquals(TransportMode.drt, access.getRoutingMode()); + +// interaction act before leg + Assertions.assertInstanceOf(Activity.class, outSelectedPlanElements.get(index - 1)); + Activity before = (Activity) outSelectedPlanElements.get(index - 1); + Assertions.assertNull(before.getCoord()); + Assertions.assertNull(before.getFacilityId()); + Assertions.assertEquals("drt interaction", before.getType()); + +// pt leg which was converted to drt leg + Assertions.assertInstanceOf(Leg.class, outSelectedPlanElements.get(index)); + Leg leg = (Leg) outSelectedPlanElements.get(index); + Assertions.assertNull(leg.getRoute()); + Assertions.assertEquals(TransportMode.drt, leg.getMode()); + + // interaction act after leg + Assertions.assertInstanceOf(Activity.class, outSelectedPlanElements.get(index + 1)); + Activity after = (Activity) outSelectedPlanElements.get(index + 1); + Assertions.assertNull(after.getCoord()); + Assertions.assertNull(after.getFacilityId()); + Assertions.assertEquals("drt interaction", after.getType()); + + // egress leg + Assertions.assertInstanceOf(Leg.class, outSelectedPlanElements.get(index + 2)); + Leg egress = (Leg) outSelectedPlanElements.get(index + 2); + Assertions.assertNull(egress.getRoute()); + Assertions.assertEquals(TransportMode.drt, egress.getRoutingMode()); + } + } +} From d7baf7ebf5094cfad8821764913c96ef3511d353 Mon Sep 17 00:00:00 2001 From: sime94 Date: Wed, 9 Oct 2024 11:07:44 +0200 Subject: [PATCH 29/34] use drt area getter in all places --- src/main/java/org/matsim/run/DrtOptions.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/matsim/run/DrtOptions.java b/src/main/java/org/matsim/run/DrtOptions.java index f92c6d9..9de6cb7 100644 --- a/src/main/java/org/matsim/run/DrtOptions.java +++ b/src/main/java/org/matsim/run/DrtOptions.java @@ -80,7 +80,7 @@ public void configureDrtConfig(Config config) { DrtConfigGroup drtConfigGroup = new DrtConfigGroup(); drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.serviceAreaBased; drtConfigGroup.stopDuration = 60.; - drtConfigGroup.drtServiceAreaShapeFile = getDrtAreaShp(); + drtConfigGroup.drtServiceAreaShapeFile = IOUtils.extendUrl(config.getContext(), getDrtAreaShp()).toString(); // optimization params now are in its own paramSet, hence the below lines DrtOptimizationConstraintsParams optimizationConstraints = new DrtOptimizationConstraintsParams(); @@ -189,7 +189,7 @@ public void configureDrtScenario(Scenario scenario) { } private void checkServiceAreaShapeFile(Config config) { - ShpOptions shp = new ShpOptions(drtAreaShp, null, null); + ShpOptions shp = new ShpOptions(getDrtAreaShp(), null, null); List features = shp.readFeatures(); boolean adapted = false; for (SimpleFeature feature : features) { @@ -201,10 +201,10 @@ private void checkServiceAreaShapeFile(Config config) { if (adapted) { log.warn("For drt service area shape file {}, at least one feature did not have the obligatory attribute typ_wt. " + - "The attribute is needed for drt estimation. The attribute was added with a standard value of 10min for those features.", drtAreaShp); + "The attribute is needed for drt estimation. The attribute was added with a standard value of 10min for those features.", getDrtAreaShp()); - GeoFileWriter.writeGeometries(features, IOUtils.extendUrl(config.getContext(), drtAreaShp).toString()); - log.warn("Adapted drt service area shp file written to {}.", drtAreaShp); + GeoFileWriter.writeGeometries(features, IOUtils.extendUrl(config.getContext(), getDrtAreaShp()).toString()); + log.warn("Adapted drt service area shp file written to {}.", IOUtils.extendUrl(config.getContext(), getDrtAreaShp())); } } From 4a7be7e6357eba8d1b2f57665a2914c5fe291175 Mon Sep 17 00:00:00 2001 From: sime94 Date: Wed, 9 Oct 2024 18:29:25 +0200 Subject: [PATCH 30/34] make first test work --- ...case-test_experienced_plans_1person.xml.gz | Bin 1980 -> 0 bytes .../lausitz-pt-case-test_plans_1person.xml.gz | Bin 0 -> 2338 bytes src/main/java/org/matsim/run/DrtOptions.java | 90 +++++++++++-- .../run/prepare/PrepareDrtScenarioAgents.java | 119 ++++-------------- .../prepare/PrepareDrtScenarioAgentsTest.java | 2 +- 5 files changed, 100 insertions(+), 111 deletions(-) delete mode 100644 input/v1.1/lausitz-pt-case-test_experienced_plans_1person.xml.gz create mode 100644 input/v1.1/lausitz-pt-case-test_plans_1person.xml.gz diff --git a/input/v1.1/lausitz-pt-case-test_experienced_plans_1person.xml.gz b/input/v1.1/lausitz-pt-case-test_experienced_plans_1person.xml.gz deleted file mode 100644 index 12097b49de657496c74a3ee0d7ae05d7abf4e79e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1980 zcmV;t2SfNDiwFoVAO&Xx0Bm7(b7^#XEpT)#V_|b;Ep%mbbYEq7aAk67Wo~0-WM6P> zVQzC@F>qyab8l`gcx`L|?ONMz(?Ae?hOaQ@m2CEYu^M>bA|Zi5fRK2yOk#>5O(NSZ zREU3P)=9ka+9b}UP$Z&ARkog8&z#vaXU9H!^!;KQT%~!D&1a*KARGqiY&@T2v-44S zS$-Pm@X^D&XZN1Gdi?Ig>!-nDzPOwwC0rf6{qXkP)0aW`xhxmaaQN-pH*}GdMRtMa z`T6iuHcgA+q?`<$Nqi*{jD!#G-aT`p_Se0^AQ+wG6AT70;hnPu_yjkZO-7;Q6blNg z-htt1G7F0FJWofVp@;~^8Pmj2rL_rzBAuq=G6kdSw6GRnl8npjDl4yp@_GSQpXV28 z%%#Q~LY0!ex_rf$gxYr&>4wTUB}GjqSv?CSTvM%~g#4bJ#XZ zYuh1@d<{|x*Pr8g_$0N}A|f3TyRk!vcy0J!I`x-MmE2YIAhqiQsi5LFfD{on5taJ` zxib6@WPc!Uc%KS5l0=kLetBa%;jL-dGxUN{oqPU4csYS_tcdLLrvWZA!XUzM{W-qI z){C#PHBv!|C0a?PgC8T$DG7;l{4*^kx%9${0lgL&JzsgEiH?VXVq1IYAkf5d~^&>LF>tV7qy?M$t3$ z{U$tOC*O;wLh&~&yC`D>5GXdWc~LQ!6ev zjxQ8x_(;kH6)ivo^m~@Rcw;*OU6c+^XLcls4y)2d1Nlz0IhPF2~Y%(vv7A38(k-}Ej5M`sWs8f5@Y=Z zna@}ib#H8EF4yGb8Txot-~QQrQ;F9mCl^64>#mALj62=fOgoJ5(Nt8e^q25klzq@+ z62AS>+lPy&(B!sq(Gr+;T8Pg0G|qccVn~fn4tn!+@c!*<0yB3}4`m=jed=*mOUBvC zCp!KO>lB~o;2ren7!ol)nsus3tfed?u&@9v1RW{97DHSrt`Sf&w(^#?(w3VDJ5A)q z4(JiB3_W0MH0jA(fcxi|M>~E9U4kh|jbu=syBuk@{xF>OK^hY#4R8jPtS=9xIi%L4 zh>3d`>egLLA|*f}$Tg18rj$tg0P2b?*3APqc95uD8McpPH_*d95rB2jJc_Uh-|0s~ z(MrUb)RaNHKpEWsXzB0A#$?ob6^F!4HtL4WUYU9HDhgjwYUED2_OW8QbH- z%jShQwli^S>hTQ!v19ZyhF*@r6ASW3&e5>Y-@l(w>&GuISyV||)JH5>VcZ3Th%$mg3%y%rm} z2=;%q23+xz4>8H?E50%%I%f1v{y)->szBT>u&JDbh4U=!Y O^8E{=h(u(0E&u= zVQzC@F>qyab8l`gcx`L|?OWNd(=ZTyhOY?Wl?LxiML~!~LIQyRA@Nj&Hk3d&B`K@; zcaGa;X%f=X_Cg=1DqY)g#`esdIb*x`&b_a*srNZb(s(f+_%tBC7tKeDaXg<4{8je8 zXZ(A2uiv@x@cDz+Z(ls}mW$)t$^MFT&aM7}qghG{zRKZc*fU>eRR!IOCwO`^oVYwz4H-e?yv z3X}Vv!+6>v!p%63%HG+oRm592fo=cDLx z62+4bl~AfT`&rXXrJAnmOX$-}M~eh%vMivI3(gI-OdDf; zFO8#m+{=^oj0M2yvq{0$)3Z;w%oQkLKgoaVM6T)`m2|RM*D3Az$34I*lgY zY%#`IU&84p-y28E`g9MTZL(NpaN1`O*WuC5l>6s-?T(WcZ7nc~=1~%lV67}nvSGsr z8$GwSXG!=uUlHl!DeD#_>RysgV*+d0%s=DzY0Oy;za9%wKw ziPcKlo1|ec-WQ^3FKUbo6kgv(wU^QRC*#3Rn7CUV$Lk5MgdtS#lxd|*yt2Ra1UFI} zt2{IqVVH97Q3)r(6LV8kD!Wf;r2?5k7)hDo7-&-x=uwo>p|a`|J+2hAbvWr9&T`9? z6jB#4i5jW`3s<*9Dt(N@wZsTY`;1?L!_{I$LpO(d9M+=?kK1qtA&9SB;*VfV9U38` z@oF?&Ch;sxz744sgmhVq>41sSQk)02N*AArGPWxyfTY-3umPxWKnmG=$Ru|LrK4&%Nuz}X3`0OE(a!8L!aJ1&y@dolbB#%buq9i4E2n zNYx&^T45)8@?T7X+Cq=&^NUD=E--IhZ)P+*aW6wiG~w4LsMpSV~U zHyBA`@7ZVc5={0ddl^B|PBc|DbFDYiJLck6+JJIWeAM6F)ljRc=8Q7*-8S<|(UFs| z1j~_NI7c*8P~~x?s*Fpt=>H4ZAAJ zF=vvO*XvaVWzCJ)aIv(Md-+?e=&ACOa-_+vkXVaXm_&Pcqy^lTdsaaSLNHoBmSvHb zMOGHoiD)Y1s!&P~fQIO15WkS8{$nbkjZi z_H3E$pXKrH(7}aV^@XiE1mm0qlHj11GfNCJ2YbXiL88YcNL8pZ-Y4wOp{kr^_}OXi zT$cF_?Jct*MO?0%g$gWXXU|McASf&%h(OA~*r8TgW{r?q4x3vA$P75)5Uqu(Y?fJI z@KH=iCXb1y%dBQ1X<*xbZ=!MZK3q*RTyJfyv}=u;fefg+X&|hnY9MFZKv_Y+t(aRaly2OEOud%d2;8OV^k+nGg}xLax$&(H^yLxfZBt^EC`@x1+Y zbO}eJC`})Sqj(AnRC-auu=SUKw2lmdp*)s+hmztrbQa~u3MmK71>}$ zAbf`zrBW`PXodC5N4+<%UQkGGLo;I#RY!CA)&|6#5H-W!06G1z!0NE`=YbrOlYzX} zM4r5Hih(648wY?Q=WL;{H3$&qh)d|$F<#SxWTBy<3O~@`XbGwFu(y(A;a)4$`d(aLRxa0-RWAOAg;_)#17`Y~cwmTXP8} zGsKo2A)WhSQ><|kaTHn`F`i>nZ2rA{8Zmy?8Z`rP#%;quwl8)J#0cO6g2W;Jdb7&A zayX6@48+QZv^C~)-OS*cFL#B0Y>tpjcI9u*5zXn@o6}7m^QEDIWQJ;Yab}B{uQYtu z5XB5w;TSJ!i}~^*a)l<&ORcoz3C$xFiBw_dcv6}(S-j57?!#PO_HxksA+AhqzNwd7O$-aXd%d#gZ(JRdEFpNNSigk{v}1EdUqdqUjo1 zIs7Ls65pCb1zd6W(`IQbBlh4;+DSigZWzJU+|RDp|MhX({e=B${-p%6EB~_c3u$#B I);Ti(0K0#R5dZ)H literal 0 HcmV?d00001 diff --git a/src/main/java/org/matsim/run/DrtOptions.java b/src/main/java/org/matsim/run/DrtOptions.java index 9de6cb7..38fe1e9 100644 --- a/src/main/java/org/matsim/run/DrtOptions.java +++ b/src/main/java/org/matsim/run/DrtOptions.java @@ -4,6 +4,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.geotools.api.feature.simple.SimpleFeature; +import org.geotools.api.feature.simple.SimpleFeatureType; +import org.geotools.feature.simple.SimpleFeatureBuilder; +import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.TransportMode; @@ -24,6 +27,7 @@ import org.matsim.core.utils.gis.GeoFileWriter; import org.matsim.core.utils.io.IOUtils; import org.matsim.pt.config.TransitRouterConfigGroup; +import org.matsim.run.prepare.PrepareDrtScenarioAgents; import org.matsim.run.prepare.PrepareNetwork; import org.matsim.run.prepare.PrepareTransitSchedule; import org.matsim.vehicles.Vehicle; @@ -32,6 +36,10 @@ import org.matsim.vehicles.VehicleUtils; import picocli.CommandLine; +import java.io.File; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -40,6 +48,7 @@ */ public class DrtOptions { private static final Logger log = LogManager.getLogger(DrtOptions.class); + public static final String DRT_DUMMY_ACT_TYPE = "drt-split-trip"; @CommandLine.Option(names = "--drt-shp", description = "Path to shp file for adding drt not network links as an allowed mode.", defaultValue = "./drt-area/nord-bautzen-waiting-times_utm32N.shp") private String drtAreaShp; @@ -65,12 +74,14 @@ public class DrtOptions { @CommandLine.Option(names = "--intermodal", defaultValue = "INTERMODALITY_ACTIVE", description = "enable intermodality for DRT service") private IntermodalityHandling intermodal; + @CommandLine.Option(names = "--manual-trip-conversion", defaultValue = "NOT_CONVERT_TRIPS_MANUALLY", description = "enable manual trip conversion from pt to drt " + + "(for legs with new pt line of LausitzPtScenario).") + private ManualTripConversionHandling manualTripConversion; + /** * a helper method, which makes all necessary config changes to simulate drt. */ public void configureDrtConfig(Config config) { -// check if every feature of shp file has attr typ_wt for drt estimation. Add attr with standard value if not present. - checkServiceAreaShapeFile(config); DvrpConfigGroup dvrpConfigGroup = ConfigUtils.addOrGetModule(config, DvrpConfigGroup.class); dvrpConfigGroup.networkModes = Set.of(TransportMode.drt); @@ -93,6 +104,11 @@ public void configureDrtConfig(Config config) { optimizationConstraintsSet.maxWalkDistance = ConfigUtils.addOrGetModule(config, TransitRouterConfigGroup.class).getSearchRadius(); drtConfigGroup.addParameterSet(optimizationConstraints); drtConfigGroup.addParameterSet(new ExtensiveInsertionSearchParams()); + + // check if every feature of shp file has attr typ_wt for drt estimation. Add attr with standard value if not present +// + set new shp file as drtServiceAreaShapeFile + checkServiceAreaShapeFile(config, drtConfigGroup); + multiModeDrtConfigGroup.addParameterSet(drtConfigGroup); } @@ -144,6 +160,15 @@ public void configureDrtConfig(Config config) { srrConfig.addIntermodalAccessEgress(accessEgressWalkParam); } + + if (manualTripConversion == ManualTripConversionHandling.CONVERT_TRIPS_MANUALLY) { + ScoringConfigGroup.ActivityParams drtDummyScoringParams = new ScoringConfigGroup.ActivityParams(); + drtDummyScoringParams.setTypicalDuration(0.); + drtDummyScoringParams.setActivityType(DRT_DUMMY_ACT_TYPE); + drtDummyScoringParams.setScoringThisActivityAtAll(false); + + scoringConfigGroup.addActivityParams(drtDummyScoringParams); + } } /** @@ -180,31 +205,67 @@ public void configureDrtScenario(Scenario scenario) { drtDummy.getAttributes().putAttribute("serviceEndTime", 86400.); scenario.getVehicles().addVehicle(drtDummy); + } -// tag intermodal pt stops for intermodality between pt and drt - if (intermodal == IntermodalityHandling.INTERMODALITY_ACTIVE) { - PrepareTransitSchedule.tagIntermodalStops(scenario.getTransitSchedule(), new ShpOptions(IOUtils.extendUrl(scenario.getConfig().getContext(), intermodalAreaShp).toString(), null, null)); - } + // tag intermodal pt stops for intermodality between pt and drt + if (intermodal == IntermodalityHandling.INTERMODALITY_ACTIVE) { + PrepareTransitSchedule.tagIntermodalStops(scenario.getTransitSchedule(), new ShpOptions(IOUtils.extendUrl(scenario.getConfig().getContext(), intermodalAreaShp).toString(), null, null)); + } + + if (manualTripConversion == ManualTripConversionHandling.CONVERT_TRIPS_MANUALLY) { + PrepareDrtScenarioAgents.convertVspRegionalTrainLegsToDrt(scenario.getPopulation(), scenario.getNetwork()); } } - private void checkServiceAreaShapeFile(Config config) { - ShpOptions shp = new ShpOptions(getDrtAreaShp(), null, null); + private void checkServiceAreaShapeFile(Config config, DrtConfigGroup drtConfigGroup) { + ShpOptions shp = new ShpOptions(IOUtils.extendUrl(config.getContext(), getDrtAreaShp()).toString(), null, null); List features = shp.readFeatures(); + List newFeatures = new ArrayList<>(); boolean adapted = false; for (SimpleFeature feature : features) { if (feature.getAttribute("typ_wt") == null) { - feature.setAttribute("typ_wt", 10 * 60.); + SimpleFeatureType existingFeatureType = feature.getFeatureType(); + + SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); + builder.init(existingFeatureType); + + builder.add("typ_wt", Double.class); + SimpleFeatureType newFeatureType = builder.buildFeatureType(); + + SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(newFeatureType); + + List existingAttributes = feature.getAttributes(); + featureBuilder.addAll(existingAttributes); + featureBuilder.add(10 * 60.); + + // Step 7: Build the new feature with a unique ID (same geometry, updated attributes) + SimpleFeature newFeature = featureBuilder.buildFeature(feature.getID()); + newFeatures.add(newFeature); adapted = true; + } else { + newFeatures.add(feature); } } if (adapted) { + String newServiceAreaPath; + try { + File file = new File(Path.of(IOUtils.extendUrl(config.getContext(), getDrtAreaShp()).toURI()).getParent().toString(), + Path.of(IOUtils.extendUrl(config.getContext(), getDrtAreaShp()).toURI()).getFileName().toString().split(".shp")[0] + "-with-waiting-time.shp"); + newServiceAreaPath = file.getAbsolutePath(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + + + + log.warn("For drt service area shape file {}, at least one feature did not have the obligatory attribute typ_wt. " + - "The attribute is needed for drt estimation. The attribute was added with a standard value of 10min for those features.", getDrtAreaShp()); + "The attribute is needed for drt estimation. The attribute was added with a standard value of 10min for those features " + + "and saved to file {}.", IOUtils.extendUrl(config.getContext(), getDrtAreaShp()), newServiceAreaPath); - GeoFileWriter.writeGeometries(features, IOUtils.extendUrl(config.getContext(), getDrtAreaShp()).toString()); - log.warn("Adapted drt service area shp file written to {}.", IOUtils.extendUrl(config.getContext(), getDrtAreaShp())); + GeoFileWriter.writeGeometries(newFeatures, newServiceAreaPath); + drtConfigGroup.drtServiceAreaShapeFile = newServiceAreaPath; } } @@ -237,4 +298,9 @@ public double getRideTimeStd() { */ enum IntermodalityHandling {INTERMODALITY_ACTIVE, INTERMODALITY_NOT_ACTIVE} + /** + * Defines if pt legs with new pt regional train from LausitzPtScenario are converted to drt legs manually or not. + */ + enum ManualTripConversionHandling {CONVERT_TRIPS_MANUALLY, NOT_CONVERT_TRIPS_MANUALLY} + } diff --git a/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java b/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java index ff524e9..645b727 100644 --- a/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java +++ b/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java @@ -1,12 +1,9 @@ package org.matsim.run.prepare; -import com.google.common.collect.Lists; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; -import org.locationtech.jts.geom.Geometry; 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.population.*; import org.matsim.application.MATSimAppCommand; @@ -16,10 +13,8 @@ import org.matsim.core.network.NetworkUtils; import org.matsim.core.network.filter.NetworkFilterManager; import org.matsim.core.population.PopulationUtils; -import org.matsim.core.router.AnalysisMainModeIdentifier; -import org.matsim.core.router.DefaultAnalysisMainModeIdentifier; import org.matsim.core.router.TripStructureUtils; -import org.matsim.core.utils.geometry.geotools.MGC; +import org.matsim.run.DrtOptions; import picocli.CommandLine; import java.nio.file.Files; @@ -42,7 +37,6 @@ public class PrepareDrtScenarioAgents implements MATSimAppCommand { @CommandLine.Mixin private final ShpOptions shp = new ShpOptions(); - private static final String PLAN_TYPE = "drtPlan"; private static final String PT_INTERACTION = "pt interaction"; public static void main(String[] args) { @@ -64,7 +58,9 @@ public Integer call() throws Exception { Population population = PopulationUtils.readPopulation(input.toString()); Network network = NetworkUtils.readNetwork(networkPath); -// convertPtToDrtTrips(population, network, shp); + // shp needs to include all locations, where the new pt line (from pt policy case) has a station +// thus, lausitz.shp should be chosen as an input + PrepareNetwork.prepareDrtNetwork(network, shp.getShapeFile()); // TODO: try if for 3 and 5 it is enough to delete act locations instead of searching for nearest drt link convertVspRegionalTrainLegsToDrt(population, network); @@ -74,12 +70,12 @@ public Integer call() throws Exception { return 0; } - private void convertVspRegionalTrainLegsToDrt(Population population, Network network) { -// shp needs to include all locations, where the new pt line (from pt policy case) has a station -// thus, lausitz.shp should be chosen as an input - PrepareNetwork.prepareDrtNetwork(network, shp.getShapeFile()); - - NetworkFilterManager manager = new NetworkFilterManager(network, new NetworkConfigGroup()); + /** + * Method to convert agents, which are using the new vsp pt line (see RunLausitzPtScenario) manually to mode DRT. + * The network needs to be including DRT as an allowed mode. + */ + public static void convertVspRegionalTrainLegsToDrt(Population population, Network networkInclDrt) { + NetworkFilterManager manager = new NetworkFilterManager(networkInclDrt, new NetworkConfigGroup()); manager.addLinkFilter(l -> l.getAllowedModes().contains(TransportMode.drt)); Network filtered = manager.applyFilters(); @@ -121,7 +117,7 @@ private void convertVspRegionalTrainLegsToDrt(Population population, Network net } if (selected.getPlanElements().get(i - 2) instanceof Activity prev) { - convertToDrtInteraction(act, prev, network, filtered); + convertToDrtInteractionAndSplitTrip(act, prev, filtered); } else { logWrongPlanElementType(person, i); throw new IllegalStateException(); @@ -133,6 +129,7 @@ private void convertVspRegionalTrainLegsToDrt(Population population, Network net // pt leg with new pt line leg.setRoute(null); leg.setMode(TransportMode.drt); + leg.setRoutingMode(TransportMode.drt); leg.setTravelTimeUndefined(); leg.setDepartureTimeUndefined(); leg.getAttributes().removeAttribute("enterVehicleTime"); @@ -146,7 +143,7 @@ private void convertVspRegionalTrainLegsToDrt(Population population, Network net throw new IllegalStateException(); } if (selected.getPlanElements().get(i + 2) instanceof Activity next) { - convertToDrtInteraction(act, next, network, filtered); + convertToDrtInteractionAndSplitTrip(act, next, filtered); } else { logWrongPlanElementType(person, i); throw new IllegalStateException(); @@ -174,93 +171,19 @@ private static void logWrongPlanElementType(Person person, int i) { "It seems to be a leg. Abort.", person.getId(), i); } - private static void convertToDrtInteraction(Activity act, Activity previous, Network fullNetwork, Network filtered) { + private static void convertToDrtInteractionAndSplitTrip(Activity act, Activity previous, Network filtered) { // TODO: test if it is enough to delete link and facility, but keep coord. Correct link shoulb be found automatically then - if (filtered.getLinks().containsKey(previous.getLinkId())) { - act.setLinkId(previous.getLinkId()); - } else { - act.setLinkId(NetworkUtils.getNearestLink(filtered, fullNetwork.getLinks().get(previous.getLinkId()).getToNode().getCoord()).getId()); +// The original trip has to be split up because MATSim does not allow trips with 2 different routing modes. +// for the drt subtrip, a dummy act, which is not scored, is created. + if (TripStructureUtils.isStageActivityType(previous.getType())) { + previous.setType(DrtOptions.DRT_DUMMY_ACT_TYPE); + previous.setFacilityId(null); + previous.setLinkId(null); } + act.setLinkId(NetworkUtils.getNearestLink(filtered, previous.getCoord()).getId()); act.setFacilityId(null); act.setCoord(null); act.setType("drt interaction"); } - - /** - * This is implemented as a separate method to be able to use it in a scenario run class. - * Additionally, it can be used to write a new output population by calling this class. - */ - public static void convertPtToDrtTrips(Population population, Network network, ShpOptions shp) { - Geometry serviceArea = shp.getGeometry(); - - AnalysisMainModeIdentifier identifier = new DefaultAnalysisMainModeIdentifier(); - - log.info("Starting to iterate through population."); - - int count = 0; - for (Person person : population.getPersons().values()) { - Plan selected = person.getSelectedPlan(); -// remove all unselected plans - for (Plan plan : Lists.newArrayList(person.getPlans())) { - if (plan != selected) - person.removePlan(plan); - } - - for (TripStructureUtils.Trip trip : TripStructureUtils.getTrips(selected)) { - - String tripMode = identifier.identifyMainMode(trip.getTripElements()); - - if (!tripMode.equals(TransportMode.pt)) { - continue; - } - - boolean startInside = isInside(network.getLinks().get(trip.getLegsOnly().getFirst().getRoute().getStartLinkId()), serviceArea); - boolean endInside = isInside(network.getLinks().get(trip.getLegsOnly().getLast().getRoute().getEndLinkId()), serviceArea); - -// we only need to change the mode for trips within the drt service area. -// All others will be handled by intermodal trips between drt and pt. -// "other" would be ending in service area but not starting and vice versa - if (startInside && endInside) { - int oldIndex = selected.getPlanElements().indexOf(trip.getLegsOnly().stream().filter(l -> l.getMode().equals(TransportMode.pt)).toList().getFirst()); - -// TODO: erst plan kopieren dann converten - int index = convertPtTripToLeg(trip, selected, identifier); - -// copy pt plan and create drt plan. Tag it as drtPlan - Plan drtCopy = person.createCopyOfSelectedPlanAndMakeSelected(); - ((Leg) drtCopy.getPlanElements().get(index)).setMode(TransportMode.drt); - drtCopy.setType(PLAN_TYPE); - count++; - } - } - } - log.info("For {} trips, a copy of the selected plan with a drt trip has been created.", count); - } - - private static int convertPtTripToLeg(TripStructureUtils.Trip trip, Plan selected, AnalysisMainModeIdentifier identifier) { - final List planElements = selected.getPlanElements(); - -// TODO: test if new leg is pasted at correct index. -// TODO: index in this method is always -1. fix this - -// TODO: rather use trips2LegsALgo instead of copy paste - final List fullTrip = - planElements.subList( - planElements.indexOf(trip.getOriginActivity()) + 1, - planElements.indexOf(trip.getDestinationActivity())); - final String mode = identifier.identifyMainMode(fullTrip); - fullTrip.clear(); - Leg leg = PopulationUtils.createLeg(mode); - TripStructureUtils.setRoutingMode(leg, mode); - int index = planElements.indexOf(leg); - fullTrip.add(leg); - if ( fullTrip.size() != 1 ) throw new IllegalArgumentException(fullTrip.toString()); - return index; - } - - private static boolean isInside(Link link, Geometry geometry) { - return MGC.coord2Point(link.getFromNode().getCoord()).within(geometry) || - MGC.coord2Point(link.getToNode().getCoord()).within(geometry); - } } diff --git a/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java b/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java index 61b690a..c8fb8e4 100644 --- a/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java +++ b/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java @@ -22,7 +22,7 @@ class PrepareDrtScenarioAgentsTest { @Test void testPrepareDrtScenarioAgents() { - String inputPopulationPath = "./input/v1.1/lausitz-pt-case-test_experienced_plans_1person.xml.gz"; + String inputPopulationPath = "./input/v1.1/lausitz-pt-case-test_plans_1person.xml.gz"; Population in = PopulationUtils.readPopulation(inputPopulationPath); String networkPath = URL + String.format("lausitz-v%s-network-with-pt.xml.gz", LausitzScenario.VERSION); String outPath = utils.getOutputDirectory() + "/drt-test-population.xml.gz"; From 44f14724655ad063b85684ead7e1de61f83e2896 Mon Sep 17 00:00:00 2001 From: sime94 Date: Thu, 10 Oct 2024 16:59:54 +0200 Subject: [PATCH 31/34] only search for act link if no coord available --- .../run/prepare/PrepareDrtScenarioAgents.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java b/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java index 645b727..72a8daf 100644 --- a/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java +++ b/src/main/java/org/matsim/run/prepare/PrepareDrtScenarioAgents.java @@ -2,7 +2,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.NotNull; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.population.*; @@ -62,7 +61,6 @@ public Integer call() throws Exception { // thus, lausitz.shp should be chosen as an input PrepareNetwork.prepareDrtNetwork(network, shp.getShapeFile()); -// TODO: try if for 3 and 5 it is enough to delete act locations instead of searching for nearest drt link convertVspRegionalTrainLegsToDrt(population, network); PopulationUtils.writePopulation(population, output.toString()); @@ -113,7 +111,6 @@ public static void convertVspRegionalTrainLegsToDrt(Population population, Netwo // interaction act before leg if (!act.getType().equals(PT_INTERACTION)) { logNotPtInteractionAct(person, act, i); - throw new IllegalStateException(); } if (selected.getPlanElements().get(i - 2) instanceof Activity prev) { @@ -140,7 +137,6 @@ public static void convertVspRegionalTrainLegsToDrt(Population population, Netwo // interaction act after leg if (!act.getType().equals(PT_INTERACTION)) { logNotPtInteractionAct(person, act, i); - throw new IllegalStateException(); } if (selected.getPlanElements().get(i + 2) instanceof Activity next) { convertToDrtInteractionAndSplitTrip(act, next, filtered); @@ -154,7 +150,7 @@ public static void convertVspRegionalTrainLegsToDrt(Population population, Netwo } } - public static @NotNull List getNewPtLineIndexes(Plan selected) { + public static List getNewPtLineIndexes(Plan selected) { return TripStructureUtils.getLegs(selected).stream() .filter(l -> l.getRoute().getStartLinkId().toString().contains("pt_vsp_") && l.getRoute().getEndLinkId().toString().contains("pt_vsp_")) @@ -164,6 +160,7 @@ public static void convertVspRegionalTrainLegsToDrt(Population population, Netwo private static void logNotPtInteractionAct(Person person, Activity act, int i) { log.fatal("For selected plan of person {} type {} expected for activity at index {}. Activity has type {} instead. Abort.", person.getId(), PT_INTERACTION, i, act.getType()); + throw new IllegalStateException(); } private static void logWrongPlanElementType(Person person, int i) { @@ -172,8 +169,6 @@ private static void logWrongPlanElementType(Person person, int i) { } private static void convertToDrtInteractionAndSplitTrip(Activity act, Activity previous, Network filtered) { -// TODO: test if it is enough to delete link and facility, but keep coord. Correct link shoulb be found automatically then - // The original trip has to be split up because MATSim does not allow trips with 2 different routing modes. // for the drt subtrip, a dummy act, which is not scored, is created. if (TripStructureUtils.isStageActivityType(previous.getType())) { @@ -181,9 +176,15 @@ private static void convertToDrtInteractionAndSplitTrip(Activity act, Activity p previous.setFacilityId(null); previous.setLinkId(null); } - act.setLinkId(NetworkUtils.getNearestLink(filtered, previous.getCoord()).getId()); + +// only set linkId here, if act has no coord. otherwise the correct link will be found during sim preparation. + if (act.getCoord() == null) { + act.setLinkId(NetworkUtils.getNearestLink(filtered, previous.getCoord()).getId()); + act.setCoord(null); + } else { + act.setLinkId(null); + } act.setFacilityId(null); - act.setCoord(null); act.setType("drt interaction"); } } From 42b5e2dd9d1b5e8d811623181c60537f9c19aa7a Mon Sep 17 00:00:00 2001 From: sime94 Date: Thu, 10 Oct 2024 17:24:25 +0200 Subject: [PATCH 32/34] disable test --- .../matsim/run/prepare/PrepareDrtScenarioAgentsTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java b/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java index c8fb8e4..04a3923 100644 --- a/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java +++ b/src/test/java/org/matsim/run/prepare/PrepareDrtScenarioAgentsTest.java @@ -1,6 +1,7 @@ package org.matsim.run.prepare; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; @@ -20,9 +21,11 @@ class PrepareDrtScenarioAgentsTest { LausitzScenario.VERSION); private static final Id PERSON_ID = Id.createPersonId("642052"); + @Disabled("Test is used to secure functionality of PrepareDrtScenarioAgents. Therefore, " + + "it does not have to run after every commit and it is disabled and only run manually. -sme1024") @Test void testPrepareDrtScenarioAgents() { - String inputPopulationPath = "./input/v1.1/lausitz-pt-case-test_plans_1person.xml.gz"; + String inputPopulationPath = String.format("./input/v%s/lausitz-pt-case-test_plans_1person.xml.gz", LausitzScenario.VERSION); Population in = PopulationUtils.readPopulation(inputPopulationPath); String networkPath = URL + String.format("lausitz-v%s-network-with-pt.xml.gz", LausitzScenario.VERSION); String outPath = utils.getOutputDirectory() + "/drt-test-population.xml.gz"; @@ -48,7 +51,6 @@ void testPrepareDrtScenarioAgents() { // interaction act before leg Assertions.assertInstanceOf(Activity.class, outSelectedPlanElements.get(index - 1)); Activity before = (Activity) outSelectedPlanElements.get(index - 1); - Assertions.assertNull(before.getCoord()); Assertions.assertNull(before.getFacilityId()); Assertions.assertEquals("drt interaction", before.getType()); @@ -61,7 +63,6 @@ void testPrepareDrtScenarioAgents() { // interaction act after leg Assertions.assertInstanceOf(Activity.class, outSelectedPlanElements.get(index + 1)); Activity after = (Activity) outSelectedPlanElements.get(index + 1); - Assertions.assertNull(after.getCoord()); Assertions.assertNull(after.getFacilityId()); Assertions.assertEquals("drt interaction", after.getType()); From 772346080b8076a8bbdb9e1fec660638479baa4d Mon Sep 17 00:00:00 2001 From: sime94 Date: Thu, 10 Oct 2024 17:24:55 +0200 Subject: [PATCH 33/34] put new drt inputs to correct version dir --- .../drt-area/nord-bautzen-waiting-times_utm32N.cpg | 0 .../drt-area/nord-bautzen-waiting-times_utm32N.dbf | Bin .../drt-area/nord-bautzen-waiting-times_utm32N.prj | 0 .../drt-area/nord-bautzen-waiting-times_utm32N.qmd | 0 .../drt-area/nord-bautzen-waiting-times_utm32N.shp | Bin .../drt-area/nord-bautzen-waiting-times_utm32N.shx | Bin .../pt-intermodal-areas-ruhland-spremberg.cpg | 0 .../pt-intermodal-areas-ruhland-spremberg.dbf | Bin .../pt-intermodal-areas-ruhland-spremberg.prj | 0 .../pt-intermodal-areas-ruhland-spremberg.shp | Bin .../pt-intermodal-areas-ruhland-spremberg.shx | Bin .../intermodal-area/pt-intermodal-areas-ruhland.cpg | 0 .../intermodal-area/pt-intermodal-areas-ruhland.dbf | Bin .../intermodal-area/pt-intermodal-areas-ruhland.prj | 0 .../intermodal-area/pt-intermodal-areas-ruhland.shp | Bin .../intermodal-area/pt-intermodal-areas-ruhland.shx | Bin .../lausitz-pt-case-test_plans_1person.xml.gz | Bin 17 files changed, 0 insertions(+), 0 deletions(-) rename input/{v1.1 => v2024.2}/drt-area/nord-bautzen-waiting-times_utm32N.cpg (100%) rename input/{v1.1 => v2024.2}/drt-area/nord-bautzen-waiting-times_utm32N.dbf (100%) rename input/{v1.1 => v2024.2}/drt-area/nord-bautzen-waiting-times_utm32N.prj (100%) rename input/{v1.1 => v2024.2}/drt-area/nord-bautzen-waiting-times_utm32N.qmd (100%) rename input/{v1.1 => v2024.2}/drt-area/nord-bautzen-waiting-times_utm32N.shp (100%) rename input/{v1.1 => v2024.2}/drt-area/nord-bautzen-waiting-times_utm32N.shx (100%) rename input/{v1.1 => v2024.2}/intermodal-area/pt-intermodal-areas-ruhland-spremberg.cpg (100%) rename input/{v1.1 => v2024.2}/intermodal-area/pt-intermodal-areas-ruhland-spremberg.dbf (100%) rename input/{v1.1 => v2024.2}/intermodal-area/pt-intermodal-areas-ruhland-spremberg.prj (100%) rename input/{v1.1 => v2024.2}/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shp (100%) rename input/{v1.1 => v2024.2}/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shx (100%) rename input/{v1.1 => v2024.2}/intermodal-area/pt-intermodal-areas-ruhland.cpg (100%) rename input/{v1.1 => v2024.2}/intermodal-area/pt-intermodal-areas-ruhland.dbf (100%) rename input/{v1.1 => v2024.2}/intermodal-area/pt-intermodal-areas-ruhland.prj (100%) rename input/{v1.1 => v2024.2}/intermodal-area/pt-intermodal-areas-ruhland.shp (100%) rename input/{v1.1 => v2024.2}/intermodal-area/pt-intermodal-areas-ruhland.shx (100%) rename input/{v1.1 => v2024.2}/lausitz-pt-case-test_plans_1person.xml.gz (100%) diff --git a/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.cpg b/input/v2024.2/drt-area/nord-bautzen-waiting-times_utm32N.cpg similarity index 100% rename from input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.cpg rename to input/v2024.2/drt-area/nord-bautzen-waiting-times_utm32N.cpg diff --git a/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.dbf b/input/v2024.2/drt-area/nord-bautzen-waiting-times_utm32N.dbf similarity index 100% rename from input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.dbf rename to input/v2024.2/drt-area/nord-bautzen-waiting-times_utm32N.dbf diff --git a/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.prj b/input/v2024.2/drt-area/nord-bautzen-waiting-times_utm32N.prj similarity index 100% rename from input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.prj rename to input/v2024.2/drt-area/nord-bautzen-waiting-times_utm32N.prj diff --git a/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.qmd b/input/v2024.2/drt-area/nord-bautzen-waiting-times_utm32N.qmd similarity index 100% rename from input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.qmd rename to input/v2024.2/drt-area/nord-bautzen-waiting-times_utm32N.qmd diff --git a/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.shp b/input/v2024.2/drt-area/nord-bautzen-waiting-times_utm32N.shp similarity index 100% rename from input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.shp rename to input/v2024.2/drt-area/nord-bautzen-waiting-times_utm32N.shp diff --git a/input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.shx b/input/v2024.2/drt-area/nord-bautzen-waiting-times_utm32N.shx similarity index 100% rename from input/v1.1/drt-area/nord-bautzen-waiting-times_utm32N.shx rename to input/v2024.2/drt-area/nord-bautzen-waiting-times_utm32N.shx diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.cpg b/input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland-spremberg.cpg similarity index 100% rename from input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.cpg rename to input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland-spremberg.cpg diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.dbf b/input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland-spremberg.dbf similarity index 100% rename from input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.dbf rename to input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland-spremberg.dbf diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.prj b/input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland-spremberg.prj similarity index 100% rename from input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.prj rename to input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland-spremberg.prj diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shp b/input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shp similarity index 100% rename from input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shp rename to input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shp diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shx b/input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shx similarity index 100% rename from input/v1.1/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shx rename to input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland-spremberg.shx diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.cpg b/input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland.cpg similarity index 100% rename from input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.cpg rename to input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland.cpg diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.dbf b/input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland.dbf similarity index 100% rename from input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.dbf rename to input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland.dbf diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.prj b/input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland.prj similarity index 100% rename from input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.prj rename to input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland.prj diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.shp b/input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland.shp similarity index 100% rename from input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.shp rename to input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland.shp diff --git a/input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.shx b/input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland.shx similarity index 100% rename from input/v1.1/intermodal-area/pt-intermodal-areas-ruhland.shx rename to input/v2024.2/intermodal-area/pt-intermodal-areas-ruhland.shx diff --git a/input/v1.1/lausitz-pt-case-test_plans_1person.xml.gz b/input/v2024.2/lausitz-pt-case-test_plans_1person.xml.gz similarity index 100% rename from input/v1.1/lausitz-pt-case-test_plans_1person.xml.gz rename to input/v2024.2/lausitz-pt-case-test_plans_1person.xml.gz From 589925f73d34a428ec3afa59d08775c877d16207 Mon Sep 17 00:00:00 2001 From: sime94 Date: Thu, 10 Oct 2024 17:35:43 +0200 Subject: [PATCH 34/34] checkstyle --- src/main/java/org/matsim/run/DrtOptions.java | 2 +- src/test/java/org/matsim/run/RunIntegrationTest.java | 12 +++--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/matsim/run/DrtOptions.java b/src/main/java/org/matsim/run/DrtOptions.java index 38fe1e9..749b6f0 100644 --- a/src/main/java/org/matsim/run/DrtOptions.java +++ b/src/main/java/org/matsim/run/DrtOptions.java @@ -254,7 +254,7 @@ private void checkServiceAreaShapeFile(Config config, DrtConfigGroup drtConfigGr Path.of(IOUtils.extendUrl(config.getContext(), getDrtAreaShp()).toURI()).getFileName().toString().split(".shp")[0] + "-with-waiting-time.shp"); newServiceAreaPath = file.getAbsolutePath(); } catch (URISyntaxException e) { - throw new RuntimeException(e); + throw new IllegalArgumentException("Error handling the Drt service area shapefile URI.", e); } diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java index 6158007..d3a0b0b 100644 --- a/src/test/java/org/matsim/run/RunIntegrationTest.java +++ b/src/test/java/org/matsim/run/RunIntegrationTest.java @@ -80,14 +80,12 @@ void runScenarioIncludingDrt() { Config config = ConfigUtils.loadConfig(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION)); ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class).defaultDashboards = SimWrapperConfigGroup.Mode.disabled; - Path inputPath = p.resolve("drt-test-population.xml.gz"); - createDrtTestPopulation(inputPath); assert MATSimApplication.execute(LausitzDrtScenario.class, config, "--1pct", "--iterations", "0", - "--config:plans.inputPlansFile", inputPath.toString(), + "--config:plans.inputPlansFile", inputPath, "--output", utils.getOutputDirectory(), "--config:controller.overwriteFiles=deleteDirectoryIfExists", "--emissions", "DO_NOT_PERFORM_EMISSIONS_ANALYSIS") == 0 : "Must return non error code"; @@ -140,7 +138,7 @@ void runScenarioIncludingAdditionalPtLine() { } - private void createDrtTestPopulation(Path inputPath) { + private void createDrtTestPopulation(String inputPath) { Random random = new Random(1); Config config = ConfigUtils.createConfig(); Scenario scenario = ScenarioUtils.loadScenario(config); @@ -153,16 +151,12 @@ private void createDrtTestPopulation(Path inputPath) { Plan plan = populationFactory.createPlan(); // a random location in the Hoyerswerda town center Activity fromAct = populationFactory.createActivityFromCoord("home_2400", new Coord(863949.91, 5711547.75)); - // Somewhere near Ruhland Hbf -// Activity fromAct = populationFactory.createActivityFromCoord("home_2400", new Coord(838213.25, 5711776.54)); // a random time between 6:00-9:00 fromAct.setEndTime(21600 + random.nextInt(10800)); // set the link to PT, such that agent could find a potential intermodal trip Leg leg = populationFactory.createLeg(TransportMode.pt); // a location close to Cottbus Hbf Activity toAct = populationFactory.createActivityFromCoord("work_2400", new Coord(867341.75, 5746965.87)); -// somewhere near ruhland hbf -// Activity toAct = populationFactory.createActivityFromCoord("work_2400", new Coord(838646.6900000001, 5711749.89)); plan.addActivity(fromAct); plan.addLeg(leg); @@ -191,7 +185,7 @@ private void createDrtTestPopulation(Path inputPath) { population.addPerson(drtOnly); - new PopulationWriter(population).write(inputPath.toString()); + new PopulationWriter(population).write(inputPath); } @Test void runSpeedReductionScenario() {