From 7b367bba9f3d505266f819d0daa50849bb638bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Fri, 27 Mar 2026 08:32:26 +0100 Subject: [PATCH 1/3] feat: extend schedule by hours and days --- .../core/tools/schedule/ExtendSchedule.java | 25 +++++++++++------ .../tools/schedule/RunExtendSchedule.java | 27 +++++++++++++++++-- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/tools/schedule/ExtendSchedule.java b/core/src/main/java/org/eqasim/core/tools/schedule/ExtendSchedule.java index f8eb2838d..f338fcd08 100644 --- a/core/src/main/java/org/eqasim/core/tools/schedule/ExtendSchedule.java +++ b/core/src/main/java/org/eqasim/core/tools/schedule/ExtendSchedule.java @@ -11,13 +11,16 @@ import org.matsim.pt.transitSchedule.api.TransitScheduleFactory; public class ExtendSchedule { - private final static String DEPATURE_PREFIX = "extension:"; - private final static double OFFSET = 24.0 * 3600.0; + private final static double H24 = 24 * 3600.0; - private final double time; + private final double endTime; - public ExtendSchedule(double time) { - this.time = time; + public ExtendSchedule(double endTime) { + this.endTime = endTime; + } + + private Id prefix(Id baseId, int extension) { + return Id.create(baseId.toString() + ":ext:" + extension, Departure.class); } public void process(TransitSchedule schedule) { @@ -28,13 +31,19 @@ public void process(TransitSchedule schedule) { List extensions = new LinkedList<>(); for (Departure departure : transitRoute.getDepartures().values()) { - if (departure.getDepartureTime() <= time) { + double updatedDepartureTime = departure.getDepartureTime() + H24; + int extensionIndex = 1; + + while (updatedDepartureTime <= endTime) { Departure extension = factory.createDeparture( // - Id.create(DEPATURE_PREFIX + departure.getId().toString(), Departure.class), // - departure.getDepartureTime() + OFFSET); + prefix(departure.getId(), extensionIndex), // + updatedDepartureTime); extension.setVehicleId(departure.getVehicleId()); extensions.add(extension); + + extensionIndex++; + updatedDepartureTime += H24; } } diff --git a/core/src/main/java/org/eqasim/core/tools/schedule/RunExtendSchedule.java b/core/src/main/java/org/eqasim/core/tools/schedule/RunExtendSchedule.java index 8b94d5c85..e2f8612de 100644 --- a/core/src/main/java/org/eqasim/core/tools/schedule/RunExtendSchedule.java +++ b/core/src/main/java/org/eqasim/core/tools/schedule/RunExtendSchedule.java @@ -12,13 +12,36 @@ public class RunExtendSchedule { static public void main(String[] args) throws ConfigurationException { CommandLine cmd = new CommandLine.Builder(args) // - .requireOptions("schedule-path", "output-path", "period") // + .requireOptions("schedule-path", "output-path") // + .allowOptions("end-time", "hours", "days") // .build(); + boolean endTimeAvailable = cmd.hasOption("end-time"); + boolean hoursAvailable = cmd.hasOption("hours"); + boolean daysAvailable = cmd.hasOption("days"); + + if (!(endTimeAvailable ^ (hoursAvailable || daysAvailable))) { + throw new IllegalStateException( + "Either --end-time (in seconds), or --hours / --days (can be combined) need to be provided."); + } + + double endTime = 0.0; + if (endTimeAvailable) { + endTime = Double.parseDouble(cmd.getOptionStrict("end-time")); + } else { + if (hoursAvailable) { + endTime += 3600.0 * Double.parseDouble(cmd.getOptionStrict("hours")); + } + + if (daysAvailable) { + endTime += 24.0 * 3600.0 * Double.parseDouble(cmd.getOptionStrict("hours")); + } + } + Config config = ConfigUtils.createConfig(); Scenario scenario = ScenarioUtils.createScenario(config); new TransitScheduleReader(scenario).readFile(cmd.getOptionStrict("schedule-path")); - new ExtendSchedule(Double.parseDouble(cmd.getOptionStrict("period"))).process(scenario.getTransitSchedule()); + new ExtendSchedule(endTime).process(scenario.getTransitSchedule()); new TransitScheduleWriter(scenario.getTransitSchedule()).writeFile(cmd.getOptionStrict("output-path")); } } \ No newline at end of file From aba400a7a91183b391f29968802cab84c519673c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Fri, 27 Mar 2026 15:40:56 +0100 Subject: [PATCH 2/3] take into account vehicles --- .../core/tools/schedule/ExtendSchedule.java | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/tools/schedule/ExtendSchedule.java b/core/src/main/java/org/eqasim/core/tools/schedule/ExtendSchedule.java index f338fcd08..7f980fba3 100644 --- a/core/src/main/java/org/eqasim/core/tools/schedule/ExtendSchedule.java +++ b/core/src/main/java/org/eqasim/core/tools/schedule/ExtendSchedule.java @@ -9,6 +9,9 @@ import org.matsim.pt.transitSchedule.api.TransitRoute; import org.matsim.pt.transitSchedule.api.TransitSchedule; import org.matsim.pt.transitSchedule.api.TransitScheduleFactory; +import org.matsim.vehicles.Vehicle; +import org.matsim.vehicles.Vehicles; +import org.matsim.vehicles.VehiclesFactory; public class ExtendSchedule { private final static double H24 = 24 * 3600.0; @@ -19,35 +22,48 @@ public ExtendSchedule(double endTime) { this.endTime = endTime; } - private Id prefix(Id baseId, int extension) { + private Id prefixDeparture(Id baseId, int extension) { return Id.create(baseId.toString() + ":ext:" + extension, Departure.class); } - public void process(TransitSchedule schedule) { - TransitScheduleFactory factory = schedule.getFactory(); + private Id prefixVehicle(Id baseId, int extension) { + return Id.create(baseId.toString() + ":ext:" + extension, Vehicle.class); + } + + public void process(TransitSchedule schedule, Vehicles vehicles) { + TransitScheduleFactory scheduleFactory = schedule.getFactory(); + VehiclesFactory vehiclesFactory = vehicles.getFactory(); for (TransitLine transitLine : schedule.getTransitLines().values()) { for (TransitRoute transitRoute : transitLine.getRoutes().values()) { - List extensions = new LinkedList<>(); + List addedDepartures = new LinkedList<>(); for (Departure departure : transitRoute.getDepartures().values()) { double updatedDepartureTime = departure.getDepartureTime() + H24; int extensionIndex = 1; while (updatedDepartureTime <= endTime) { - Departure extension = factory.createDeparture( // - prefix(departure.getId(), extensionIndex), // + Departure updatedDeparture = scheduleFactory.createDeparture( // + prefixDeparture(departure.getId(), extensionIndex), // updatedDepartureTime); + addedDepartures.add(updatedDeparture); + + Vehicle vehicle = vehicles.getVehicles().get(departure.getVehicleId()); + + Id updatedVehicleId = prefixVehicle(vehicle.getId(), extensionIndex); + updatedDeparture.setVehicleId(updatedVehicleId); - extension.setVehicleId(departure.getVehicleId()); - extensions.add(extension); + if (!vehicles.getVehicles().containsKey(updatedVehicleId)) { + Vehicle updatedVehicle = vehiclesFactory.createVehicle(updatedVehicleId, vehicle.getType()); + vehicles.addVehicle(updatedVehicle); + } extensionIndex++; updatedDepartureTime += H24; } } - for (Departure extension : extensions) { + for (Departure extension : addedDepartures) { transitRoute.addDeparture(extension); } } From 689321d7a54f0b4b3297559166552b27efdb3118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Fri, 27 Mar 2026 15:43:08 +0100 Subject: [PATCH 3/3] fix --- .../core/tools/schedule/RunExtendSchedule.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/tools/schedule/RunExtendSchedule.java b/core/src/main/java/org/eqasim/core/tools/schedule/RunExtendSchedule.java index e2f8612de..380ae2009 100644 --- a/core/src/main/java/org/eqasim/core/tools/schedule/RunExtendSchedule.java +++ b/core/src/main/java/org/eqasim/core/tools/schedule/RunExtendSchedule.java @@ -8,11 +8,14 @@ import org.matsim.core.scenario.ScenarioUtils; import org.matsim.pt.transitSchedule.api.TransitScheduleReader; import org.matsim.pt.transitSchedule.api.TransitScheduleWriter; +import org.matsim.vehicles.MatsimVehicleReader; +import org.matsim.vehicles.MatsimVehicleWriter; public class RunExtendSchedule { static public void main(String[] args) throws ConfigurationException { CommandLine cmd = new CommandLine.Builder(args) // - .requireOptions("schedule-path", "output-path") // + .requireOptions("input-schedule-path", "output-schedule-path", "input-vehicles-path", + "output-vehicles-path") // .allowOptions("end-time", "hours", "days") // .build(); @@ -40,8 +43,13 @@ static public void main(String[] args) throws ConfigurationException { Config config = ConfigUtils.createConfig(); Scenario scenario = ScenarioUtils.createScenario(config); - new TransitScheduleReader(scenario).readFile(cmd.getOptionStrict("schedule-path")); - new ExtendSchedule(endTime).process(scenario.getTransitSchedule()); - new TransitScheduleWriter(scenario.getTransitSchedule()).writeFile(cmd.getOptionStrict("output-path")); + + new TransitScheduleReader(scenario).readFile(cmd.getOptionStrict("input-schedule-path")); + new MatsimVehicleReader(scenario.getTransitVehicles()).readFile(cmd.getOptionStrict("input-vehicles-path")); + + new ExtendSchedule(endTime).process(scenario.getTransitSchedule(), scenario.getTransitVehicles()); + + new TransitScheduleWriter(scenario.getTransitSchedule()).writeFile(cmd.getOptionStrict("output-schedule-path")); + new MatsimVehicleWriter(scenario.getTransitVehicles()).writeFile(cmd.getOptionStrict("output-vehicles-path")); } } \ No newline at end of file