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
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