diff --git a/pom.xml b/pom.xml
index 8dd724e..64101f4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
matsim-all
- 2025.0-PR3271
+ 2025.0-PR3328
diff --git a/src/main/java/org/matsim/analysis/postAnalysis/drt/DrtPostProcessingAverageAnalysis.java b/src/main/java/org/matsim/analysis/postAnalysis/drt/DrtPostProcessingAverageAnalysis.java
index 035d0c2..fa2a8cb 100644
--- a/src/main/java/org/matsim/analysis/postAnalysis/drt/DrtPostProcessingAverageAnalysis.java
+++ b/src/main/java/org/matsim/analysis/postAnalysis/drt/DrtPostProcessingAverageAnalysis.java
@@ -17,6 +17,8 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
import java.time.LocalTime;
import java.util.*;
@@ -25,11 +27,7 @@
@CommandLine.Command(name = "average-drt", description = "Calculates average drt stats based on several sim runs with different random seeds.")
@CommandSpec(
requires = {"runs", "mode"},
- produces = {"rides_per_veh_avg_demand_stats.csv", "avg_wait_time_avg_demand_stats.csv", "requests_avg_demand_stats.csv", "avg_total_travel_time_avg_demand_stats.csv",
- "rides_avg_demand_stats.csv", "avg_direct_distance_[km]_avg_demand_stats.csv", "rejections_avg_demand_stats.csv", "95th_percentile_wait_time_avg_demand_stats.csv",
- "avg_in-vehicle_time_avg_demand_stats.csv", "avg_ride_distance_[km]_avg_demand_stats.csv", "rejection_rate_avg_demand_stats.csv",
- "avg_fare_[MoneyUnit]_avg_demand_stats.csv", "total_service_hours_avg_supply_stats.csv", "pooling_ratio_avg_supply_stats.csv", "detour_ratio_avg_supply_stats.csv",
- "total_vehicle_mileage_[km]_avg_supply_stats.csv", "empty_ratio_avg_supply_stats.csv", "number_of_stops_avg_supply_stats.csv", "total_pax_distance_[km]_avg_supply_stats.csv", "vehicles_avg_supply_stats.csv"}
+ produces = {"avg_demand_stats.csv", "avg_supply_stats.csv"}
)
public class DrtPostProcessingAverageAnalysis implements MATSimAppCommand {
@@ -44,7 +42,6 @@ public class DrtPostProcessingAverageAnalysis implements MATSimAppCommand {
private final Map> supplyStats = new HashMap<>();
private final Map demandAvgs = new HashMap<>();
private final Map supplyAvgs = new HashMap<>();
- Map> params = new HashMap<>();
private final CsvOptions csv = new CsvOptions();
@@ -70,11 +67,11 @@ public Integer call() throws Exception {
Table demand = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(demandKpiCsv))
.sample(false)
- .separator(csv.detectDelimiter(demandKpiCsv)).build());
+ .separator(CsvOptions.detectDelimiter(demandKpiCsv)).build());
Table supply = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(supplyKpiCsv))
.sample(false)
- .separator(csv.detectDelimiter(supplyKpiCsv)).build());
+ .separator(CsvOptions.detectDelimiter(supplyKpiCsv)).build());
// get all demand stats
for (int i = 0; i < demand.rowCount(); i++) {
@@ -113,38 +110,30 @@ public Integer call() throws Exception {
fillAvgMap(demandStats, demandAvgs);
fillAvgMap(supplyStats, supplyAvgs);
- params.put("avg_demand_stats.csv", List.of("rides_per_veh", "avg_wait_time", "requests", "avg_total_travel_time", "rides", "avg_direct_distance_[km]",
- "rejections", "95th_percentile_wait_time", "avg_in-vehicle_time", "avg_ride_distance_[km]", "rejection_rate", "avg_fare_[MoneyUnit]"));
- params.put("avg_supply_stats.csv", List.of("total_service_hours", "pooling_ratio", "detour_ratio", "total_vehicle_mileage_[km]", "empty_ratio", "number_of_stops",
- "total_pax_distance_[km]", "vehicles"));
+// ordered list of params to display them in same order as in single-run DrtDashboard
+ List orderedDemandParams = List.of("Handled Requests", "Passengers (Pax)", "Avg Group Size", "Pax per veh", "Pax per veh-h", "Pax per veh-km",
+ "Rejections", "Rejection rate", "Avg. total travel time", "Avg. in-vehicle time", "Avg. wait time", "95th percentile wait time", "Avg. ride distance [km]",
+ "Avg. direct distance [km]", "Avg. fare [MoneyUnit]");
+ List orderedSupplyParams = List.of("Number of stops", "Vehicles", "Total vehicle mileage [km]", "Empty ratio", "Total pax distance [km]",
+ "Occupancy rate [pax-km/v-km]", "Detour ratio", "Total service hours");
- for (Map.Entry> e : params.entrySet()) {
- for (String param : params.get(e.getKey())) {
- if (e.getKey().contains("demand")) {
- writeFile(e.getKey(), demandAvgs, param);
- } else {
- writeFile(e.getKey(), supplyAvgs, param);
- }
- }
- }
+ writeFile("avg_demand_stats.csv", demandAvgs, orderedDemandParams);
+ writeFile("avg_supply_stats.csv", supplyAvgs, orderedSupplyParams);
return 0;
}
- private void writeFile(String fileName, Map values, String param) throws IOException {
- try (CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(output.getPath(param + "_" + fileName)), CSVFormat.DEFAULT)) {
+ private void writeFile(String fileName, Map values, List orderedParams) throws IOException {
+ try (CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(output.getPath(fileName)), CSVFormat.DEFAULT)) {
+ DecimalFormat df = new DecimalFormat("#,###.##", new DecimalFormatSymbols(Locale.US));
- printer.printRecord("info", value);
+// as of 19.06.24 min and max values are not printed anymore. they will still be calculated though.
+// if one wants to include them to dashboard tables one just has to re-include them in this print method. -sme0624
+ printer.printRecord("parameter", "mean", "median", "standard deviation");
- for (Map.Entry e : values.entrySet()) {
- String transformed = e.getKey().toLowerCase().replace(".", "").replace(" ", "_");
- if (transformed.contains(param)) {
- printer.printRecord("mean-" + e.getKey(), e.getValue()[0]);
- printer.printRecord("median-" + e.getKey(), e.getValue()[1]);
- printer.printRecord("sd-" + e.getKey(), e.getValue()[2]);
- printer.printRecord("min-" + e.getKey(), e.getValue()[3]);
- printer.printRecord("max-" + e.getKey(), e.getValue()[4]);
- }
+
+ for (String param : orderedParams) {
+ printer.printRecord(param, df.format(values.get(param)[0]), df.format(values.get(param)[1]), df.format(values.get(param)[2]));
}
}
}
diff --git a/src/main/java/org/matsim/analysis/postAnalysis/drt/DrtServiceQualityAnalysis.java b/src/main/java/org/matsim/analysis/postAnalysis/drt/DrtServiceQualityAnalysis.java
index b1027c2..6391f16 100644
--- a/src/main/java/org/matsim/analysis/postAnalysis/drt/DrtServiceQualityAnalysis.java
+++ b/src/main/java/org/matsim/analysis/postAnalysis/drt/DrtServiceQualityAnalysis.java
@@ -8,6 +8,7 @@
import org.apache.commons.math3.util.Precision;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.geotools.api.feature.simple.SimpleFeature;
import org.locationtech.jts.geom.Geometry;
import org.matsim.analysis.postAnalysis.traffic.TrafficAnalysis;
import org.matsim.api.core.v01.Coord;
@@ -35,7 +36,6 @@
import org.matsim.vehicles.Vehicle;
import org.matsim.vehicles.VehicleType;
import org.matsim.vehicles.VehicleUtils;
-import org.opengis.feature.simple.SimpleFeature;
import picocli.CommandLine;
import java.io.FileWriter;
diff --git a/src/main/java/org/matsim/dashboard/AverageDrtDashboard.java b/src/main/java/org/matsim/dashboard/AverageDrtDashboard.java
index 82ed8fd..cb467c2 100644
--- a/src/main/java/org/matsim/dashboard/AverageDrtDashboard.java
+++ b/src/main/java/org/matsim/dashboard/AverageDrtDashboard.java
@@ -39,142 +39,20 @@ public void configure(Header header, Layout layout) {
header.description = "Overview for the demand-responsive mode '" + mode + "'. This dashboard shows average values for " + noRuns +
" simulation runs. For the results of the specific runs please choose the according directory next to this dashboard.yaml.";
-// DEMAND
- layout.row("one")
- .el(Table.class, (viz, data) -> {
- viz.title = "Rides per vehicle";
- viz.dataset = postProcess(data, "rides_per_veh_avg_demand_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- })
- .el(Table.class, (viz, data) -> {
- viz.title = "Avg wait time";
- viz.dataset = postProcess(data, "avg_wait_time_avg_demand_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- })
- .el(Table.class, (viz, data) -> {
- viz.title = "Requests";
- viz.dataset = postProcess(data, "requests_avg_demand_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- });
-
- layout.row("two")
- .el(Table.class, (viz, data) -> {
- viz.title = "Avg total travel time";
- viz.dataset = postProcess(data, "avg_total_travel_time_avg_demand_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- })
- .el(Table.class, (viz, data) -> {
- viz.title = "Rides";
- viz.dataset = postProcess(data, "rides_avg_demand_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- })
- .el(Table.class, (viz, data) -> {
- viz.title = "Avg direct distance [km]";
- viz.dataset = postProcess(data, "avg_direct_distance_[km]_avg_demand_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- });
-
- layout.row("three")
- .el(Table.class, (viz, data) -> {
- viz.title = "Rejections";
- viz.dataset = postProcess(data, "rejections_avg_demand_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- })
- .el(Table.class, (viz, data) -> {
- viz.title = "95th percentile wait time";
- viz.dataset = postProcess(data, "95th_percentile_wait_time_avg_demand_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- })
- .el(Table.class, (viz, data) -> {
- viz.title = "Avg in-vehicle time";
- viz.dataset = postProcess(data, "avg_in-vehicle_time_avg_demand_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- });
-
- layout.row("four")
- .el(Table.class, (viz, data) -> {
- viz.title = "Avg ride distance [km]";
- viz.dataset = postProcess(data, "avg_ride_distance_[km]_avg_demand_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- })
- .el(Table.class, (viz, data) -> {
- viz.title = "Rejection rate";
- viz.dataset = postProcess(data, "rejection_rate_avg_demand_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- })
- .el(Table.class, (viz, data) -> {
- viz.title = "Avg fare [MoneyUnit]";
- viz.dataset = postProcess(data, "avg_fare_[MoneyUnit]_avg_demand_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- });
-
// SUPPLY
- supplyTabs(layout);
- }
-
- private void supplyTabs(Layout layout) {
- layout.row("six")
+ layout.row("supply")
.el(Table.class, (viz, data) -> {
- viz.title = "Total service hours";
- viz.dataset = postProcess(data, "total_service_hours_avg_supply_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- })
- .el(Table.class, (viz, data) -> {
- viz.title = "Pooling ratio";
- viz.dataset = postProcess(data, "pooling_ratio_avg_supply_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- })
- .el(Table.class, (viz, data) -> {
- viz.title = "Detour ratio";
- viz.dataset = postProcess(data, "detour_ratio_avg_supply_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- });
-
- layout.row("seven")
- .el(Table.class, (viz, data) -> {
- viz.title = "Total vehicle mileage [km]";
- viz.dataset = postProcess(data, "total_vehicle_mileage_[km]_avg_supply_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- })
- .el(Table.class, (viz, data) -> {
- viz.title = "Empty ratio";
- viz.dataset = postProcess(data, "empty_ratio_avg_supply_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- })
- .el(Table.class, (viz, data) -> {
- viz.title = "Number of stops";
- viz.dataset = postProcess(data, "number_of_stops_avg_supply_stats.csv");
+ viz.title = "Service summary";
+ viz.dataset = postProcess(data, "avg_supply_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
});
- layout.row("eight")
- .el(Table.class, (viz, data) -> {
- viz.title = "Total pax distance [km]";
- viz.dataset = postProcess(data, "total_pax_distance_[km]_avg_supply_stats.csv");
- viz.showAllRows = true;
- viz.width = 1.;
- })
+ // DEMAND
+ layout.row("demand")
.el(Table.class, (viz, data) -> {
- viz.title = "Vehicles";
- viz.dataset = postProcess(data, "vehicles_avg_supply_stats.csv");
+ viz.title = "Demand summary";
+ viz.dataset = postProcess(data, "avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
});
diff --git a/src/main/java/org/matsim/dashboard/CreateAverageDashboards.java b/src/main/java/org/matsim/dashboard/CreateAverageDashboards.java
index d4c1f9e..cc0dd7f 100644
--- a/src/main/java/org/matsim/dashboard/CreateAverageDashboards.java
+++ b/src/main/java/org/matsim/dashboard/CreateAverageDashboards.java
@@ -19,7 +19,7 @@
/**
* class to create average dashboards and run the necessary analysis for that.
*/
-public class CreateAverageDashboards implements MATSimAppCommand {
+final class CreateAverageDashboards implements MATSimAppCommand {
@CommandLine.Option(names = "--input-path", required = true, description = "Path to directory with run directories.")
private String inputPath;
@CommandLine.Option(names = "--no-runs", defaultValue = "5", description = "Number of simulation runs to be averaged.")
@@ -62,7 +62,7 @@ public Integer call() throws Exception {
Arrays.stream(new File(analysisDir).listFiles())
.filter(d -> d.getAbsolutePath().contains(TransportMode.drt))
- .forEach(f -> modes.add(f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf("\\") + 1)));
+ .forEach(f -> modes.add(f.getName()));
SimWrapper sw = SimWrapper.create();
diff --git a/src/main/java/org/matsim/dashboard/KelheimDashboardProvider.java b/src/main/java/org/matsim/dashboard/KelheimDashboardProvider.java
index 19a478d..17a1a6c 100644
--- a/src/main/java/org/matsim/dashboard/KelheimDashboardProvider.java
+++ b/src/main/java/org/matsim/dashboard/KelheimDashboardProvider.java
@@ -6,7 +6,6 @@
import org.matsim.simwrapper.Dashboard;
import org.matsim.simwrapper.DashboardProvider;
import org.matsim.simwrapper.SimWrapper;
-import org.matsim.simwrapper.dashboard.NoiseDashboard;
import org.matsim.simwrapper.dashboard.TravelTimeComparisonDashboard;
import org.matsim.simwrapper.dashboard.TripDashboard;
@@ -27,8 +26,9 @@ public List getDashboards(Config config, SimWrapper simWrapper) {
return List.of(
trips,
new TravelTimeComparisonDashboard(IOUtils.resolveFileOrResource( "kelheim-v3.0-routes-ref.csv.gz").toString()),
- new KelheimEmissionsDashboard(),
- new NoiseDashboard()
+ new KelheimEmissionsDashboard()
+ //the NoiseAnalysis needs more RAM than the entire simulation, which leads to VM crashes and prevents other analysis to run. We have to run it separately (e.g. with KelheimSimWrapperRunner)
+// new NoiseDashboard()
);
}
diff --git a/src/main/java/org/matsim/analysis/CreateEmissionDashboard.java b/src/main/java/org/matsim/dashboard/KelheimSimWrapperRunner.java
similarity index 68%
rename from src/main/java/org/matsim/analysis/CreateEmissionDashboard.java
rename to src/main/java/org/matsim/dashboard/KelheimSimWrapperRunner.java
index 6ea2e79..e6fdc07 100644
--- a/src/main/java/org/matsim/analysis/CreateEmissionDashboard.java
+++ b/src/main/java/org/matsim/dashboard/KelheimSimWrapperRunner.java
@@ -18,7 +18,7 @@
* *
* *********************************************************************** */
-package org.matsim.analysis;
+package org.matsim.dashboard;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -26,24 +26,25 @@
import org.matsim.application.ApplicationUtils;
import org.matsim.application.MATSimAppCommand;
import org.matsim.application.options.ShpOptions;
+import org.matsim.contrib.drt.extension.dashboards.DrtDashboardProvider;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.simwrapper.SimWrapper;
import org.matsim.simwrapper.SimWrapperConfigGroup;
+import org.matsim.simwrapper.dashboard.NoiseDashboard;
import picocli.CommandLine;
-import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
@CommandLine.Command(
- name = "emissions",
+ name = "simwrapper",
description = "Run emission analysis and create SimWrapper dashboard for existing run output."
)
-final class CreateEmissionDashboard implements MATSimAppCommand {
+final class KelheimSimWrapperRunner implements MATSimAppCommand {
- private static final Logger log = LogManager.getLogger(CreateEmissionDashboard.class);
+ private static final Logger log = LogManager.getLogger(KelheimSimWrapperRunner.class);
@CommandLine.Parameters(arity = "1..*", description = "Path to run output directories for which emission dashboards are to be generated.")
private List inputPaths;
@@ -53,15 +54,29 @@ final class CreateEmissionDashboard implements MATSimAppCommand {
@CommandLine.Option(names = "--base", description = "Optional. " +
"Relative path (from each! output directory provided) to main output folder for the base MATSim run. " +
- "Will be used to compare emissions per link.", required = false)
+ "Will be used to compare emissions per link.")
private String baseRun;
- private CreateEmissionDashboard(){
+ @CommandLine.Option(names = "--emissions", defaultValue = "false", description = "create emissions dashboard")
+ private boolean emissions;
+
+ @CommandLine.Option(names = "--noise", defaultValue = "false", description = "create noise dashboard")
+ private boolean noise;
+
+ @CommandLine.Option(names = "--drt", defaultValue = "false", description = "create DRT + AV dashboards")
+ private boolean drt;
+
+
+ private KelheimSimWrapperRunner(){
}
@Override
public Integer call() throws Exception {
+ if (!drt && !emissions && !noise){
+ throw new IllegalArgumentException("you have not configured any dashboard to be created! Use command line parameters!");
+ }
+
for (Path runDirectory : inputPaths) {
log.info("Running on {}", runDirectory);
@@ -81,10 +96,19 @@ public Integer call() throws Exception {
simwrapperCfg.defaultDashboards = SimWrapperConfigGroup.Mode.disabled;
simwrapperCfg.defaultParams().mapCenter = "48.91265,11.89223";
- if (baseRun != null){
- sw.addDashboard(new KelheimEmissionsDashboard(baseRun));
- } else {
- sw.addDashboard(new KelheimEmissionsDashboard());
+ //add dashboards according to command line parameters
+ if (emissions){
+ if (baseRun != null){
+ sw.addDashboard(new KelheimEmissionsDashboard(baseRun));
+ } else {
+ sw.addDashboard(new KelheimEmissionsDashboard());
+ }
+ }
+ if (drt){
+ new DrtDashboardProvider().getDashboards(config, sw).forEach(sw::addDashboard);
+ }
+ if (noise){
+ sw.addDashboard(new NoiseDashboard());
}
try {
@@ -99,45 +123,8 @@ public Integer call() throws Exception {
}
public static void main(String[] args) {
- new CreateEmissionDashboard().execute(args);
+ new KelheimSimWrapperRunner().execute(args);
}
- private static void renameExistingDashboardYAMLs(Path runDirectory) {
- // List of files in the folder
- File folder = new File(runDirectory.toString());
- File[] files = folder.listFiles();
-
- // Loop through all files in the folder
- if (files != null) {
- for (File file : files) {
- if (file.isFile()) {
- // Check if the file name starts with "dashboard-" and ends with ".yaml"
- if (file.getName().startsWith("dashboard-") && file.getName().endsWith(".yaml")) {
- // Get the current file name
- String oldName = file.getName();
-
- // Extract the number from the file name
- String numberPart = oldName.substring(oldName.indexOf('-') + 1, oldName.lastIndexOf('.'));
-
- // Increment the number by ten
- int number = Integer.parseInt(numberPart) + 10;
-
- // Create the new file name
- String newName = "dashboard-" + number + ".yaml";
-
- // Create the new File object with the new file name
- File newFile = new File(file.getParent(), newName);
-
- // Rename the file
- if (file.renameTo(newFile)) {
- log.info("File successfully renamed: " + newName);
- } else {
- log.info("Error renaming file: " + file.getName());
- }
- }
- }
- }
- }
- }
}
diff --git a/src/main/java/org/matsim/drtFare/KelheimDrtFareHandler.java b/src/main/java/org/matsim/drtFare/KelheimDrtFareHandler.java
index d689c1d..25ce692 100644
--- a/src/main/java/org/matsim/drtFare/KelheimDrtFareHandler.java
+++ b/src/main/java/org/matsim/drtFare/KelheimDrtFareHandler.java
@@ -3,6 +3,7 @@
import com.google.inject.Inject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.geotools.api.feature.simple.SimpleFeature;
import org.locationtech.jts.geom.Geometry;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.PersonMoneyEvent;
@@ -19,7 +20,6 @@
import org.matsim.core.api.experimental.events.EventsManager;
import org.matsim.core.utils.geometry.geotools.MGC;
import org.matsim.core.utils.gis.GeoFileReader;
-import org.opengis.feature.simple.SimpleFeature;
import java.net.MalformedURLException;
import java.net.URL;
diff --git a/src/main/java/org/matsim/run/prepare/DrtStopsWriter.java b/src/main/java/org/matsim/run/prepare/DrtStopsWriter.java
index d69d3f8..ab5fdf8 100644
--- a/src/main/java/org/matsim/run/prepare/DrtStopsWriter.java
+++ b/src/main/java/org/matsim/run/prepare/DrtStopsWriter.java
@@ -5,6 +5,7 @@
import org.apache.commons.csv.CSVRecord;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.geotools.api.feature.simple.SimpleFeature;
import org.locationtech.jts.geom.Geometry;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.Id;
@@ -18,7 +19,6 @@
import org.matsim.core.utils.io.IOUtils;
import org.matsim.core.utils.io.MatsimXmlWriter;
import org.matsim.run.RunKelheimScenario;
-import org.opengis.feature.simple.SimpleFeature;
import java.io.FileWriter;
import java.io.IOException;
diff --git a/src/main/java/org/matsim/run/prepare/PrepareNetwork.java b/src/main/java/org/matsim/run/prepare/PrepareNetwork.java
index 3bafb9f..b22fb53 100644
--- a/src/main/java/org/matsim/run/prepare/PrepareNetwork.java
+++ b/src/main/java/org/matsim/run/prepare/PrepareNetwork.java
@@ -2,6 +2,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.geotools.api.feature.simple.SimpleFeature;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
@@ -13,7 +14,6 @@
import org.matsim.application.options.ShpOptions;
import org.matsim.core.network.NetworkUtils;
import org.matsim.core.utils.geometry.geotools.MGC;
-import org.opengis.feature.simple.SimpleFeature;
import picocli.CommandLine;
import java.util.HashSet;
diff --git a/src/main/java/org/matsim/run/prepare/PrepareTransitSchedule.java b/src/main/java/org/matsim/run/prepare/PrepareTransitSchedule.java
index a7fd41a..689e5bf 100644
--- a/src/main/java/org/matsim/run/prepare/PrepareTransitSchedule.java
+++ b/src/main/java/org/matsim/run/prepare/PrepareTransitSchedule.java
@@ -1,5 +1,6 @@
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;
@@ -12,7 +13,6 @@
import org.matsim.pt.transitSchedule.api.TransitSchedule;
import org.matsim.pt.transitSchedule.api.TransitScheduleWriter;
import org.matsim.pt.transitSchedule.api.TransitStopFacility;
-import org.opengis.feature.simple.SimpleFeature;
import picocli.CommandLine;
import java.util.List;