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