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;
+ }
+}