diff --git a/.github/workflows/deploy-dtds.yaml b/.github/workflows/deploy-dtds.yaml
index bb48f61d27b..09d94069d76 100644
--- a/.github/workflows/deploy-dtds.yaml
+++ b/.github/workflows/deploy-dtds.yaml
@@ -1,18 +1,20 @@
name: deploy-dtds-on-website
on:
- push:
- branches:
- - master
+ pull_request:
+ types:
+ - closed
paths:
- - matsim/src/main/resources/dtd
+ - 'matsim/src/main/resources/dtd/**'
jobs:
rsync-dtds:
+ if: github.event.pull_request.merged == true # only if PR closed by merging
name: sync DTDs to website
runs-on: ubuntu-latest
steps:
+ - uses: actions/checkout@v4
- name: rsync dtds
uses: burnett01/rsync-deployments@7.0.1
with:
diff --git a/.github/workflows/full-integration.yaml b/.github/workflows/full-integration.yaml
index a75ea5767da..2c20cb48d31 100644
--- a/.github/workflows/full-integration.yaml
+++ b/.github/workflows/full-integration.yaml
@@ -14,7 +14,8 @@ jobs:
strategy:
fail-fast: false
matrix:
- os: [ubuntu-latest, windows-latest, macos-latest]
+ os: [ubuntu-latest, windows-latest]
+ #os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Prepare git
diff --git a/contribs/accessibility/pom.xml b/contribs/accessibility/pom.xml
index 73058cefd24..973dc3c5177 100644
--- a/contribs/accessibility/pom.xml
+++ b/contribs/accessibility/pom.xml
@@ -37,12 +37,12 @@
org.matsim.contribmatrixbasedptrouter
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribroadpricing
- 2025.0-SNAPSHOT
+ ${project.parent.version}net.sf.trove4j
@@ -70,7 +70,7 @@
org.matsim.contribanalysis
- 2025.0-SNAPSHOT
+ ${project.parent.version}
diff --git a/contribs/analysis/pom.xml b/contribs/analysis/pom.xml
index 74a32b64c03..eea01c79ffb 100644
--- a/contribs/analysis/pom.xml
+++ b/contribs/analysis/pom.xml
@@ -13,7 +13,7 @@
org.matsim.contribroadpricing
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.osgeo
diff --git a/contribs/application/pom.xml b/contribs/application/pom.xml
index 88bd8e9606c..c2cfee1e0bf 100644
--- a/contribs/application/pom.xml
+++ b/contribs/application/pom.xml
@@ -40,37 +40,37 @@
org.matsim.contribotfvis
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribosm
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribsumo
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribanalysis
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribemissions
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribnoise
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribfreight
- 2025.0-SNAPSHOT
+ ${project.parent.version}
@@ -87,7 +87,7 @@
com.github.matsim-orggtfs2matsim
- fc8b13954d
+ 47b0802a29
@@ -151,7 +151,7 @@
org.matsim.contribdvrp
- 2025.0-SNAPSHOT
+ ${project.parent.version}compile
diff --git a/contribs/application/src/main/java/org/matsim/application/ApplicationUtils.java b/contribs/application/src/main/java/org/matsim/application/ApplicationUtils.java
index 083a315ecb5..0a13fbe9311 100644
--- a/contribs/application/src/main/java/org/matsim/application/ApplicationUtils.java
+++ b/contribs/application/src/main/java/org/matsim/application/ApplicationUtils.java
@@ -440,12 +440,17 @@ public static Path matchInput(String name, Path dir) {
if (path.isPresent())
return path.get();
- // Match more general pattern at last
- path = matchPattern(".+\\.[a-zA-Z0-9]*_" + name + "\\..+", dir);
+ // Match more general pattern
+ path = matchPattern(".+\\.[a-zA-Z0-9\\-]*_" + name + "\\..+", dir);
if (path.isPresent())
return path.get();
- throw new IllegalArgumentException("Could not match input file: " + name);
+ // Even more permissive pattern
+ path = matchPattern(".+[a-zA-Z0-9_.\\-]*(_|\\.)" + name + ".+", dir);
+ if (path.isPresent())
+ return path.get();
+
+ throw new IllegalArgumentException("Could not match input file: %s (in %s)".formatted(name, dir));
}
private static Optional matchSuffix(String suffix, Path dir) {
diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/noise/NoiseAnalysis.java b/contribs/application/src/main/java/org/matsim/application/analysis/noise/NoiseAnalysis.java
index 3976a35c21b..bac5eaadd7c 100644
--- a/contribs/application/src/main/java/org/matsim/application/analysis/noise/NoiseAnalysis.java
+++ b/contribs/application/src/main/java/org/matsim/application/analysis/noise/NoiseAnalysis.java
@@ -7,6 +7,7 @@
import org.locationtech.jts.geom.Envelope;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.Scenario;
+import org.matsim.api.core.v01.TransportMode;
import org.matsim.application.ApplicationUtils;
import org.matsim.application.CommandSpec;
import org.matsim.application.MATSimAppCommand;
@@ -20,6 +21,7 @@
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.scenario.ScenarioUtils;
+import org.matsim.core.utils.collections.CollectionUtils;
import org.matsim.core.utils.geometry.CoordinateTransformation;
import org.matsim.core.utils.io.IOUtils;
import picocli.CommandLine;
@@ -28,10 +30,7 @@
import java.nio.file.Path;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
+import java.util.*;
@CommandLine.Command(
name = "noise-analysis",
@@ -67,7 +66,7 @@ public class NoiseAnalysis implements MATSimAppCommand {
@CommandLine.Option(names = "--consider-activities", split = ",", description = "Considered activities for noise calculation." +
" Use asterisk ('*') for acttype prefixes, if all such acts shall be considered.", defaultValue = "home*,work*,educ*,leisure*")
- private Set considerActivities;
+ private Set consideredActivities;
@CommandLine.Option(names = "--noise-barrier", description = "Path to the noise barrier File", defaultValue = "")
private String noiseBarrierFile;
@@ -87,10 +86,19 @@ public Integer call() throws Exception {
boolean overrideParameters = ! ConfigUtils.hasModule(config, NoiseConfigGroup.class);
NoiseConfigGroup noiseParameters = ConfigUtils.addOrGetModule(config, NoiseConfigGroup.class);
- if(overrideParameters){
- log.warn("no NoiseConfigGroup was configured before. Will set some standards. You should check the next lines in the log file!");
- noiseParameters.setConsideredActivitiesForReceiverPointGridArray(considerActivities.toArray(String[]::new));
- noiseParameters.setConsideredActivitiesForDamageCalculationArray(considerActivities.toArray(String[]::new));
+ if (overrideParameters){
+ log.warn("no NoiseConfigGroup was configured before. Will set some standards. You should check the next lines in the log file and the output_config.xml!");
+ noiseParameters.setConsideredActivitiesForReceiverPointGridArray(consideredActivities.toArray(String[]::new));
+ noiseParameters.setConsideredActivitiesForDamageCalculationArray(consideredActivities.toArray(String[]::new));
+
+ {
+ //the default settings are now actually the same as what we 'override' here, but let's leave it here for clarity.
+ Set ignoredNetworkModes = CollectionUtils.stringArrayToSet( new String[]{TransportMode.bike, TransportMode.walk, TransportMode.transit_walk, TransportMode.non_network_walk} );
+ noiseParameters.setNetworkModesToIgnoreSet( ignoredNetworkModes );
+
+ String[] hgvIdPrefixes = {"lkw", "truck", "freight"};
+ noiseParameters.setHgvIdPrefixesArray( hgvIdPrefixes );
+ }
//use actual speed and not freespeed
noiseParameters.setUseActualSpeedLevel(true);
diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java b/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java
index 11c75f21b1a..2365ed8a189 100644
--- a/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java
+++ b/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java
@@ -4,10 +4,7 @@
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
-import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap;
-import it.unimi.dsi.fastutil.objects.Object2IntMap;
-import it.unimi.dsi.fastutil.objects.Object2LongMap;
-import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
+import it.unimi.dsi.fastutil.objects.*;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.math3.analysis.interpolation.LoessInterpolator;
@@ -17,6 +14,7 @@
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
+import org.matsim.application.ApplicationUtils;
import org.matsim.application.CommandSpec;
import org.matsim.application.MATSimAppCommand;
import org.matsim.application.options.CsvOptions;
@@ -26,6 +24,7 @@
import org.matsim.core.utils.io.IOUtils;
import picocli.CommandLine;
import tech.tablesaw.api.*;
+import tech.tablesaw.columns.strings.AbstractStringColumn;
import tech.tablesaw.io.csv.CsvReadOptions;
import tech.tablesaw.joining.DataFrameJoiner;
import tech.tablesaw.selection.Selection;
@@ -34,7 +33,9 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.*;
+import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static tech.tablesaw.aggregate.AggregateFunctions.count;
@@ -44,16 +45,15 @@
requires = {"trips.csv", "persons.csv"},
produces = {
"mode_share.csv", "mode_share_per_dist.csv", "mode_users.csv", "trip_stats.csv",
- "mode_share_per_%s.csv", "population_trip_stats.csv", "trip_purposes_by_hour.csv",
- "mode_share_distance_distribution.csv",
+ "mode_share_per_purpose.csv", "mode_share_per_%s.csv",
+ "population_trip_stats.csv", "trip_purposes_by_hour.csv",
+ "mode_share_distance_distribution.csv", "mode_shift.csv", "mode_chains.csv",
"mode_choices.csv", "mode_choice_evaluation.csv", "mode_choice_evaluation_per_mode.csv",
"mode_confusion_matrix.csv", "mode_prediction_error.csv"
}
)
public class TripAnalysis implements MATSimAppCommand {
- private static final Logger log = LogManager.getLogger(TripAnalysis.class);
-
/**
* Attributes which relates this person to a reference person.
*/
@@ -66,31 +66,24 @@ public class TripAnalysis implements MATSimAppCommand {
* Person attribute containing its weight for analysis purposes.
*/
public static final String ATTR_REF_WEIGHT = "ref_weight";
-
+ private static final Logger log = LogManager.getLogger(TripAnalysis.class);
+ @CommandLine.Option(names = "--person-filter", description = "Define which persons should be included into trip analysis. Map like: Attribute name (key), attribute value (value). " +
+ "The attribute needs to be contained by output_persons.csv. Persons who do not match all filters are filtered out.", split = ",")
+ private final Map personFilters = new HashMap<>();
@CommandLine.Mixin
private InputOptions input = InputOptions.ofCommand(TripAnalysis.class);
@CommandLine.Mixin
private OutputOptions output = OutputOptions.ofCommand(TripAnalysis.class);
-
@CommandLine.Option(names = "--input-ref-data", description = "Optional path to reference data", required = false)
private String refData;
-
@CommandLine.Option(names = "--match-id", description = "Pattern to filter agents by id")
private String matchId;
-
@CommandLine.Option(names = "--dist-groups", split = ",", description = "List of distances for binning", defaultValue = "0,1000,2000,5000,10000,20000")
private List distGroups;
-
@CommandLine.Option(names = "--modes", split = ",", description = "List of considered modes, if not set all will be used")
private List modeOrder;
-
@CommandLine.Option(names = "--shp-filter", description = "Define how the shp file filtering should work", defaultValue = "home")
private LocationFilter filter;
-
- @CommandLine.Option(names = "--person-filter", description = "Define which persons should be included into trip analysis. Map like: Attribute name (key), attribute value (value). " +
- "The attribute needs to be contained by output_persons.csv. Persons who do not match all filters are filtered out.", split = ",")
- private final Map personFilters = new HashMap<>();
-
@CommandLine.Mixin
private ShpOptions shp;
@@ -137,6 +130,20 @@ private static double[] calcHistogram(double[] data, double[] bins) {
return hist;
}
+ private static Map getColumnTypes() {
+ Map columnTypes = new HashMap<>(Map.of("person", ColumnType.TEXT,
+ "trav_time", ColumnType.STRING, "wait_time", ColumnType.STRING, "dep_time", ColumnType.STRING,
+ "longest_distance_mode", ColumnType.STRING, "main_mode", ColumnType.STRING,
+ "start_activity_type", ColumnType.TEXT, "end_activity_type", ColumnType.TEXT,
+ "first_pt_boarding_stop", ColumnType.TEXT, "last_pt_egress_stop", ColumnType.TEXT));
+
+ // Map.of only has 10 argument max
+ columnTypes.put("traveled_distance", ColumnType.LONG);
+ columnTypes.put("euclidean_distance", ColumnType.LONG);
+
+ return columnTypes;
+ }
+
@Override
public Integer call() throws Exception {
@@ -209,18 +216,8 @@ public Integer call() throws Exception {
log.info("Filtered {} out of {} persons", persons.rowCount(), total);
- Map columnTypes = new HashMap<>(Map.of("person", ColumnType.TEXT,
- "trav_time", ColumnType.STRING, "wait_time", ColumnType.STRING, "dep_time", ColumnType.STRING,
- "longest_distance_mode", ColumnType.STRING, "main_mode", ColumnType.STRING,
- "start_activity_type", ColumnType.TEXT, "end_activity_type", ColumnType.TEXT,
- "first_pt_boarding_stop", ColumnType.TEXT, "last_pt_egress_stop", ColumnType.TEXT));
-
- // Map.of only has 10 argument max
- columnTypes.put("traveled_distance", ColumnType.LONG);
- columnTypes.put("euclidean_distance", ColumnType.LONG);
-
Table trips = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(input.getPath("trips.csv")))
- .columnTypesPartial(columnTypes)
+ .columnTypesPartial(getColumnTypes())
.sample(false)
.separator(CsvOptions.detectDelimiter(input.getPath("trips.csv"))).build());
@@ -286,10 +283,15 @@ public Integer call() throws Exception {
joined.addColumns(dist_group);
+ TextColumn purpose = joined.textColumn("end_activity_type");
+
+ // Remove suffix durations like _345
+ purpose.set(Selection.withRange(0, purpose.size()), purpose.replaceAll("_[0-9]{2,}$", ""));
+
writeModeShare(joined, labels);
if (groups != null) {
- groups.analyzeModeShare(joined, labels, modeOrder, (g) -> output.getPath("mode_share_per_%s.csv", g));
+ groups.writeModeShare(joined, labels, modeOrder, (g) -> output.getPath("mode_share_per_%s.csv", g));
}
if (persons.containsColumn(ATTR_REF_MODES)) {
@@ -308,15 +310,24 @@ public Integer call() throws Exception {
writePopulationStats(persons, joined);
- writeTripStats(joined);
-
- writeTripPurposes(joined);
-
- writeTripDistribution(joined);
+ tryRun(this::writeTripStats, joined);
+ tryRun(this::writeTripPurposes, joined);
+ tryRun(this::writeTripDistribution, joined);
+ tryRun(this::writeModeShift, joined);
+ tryRun(this::writeModeChains, joined);
+ tryRun(this::writeModeStatsPerPurpose, joined);
return 0;
}
+ private void tryRun(ThrowingConsumer
f, Table df) {
+ try {
+ f.accept(df);
+ } catch (IOException e) {
+ log.error("Error while running method", e);
+ }
+ }
+
private void writeModeShare(Table trips, List labels) {
Table aggr = trips.summarize("trip_id", count).by("dist_group", "main_mode");
@@ -503,11 +514,6 @@ private void writeTripPurposes(Table trips) {
IntColumn.create("arrival_h", arrival.intStream().toArray())
);
- TextColumn purpose = trips.textColumn("end_activity_type");
-
- // Remove suffix durations like _345
- purpose.set(Selection.withRange(0, purpose.size()), purpose.replaceAll("_[0-9]{2,}$", ""));
-
Table tArrival = trips.summarize("trip_id", count).by("end_activity_type", "arrival_h");
tArrival.column(0).setName("purpose");
@@ -583,6 +589,117 @@ private void writeTripDistribution(Table trips) throws IOException {
}
}
+ private void writeModeShift(Table trips) throws IOException {
+ Path path;
+ try {
+ Path dir = Path.of(input.getPath("trips.csv")).getParent().resolve("ITERS").resolve("it.0");
+ path = ApplicationUtils.matchInput("trips.csv", dir);
+ } catch (Exception e) {
+ log.error("Could not find trips from 0th iteration.", e);
+ return;
+ }
+
+ Table originalTrips = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(path.toString()))
+ .columnTypesPartial(getColumnTypes())
+ .sample(false)
+ .separator(CsvOptions.detectDelimiter(path.toString())).build());
+
+ // Use longest_distance_mode where main_mode is not present
+ originalTrips.stringColumn("main_mode")
+ .set(originalTrips.stringColumn("main_mode").isMissing(),
+ originalTrips.stringColumn("longest_distance_mode"));
+
+ originalTrips.column("main_mode").setName("original_mode");
+
+ Table joined = new DataFrameJoiner(trips, "trip_id").inner(true, originalTrips);
+ Table aggr = joined.summarize("trip_id", count).by("original_mode", "main_mode");
+
+ aggr.write().csv(output.getPath("mode_shift.csv").toFile());
+ }
+
+ /**
+ * Collects information about all modes used during one day.
+ */
+ private void writeModeChains(Table trips) throws IOException {
+
+ Map> modesPerPerson = new LinkedHashMap<>();
+
+ for (Row trip : trips) {
+ String id = trip.getString("person");
+ String mode = trip.getString("main_mode");
+ modesPerPerson.computeIfAbsent(id, s -> new LinkedList<>()).add(mode);
+ }
+
+ // Store other values explicitly
+ ObjectDoubleMutablePair other = ObjectDoubleMutablePair.of("other", 0);
+ Object2DoubleMap chains = new Object2DoubleOpenHashMap<>();
+ for (List modes : modesPerPerson.values()) {
+ String key;
+ if (modes.size() == 1)
+ key = modes.getFirst();
+ else if (modes.size() > 6) {
+ other.right(other.rightDouble() + 1);
+ continue;
+ } else
+ key = String.join("-", modes);
+
+ chains.mergeDouble(key, 1, Double::sum);
+ }
+
+
+ List> counts = chains.object2DoubleEntrySet().stream()
+ .map(e -> ObjectDoubleMutablePair.of(e.getKey(), (int) e.getDoubleValue()))
+ .sorted(Comparator.comparingDouble(p -> -p.rightDouble()))
+ .collect(Collectors.toList());
+
+ // Aggregate entries to prevent file from getting too large
+ for (int i = 250; i < counts.size(); i++) {
+ other.right(other.rightDouble() + counts.get(i).rightDouble());
+ }
+ counts = counts.subList(0, Math.min(counts.size(), 250));
+ counts.add(other);
+
+ counts.sort(Comparator.comparingDouble(p -> -p.rightDouble()));
+
+
+ try (CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(output.getPath("mode_chains.csv")), CSVFormat.DEFAULT)) {
+
+ printer.printRecord("modes", "count", "share");
+
+ double total = counts.stream().mapToDouble(ObjectDoubleMutablePair::rightDouble).sum();
+ for (ObjectDoubleMutablePair p : counts) {
+ printer.printRecord(p.left(), (int) p.rightDouble(), p.rightDouble() / total);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void writeModeStatsPerPurpose(Table trips) {
+
+ Table aggr = trips.summarize("trip_id", count).by("end_activity_type", "main_mode");
+
+ Comparator cmp = Comparator.comparing(row -> row.getString("end_activity_type"));
+ aggr = aggr.sortOn(cmp.thenComparing(row -> row.getString("main_mode")));
+
+ aggr.doubleColumn(aggr.columnCount() - 1).setName("share");
+ aggr.column("end_activity_type").setName("purpose");
+
+ Set purposes = (Set) aggr.column("purpose").asSet();
+
+ // Norm each purpose to 1
+ // It was not clear if the purpose is a string or text colum, therefor this code uses the abstract version
+ for (String label : purposes) {
+ DoubleColumn all = aggr.doubleColumn("share");
+ Selection sel = ((AbstractStringColumn>) aggr.column("purpose")).isEqualTo(label);
+
+ double total = all.where(sel).sum();
+ if (total > 0)
+ all.set(sel, all.divide(total));
+ }
+
+ aggr.write().csv(output.getPath("mode_share_per_purpose.csv").toFile());
+ }
+
/**
* How shape file filtering should be applied.
*/
@@ -592,4 +709,9 @@ enum LocationFilter {
home,
none
}
+
+ @FunctionalInterface
+ private interface ThrowingConsumer {
+ void accept(T t) throws IOException;
+ }
}
diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/population/TripByGroupAnalysis.java b/contribs/application/src/main/java/org/matsim/application/analysis/population/TripByGroupAnalysis.java
index b63a58f5ed8..5f7e8894500 100644
--- a/contribs/application/src/main/java/org/matsim/application/analysis/population/TripByGroupAnalysis.java
+++ b/contribs/application/src/main/java/org/matsim/application/analysis/population/TripByGroupAnalysis.java
@@ -100,7 +100,7 @@ final class TripByGroupAnalysis {
}
}
- void analyzeModeShare(Table trips, List dists, List modeOrder, Function output) {
+ void writeModeShare(Table trips, List dists, List modeOrder, Function output) {
for (Group group : groups) {
diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/pt/PublicTransitAnalysis.java b/contribs/application/src/main/java/org/matsim/application/analysis/pt/PublicTransitAnalysis.java
new file mode 100644
index 00000000000..e8785b30cda
--- /dev/null
+++ b/contribs/application/src/main/java/org/matsim/application/analysis/pt/PublicTransitAnalysis.java
@@ -0,0 +1,105 @@
+/* *********************************************************************** *
+ * project: org.matsim.*
+ * *
+ * *********************************************************************** *
+ * *
+ * copyright : (C) 2024 by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * *********************************************************************** */
+
+package org.matsim.application.analysis.pt;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.matsim.analysis.pt.stop2stop.PtStop2StopAnalysis;
+import org.matsim.api.core.v01.Scenario;
+import org.matsim.application.ApplicationUtils;
+import org.matsim.application.CommandSpec;
+import org.matsim.application.MATSimAppCommand;
+import org.matsim.application.analysis.emissions.AirPollutionAnalysis;
+import org.matsim.application.options.InputOptions;
+import org.matsim.application.options.OutputOptions;
+import org.matsim.application.options.SampleOptions;
+import org.matsim.core.api.experimental.events.EventsManager;
+import org.matsim.core.config.Config;
+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 picocli.CommandLine;
+
+@CommandLine.Command(
+ name = "transit", description = "General public transit analysis.",
+ mixinStandardHelpOptions = true, showDefaultValues = true
+)
+@CommandSpec(requireRunDirectory = true,
+ produces = {
+ "pt_pax_volumes.csv.gz",
+ }
+)
+public class PublicTransitAnalysis implements MATSimAppCommand {
+
+ private static final Logger log = LogManager.getLogger(PublicTransitAnalysis.class);
+
+ @CommandLine.Mixin
+ private final InputOptions input = InputOptions.ofCommand(PublicTransitAnalysis.class);
+ @CommandLine.Mixin
+ private final OutputOptions output = OutputOptions.ofCommand(PublicTransitAnalysis.class);
+ @CommandLine.Mixin
+ private SampleOptions sample;
+
+ public static void main(String[] args) {
+ new PublicTransitAnalysis().execute(args);
+ }
+
+ @Override
+ public Integer call() throws Exception {
+
+ Config config = prepareConfig();
+ Scenario scenario = ScenarioUtils.loadScenario(config);
+ EventsManager eventsManager = EventsUtils.createEventsManager();
+
+ String eventsFile = ApplicationUtils.matchInput("events", input.getRunDirectory()).toString();
+
+ PtStop2StopAnalysis ptStop2StopEventHandler = new PtStop2StopAnalysis(scenario.getTransitVehicles(), sample.getUpscaleFactor());
+ eventsManager.addHandler(ptStop2StopEventHandler);
+ eventsManager.initProcessing();
+ MatsimEventsReader matsimEventsReader = new MatsimEventsReader(eventsManager);
+ matsimEventsReader.readFile(eventsFile);
+
+ log.info("Done reading the events file.");
+ log.info("Finish processing...");
+ eventsManager.finishProcessing();
+
+ ptStop2StopEventHandler.writeStop2StopEntriesByDepartureCsv(output.getPath("pt_pax_volumes.csv.gz"),
+ ",", ";");
+
+ return 0;
+ }
+
+ private Config prepareConfig() {
+ Config config = ConfigUtils.loadConfig(ApplicationUtils.matchInput("config.xml", input.getRunDirectory()).toAbsolutePath().toString());
+
+ config.vehicles().setVehiclesFile(ApplicationUtils.matchInput("vehicles", input.getRunDirectory()).toAbsolutePath().toString());
+ config.network().setInputFile(ApplicationUtils.matchInput("network", input.getRunDirectory()).toAbsolutePath().toString());
+ config.transit().setTransitScheduleFile(ApplicationUtils.matchInput("transitSchedule", input.getRunDirectory()).toAbsolutePath().toString());
+ config.transit().setVehiclesFile(ApplicationUtils.matchInput("transitVehicles", input.getRunDirectory()).toAbsolutePath().toString());
+ config.plans().setInputFile(null);
+ config.facilities().setInputFile(null);
+ config.eventsManager().setNumberOfThreads(null);
+ config.eventsManager().setEstimatedNumberOfEvents(null);
+ config.global().setNumberOfThreads(1);
+
+ return config;
+ }
+}
diff --git a/contribs/application/src/main/java/org/matsim/application/options/ShpOptions.java b/contribs/application/src/main/java/org/matsim/application/options/ShpOptions.java
index 985db84bba7..5d9f8ccec99 100644
--- a/contribs/application/src/main/java/org/matsim/application/options/ShpOptions.java
+++ b/contribs/application/src/main/java/org/matsim/application/options/ShpOptions.java
@@ -8,9 +8,12 @@
import org.geotools.api.feature.simple.SimpleFeatureType;
import org.geotools.api.referencing.FactoryException;
import org.geotools.api.referencing.crs.CoordinateReferenceSystem;
-import org.geotools.data.*;
+import org.geotools.api.referencing.operation.MathTransform;
+import org.geotools.api.referencing.operation.TransformException;
+import org.geotools.data.DefaultTransaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
+import org.geotools.geometry.jts.JTS;
import org.geotools.geopkg.GeoPkgDataStoreFactory;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.*;
@@ -219,12 +222,30 @@ public Geometry getGeometry() {
);
if (geometryCollection.isEmpty()) {
- throw new IllegalStateException("There are noe geometries in the shape file.");
+ throw new IllegalStateException("There are no geometries in the shape file.");
}
return geometryCollection.union();
}
+ /**
+ * Return the union of all geometries in the shape file and project it to the target crs.
+ * @param toCRS target coordinate system
+ */
+ public Geometry getGeometry(String toCRS) {
+ try {
+ CoordinateReferenceSystem sourceCRS = CRS.decode(detectCRS());
+ CoordinateReferenceSystem targetCRS = CRS.decode(toCRS);
+
+ MathTransform ct = CRS.findMathTransform(sourceCRS, targetCRS);
+
+ return JTS.transform(getGeometry(), ct);
+
+ } catch (TransformException | FactoryException e) {
+ throw new IllegalStateException("Could not transform coordinates of the provided shape", e);
+ }
+ }
+
/**
* Creates an index to query features from this shape file.
*
diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/network/CreateAvroNetwork.java b/contribs/application/src/main/java/org/matsim/application/prepare/network/CreateAvroNetwork.java
index c94b17f9335..04f06a7df91 100644
--- a/contribs/application/src/main/java/org/matsim/application/prepare/network/CreateAvroNetwork.java
+++ b/contribs/application/src/main/java/org/matsim/application/prepare/network/CreateAvroNetwork.java
@@ -108,8 +108,11 @@ public Integer call() throws Exception {
filter = filter.and(link -> p.matcher(link.getId().toString()).matches());
}
+ // Strings that could have been added in the list, due to command line parsing
+ modes.removeIf(m -> m.isBlank() || m.equals("none") || m.equals("\"") || m.equals("\"\""));
+
// At least one of the specified modes needs to be contained
- if (!modes.isEmpty() && !modes.equals(Set.of("none"))) {
+ if (!modes.isEmpty()) {
filter = filter.and(link -> modes.stream().anyMatch(m -> link.getAllowedModes().contains(m)));
}
diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/network/params/ApplyNetworkParams.java b/contribs/application/src/main/java/org/matsim/application/prepare/network/params/ApplyNetworkParams.java
index 048e2fa81b7..8d8e341154d 100644
--- a/contribs/application/src/main/java/org/matsim/application/prepare/network/params/ApplyNetworkParams.java
+++ b/contribs/application/src/main/java/org/matsim/application/prepare/network/params/ApplyNetworkParams.java
@@ -53,7 +53,8 @@ public class ApplyNetworkParams implements MATSimAppCommand {
@CommandLine.Option(names = "--model", description = "Reference to the network model class", required = true)
private Class extends NetworkModel> modelClazz;
- @CommandLine.Option(names = "--factor-bounds", split = ",", description = "Speed factor limits (lower,upper bound)", defaultValue = NetworkParamsOpt.DEFAULT_FACTOR_BOUNDS)
+ @CommandLine.Option(names = "--factor-bounds", split = ",", description = "Speed factor limits (lower, upper bound). " +
+ "Can be negative to indicate absolute speed bounds (in km/h)", defaultValue = NetworkParamsOpt.DEFAULT_FACTOR_BOUNDS)
private double[] speedFactorBounds;
@CommandLine.Option(names = "--capacity-bounds", split = ",", defaultValue = "0.4,0.6,0.8",
@@ -234,30 +235,50 @@ private boolean applyFreeSpeed(Link link, Feature ft) {
return false;
}
+ double allowedSpeed = (double) link.getAttributes().getAttribute("allowed_speed");
+ double freeSpeed = allowedSpeed * speedFactor;
+
boolean modified = false;
- if (speedFactor > speedFactorBounds[1]) {
+ if (speedFactor > speedFactorBounds[1] && speedFactorBounds[1] >= 0) {
log.warn("Reducing speed factor on {} from {} to {}", link.getId(), speedFactor, speedFactorBounds[1]);
speedFactor = speedFactorBounds[1];
modified = true;
}
+ // Use absolute bound for speed
+ if (freeSpeed > -speedFactorBounds[1]/3.6 && speedFactorBounds[1] < 0) {
+ log.warn("Reducing speed on {} from {} to {}", link.getId(), freeSpeed, -speedFactorBounds[1]/3.6);
+ speedFactor = (-speedFactorBounds[1] / 3.6) / allowedSpeed;
+ modified = true;
+ }
+
// Threshold for very low speed factors
- if (speedFactor < speedFactorBounds[0]) {
+ if (speedFactor < speedFactorBounds[0] && speedFactorBounds[0] >= 0) {
log.warn("Increasing speed factor on {} from {} to {}", link, speedFactor, speedFactorBounds[0]);
speedFactor = speedFactorBounds[0];
modified = true;
}
- double freeSpeed = (double) link.getAttributes().getAttribute("allowed_speed") * speedFactor;
+ // Absolute negative speed factor
+ if (freeSpeed < -speedFactorBounds[0]/3.6 && speedFactorBounds[0] < 0) {
+ log.warn("Increasing speed on {} from {} to {}", link, freeSpeed, -speedFactorBounds[0]/3.6);
+ speedFactor = (-speedFactorBounds[0] / 3.6) / allowedSpeed;
+ modified = true;
+ }
+ // Recalculate with updated speed factor
+ freeSpeed = allowedSpeed * speedFactor;
freeSpeed = BigDecimal.valueOf(freeSpeed).setScale(3, RoundingMode.HALF_EVEN).doubleValue();
if (decrease && freeSpeed > link.getFreespeed())
return false;
link.setFreespeed(freeSpeed);
- link.getAttributes().putAttribute("speed_factor", freeSpeed);
+ link.getAttributes().putAttribute(
+ "speed_factor",
+ BigDecimal.valueOf(freeSpeed).setScale(5, RoundingMode.HALF_EVEN).doubleValue()
+ );
return modified;
}
diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/network/params/EvalFreespeedParams.java b/contribs/application/src/main/java/org/matsim/application/prepare/network/params/EvalFreespeedParams.java
index cd2ba4e016a..68cd6099058 100644
--- a/contribs/application/src/main/java/org/matsim/application/prepare/network/params/EvalFreespeedParams.java
+++ b/contribs/application/src/main/java/org/matsim/application/prepare/network/params/EvalFreespeedParams.java
@@ -121,12 +121,27 @@ static Result applyAndEvaluateParams(
speedFactor = speedModel.predict(ft.features(), ft.categories());
// apply lower and upper bound
- speedFactor = Math.max(speedFactorBounds[0], speedFactor);
- speedFactor = Math.min(speedFactorBounds[1], speedFactor);
+ if (speedFactorBounds[0] >= 0)
+ speedFactor = Math.max(speedFactorBounds[0], speedFactor);
+
+ if (speedFactorBounds[1] >= 0)
+ speedFactor = Math.min(speedFactorBounds[1], speedFactor);
attributes.put(link.getId(), speedModel.getData(ft.features(), ft.categories()));
- link.setFreespeed(allowedSpeed * speedFactor);
+ double freespeed = allowedSpeed * speedFactor;
+
+ // Check absolute bounds on the freespeed
+ if (speedFactorBounds[0] < 0 && freespeed < -speedFactorBounds[0]/3.6) {
+ freespeed = -speedFactorBounds[0]/3.6;
+ speedFactor = freespeed / allowedSpeed;
+ }
+ if (speedFactorBounds[1] < 0 && freespeed > -speedFactorBounds[1]/3.6) {
+ freespeed = -speedFactorBounds[1]/3.6;
+ speedFactor = freespeed / allowedSpeed;
+ }
+
+ link.setFreespeed(freespeed);
link.getAttributes().putAttribute("speed_factor", speedFactor);
} else
diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/network/params/FreespeedOptServer.java b/contribs/application/src/main/java/org/matsim/application/prepare/network/params/FreespeedOptServer.java
index fef19850305..c17189b3a95 100644
--- a/contribs/application/src/main/java/org/matsim/application/prepare/network/params/FreespeedOptServer.java
+++ b/contribs/application/src/main/java/org/matsim/application/prepare/network/params/FreespeedOptServer.java
@@ -57,7 +57,8 @@ public class FreespeedOptServer implements MATSimAppCommand {
@CommandLine.Parameters(arity = "1..*", description = "Input validation files loaded from APIs")
private List validationFiles;
- @CommandLine.Option(names = "--factor-bounds", split = ",", description = "Speed factor limits (lower,upper bound)", defaultValue = NetworkParamsOpt.DEFAULT_FACTOR_BOUNDS)
+ @CommandLine.Option(names = "--factor-bounds", split = ",", description = "Speed factor limits (lower, upper bound). " +
+ "Can be negative to indicate absolute speed bounds (in km/h)", defaultValue = NetworkParamsOpt.DEFAULT_FACTOR_BOUNDS)
private double[] speedFactorBounds;
@CommandLine.Option(names = "--ref-hours", description = "Reference hours", defaultValue = "3,21", split = ",")
diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/pt/AdjustSameDepartureTimes.java b/contribs/application/src/main/java/org/matsim/application/prepare/pt/AdjustSameDepartureTimes.java
new file mode 100644
index 00000000000..4d8b9378815
--- /dev/null
+++ b/contribs/application/src/main/java/org/matsim/application/prepare/pt/AdjustSameDepartureTimes.java
@@ -0,0 +1,154 @@
+package org.matsim.application.prepare.pt;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.matsim.core.utils.geometry.CoordUtils;
+import org.matsim.core.utils.misc.OptionalTime;
+import org.matsim.pt.transitSchedule.api.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+
+/**
+ * Some providers set the same departure and arrival times for multiple stops.
+ * This usually happens with on-demand buses, but can also happen on night buses where multiple stops can have a departure at the same minute.
+ * These departure times will lead to artifacts when using a pseudo network.
+ * The purpose of this class is to spread these departures more evently.
+ * However, in the case of on demand buses, the travel times will likely still be too optimistic.
+ */
+public class AdjustSameDepartureTimes implements Consumer {
+
+ private static Logger log = LogManager.getLogger(AdjustSameDepartureTimes.class);
+
+ private static OptionalTime add(OptionalTime x, double t) {
+ if (!x.isDefined()) {
+ return x;
+ }
+ return OptionalTime.defined(x.seconds() + t);
+ }
+
+ @Override
+ public void accept(TransitSchedule schedule) {
+ for (TransitLine line : schedule.getTransitLines().values()) {
+
+ List routes = new ArrayList<>(line.getRoutes().values());
+ for (TransitRoute route : routes) {
+ List newStops = adjustDepartures(schedule.getFactory(), route);
+
+ if (newStops == null) {
+ continue;
+ }
+
+ log.info("Adjusted departures for route {} in line {}", route.getId(), line.getId());
+
+ line.removeRoute(route);
+
+ TransitRoute newRoute = schedule.getFactory().createTransitRoute(route.getId(), route.getRoute(), newStops, route.getTransportMode());
+ newRoute.setDescription(route.getDescription());
+ for (Map.Entry e : route.getAttributes().getAsMap().entrySet()) {
+ newRoute.getAttributes().putAttribute(e.getKey(), e.getValue());
+ }
+ route.getDepartures().values().forEach(newRoute::addDeparture);
+
+ line.addRoute(newRoute);
+ }
+ }
+
+ }
+
+ private List adjustDepartures(TransitScheduleFactory f, TransitRoute route) {
+
+ List stops = new ArrayList<>(route.getStops());
+
+ boolean adjusted = false;
+
+ // Check if the times at the end of the schedule are the same
+ // These need to be calculated and can not be interpolated
+ // The arrival at the last stop is shifted by small travel time
+ if (stops.size() > 1) {
+ TransitRouteStop last = stops.getLast();
+ TransitRouteStop secondLast = stops.get(stops.size() - 2);
+
+ OptionalTime lastDep = last.getDepartureOffset().or(last.getArrivalOffset());
+ OptionalTime secondLastDep = secondLast.getDepartureOffset().or(secondLast.getArrivalOffset());
+
+ if (lastDep.isDefined() && secondLastDep.isDefined() && lastDep.equals(secondLastDep)) {
+ // Calculate the time between the last two stops
+ double dist = Math.max(20, CoordUtils.calcEuclideanDistance(last.getStopFacility().getCoord(), secondLast.getStopFacility().getCoord()));
+ double time = dist / 10; // 10 m/s
+
+ // Calculate the time for the last stop
+ TransitRouteStop newStop = f.createTransitRouteStop(
+ last.getStopFacility(),
+ add(last.getArrivalOffset(), time),
+ add(last.getDepartureOffset(), time)
+ );
+
+ newStop.setAwaitDepartureTime(last.isAwaitDepartureTime());
+ newStop.setAllowAlighting(last.isAllowAlighting());
+ newStop.setAllowBoarding(last.isAllowBoarding());
+
+ stops.set(stops.size() - 1, newStop);
+ adjusted = true;
+ }
+ }
+
+ for (int i = 0; i < stops.size() - 1; ) {
+
+ TransitRouteStop stop = stops.get(i);
+ OptionalTime dep = stop.getDepartureOffset().or(stop.getArrivalOffset());
+
+ if (!dep.isDefined()) {
+ i++;
+ continue;
+ }
+
+ OptionalTime arr = null;
+ int j = i + 1;
+ for (; j < stops.size(); j++) {
+ TransitRouteStop nextStop = stops.get(j);
+ arr = nextStop.getArrivalOffset().or(nextStop.getDepartureOffset());
+ if (!dep.equals(arr)) {
+ break;
+ }
+ }
+
+ if (arr == null) {
+ i++;
+ continue;
+ }
+
+ if (j > i + 1) {
+ double time = dep.seconds();
+ double diff = (arr.seconds() - time) / (j - i);
+
+ for (int k = i + 1; k < j; k++) {
+ TransitRouteStop stopToAdjust = stops.get(k);
+ int add = (int) (diff * (k - i));
+
+ TransitRouteStop newStop = f.createTransitRouteStop(
+ stopToAdjust.getStopFacility(),
+ add(stopToAdjust.getArrivalOffset(), add),
+ add(stopToAdjust.getDepartureOffset(), add)
+ );
+
+ newStop.setAwaitDepartureTime(stopToAdjust.isAwaitDepartureTime());
+ newStop.setAllowAlighting(stopToAdjust.isAllowAlighting());
+ newStop.setAllowBoarding(stopToAdjust.isAllowBoarding());
+
+ stops.set(k, newStop);
+ adjusted = true;
+ }
+ }
+
+ i = j;
+ }
+
+ if (adjusted)
+ return stops;
+
+ return null;
+ }
+}
diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java b/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java
index 5038d1f046c..ddbe0e7868a 100644
--- a/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java
+++ b/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java
@@ -1,5 +1,6 @@
package org.matsim.application.prepare.pt;
+import com.conveyal.gtfs.model.Route;
import com.conveyal.gtfs.model.Stop;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager;
@@ -31,10 +32,8 @@
import java.io.File;
import java.nio.file.Path;
import java.time.LocalDate;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
+import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -77,6 +76,15 @@ public class CreateTransitScheduleFromGtfs implements MATSimAppCommand {
@CommandLine.Option(names = "--include-stops", description = "Fully qualified class name to a Predicate for filtering certain stops")
private Class> includeStops;
+ @CommandLine.Option(names = "--transform-stops", description = "Fully qualified class name to a Consumer for transforming stops before usage")
+ private Class> transformStops;
+
+ @CommandLine.Option(names = "--transform-routes", description = "Fully qualified class name to a Consumer for transforming routes before usage")
+ private Class> transformRoutes;
+
+ @CommandLine.Option(names = "--transform-schedule", description = "Fully qualified class name to a Consumer to be executed after the schedule was created", arity = "0..*", split = ",")
+ private List> transformSchedule;
+
@CommandLine.Option(names = "--merge-stops", description = "Whether stops should be merged by coordinate")
private boolean mergeStops;
@@ -134,6 +142,15 @@ public Integer call() throws Exception {
log.info("Using prefix: {}", prefix);
}
+ if (transformStops != null) {
+ converter.setTransformStop(createConsumer(transformStops, Stop.class));
+ }
+
+ if (transformRoutes != null) {
+ converter.setTransformRoute(createConsumer(transformRoutes, Route.class));
+ }
+
+
converter.build().convert();
i++;
}
@@ -144,6 +161,24 @@ public Integer call() throws Exception {
TransitSchedulePostProcessTools.copyEarlyDeparturesToFollowingNight(scenario.getTransitSchedule(), 6 * 3600, "copied");
}
+ if (transformSchedule != null && !transformSchedule.isEmpty()) {
+ for (Class> c : transformSchedule) {
+ Consumer f = createConsumer(c, TransitSchedule.class);
+ log.info("Applying {} to created schedule", c.getName());
+ f.accept(scenario.getTransitSchedule());
+ }
+ }
+
+ for (TransitLine line : scenario.getTransitSchedule().getTransitLines().values()) {
+ List routes = new ArrayList<>(line.getRoutes().values());
+ for (TransitRoute route : routes) {
+ if (route.getDepartures().isEmpty()) {
+ log.warn("Route {} in line {} with no departures removed.", route.getId(), line.getId());
+ line.removeRoute(route);
+ }
+ }
+ }
+
Network network = NetworkUtils.readNetwork(networkFile);
Scenario ptScenario = getScenarioWithPseudoPtNetworkAndTransitVehicles(network, scenario.getTransitSchedule(), "pt_");
@@ -151,11 +186,14 @@ public Integer call() throws Exception {
if (validate) {
//Check schedule and network
TransitScheduleValidator.ValidationResult checkResult = TransitScheduleValidator.validateAll(ptScenario.getTransitSchedule(), ptScenario.getNetwork());
+ List warnings = checkResult.getWarnings();
+ if (!warnings.isEmpty())
+ log.warn("TransitScheduleValidator warnings: {}", String.join("\n", warnings));
+
if (checkResult.isValid()) {
log.info("TransitSchedule and Network valid according to TransitScheduleValidator");
- log.warn("TransitScheduleValidator warnings: {}", checkResult.getWarnings());
} else {
- log.error(checkResult.getErrors());
+ log.error("TransitScheduleValidator errors: {}", String.join("\n", checkResult.getErrors()));
throw new RuntimeException("TransitSchedule and/or Network invalid");
}
}
@@ -170,6 +208,12 @@ public Integer call() throws Exception {
return 0;
}
+ @SuppressWarnings({"unchecked", "unused"})
+ private Consumer createConsumer(Class> consumer, Class type) throws ReflectiveOperationException {
+ return (Consumer) consumer.getDeclaredConstructor().newInstance();
+ }
+
+ @SuppressWarnings("unchecked")
private Predicate createFilter(int i) throws Exception {
Predicate filter = (stop) -> true;
diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/scenario/CreateScenarioCutOut.java b/contribs/application/src/main/java/org/matsim/application/prepare/scenario/CreateScenarioCutOut.java
index d7450553f5c..4dcd8a6bf5a 100644
--- a/contribs/application/src/main/java/org/matsim/application/prepare/scenario/CreateScenarioCutOut.java
+++ b/contribs/application/src/main/java/org/matsim/application/prepare/scenario/CreateScenarioCutOut.java
@@ -2,10 +2,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.LineString;
+import org.locationtech.jts.geom.*;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
@@ -30,6 +27,7 @@
import org.matsim.core.population.algorithms.ParallelPersonAlgorithmUtils;
import org.matsim.core.population.algorithms.PersonAlgorithm;
import org.matsim.core.population.routes.NetworkRoute;
+import org.matsim.core.router.DefaultAnalysisMainModeIdentifier;
import org.matsim.core.router.TripStructureUtils;
import org.matsim.core.router.TripStructureUtils.Trip;
import org.matsim.core.router.costcalculators.OnlyTimeDependentTravelDisutility;
@@ -212,6 +210,11 @@ public Integer call() throws Exception {
return 2;
}
+ if (eventPath != null && outputEvents == null) {
+ log.error("Events were given as input, that means --output-network-change-events must be set.");
+ return 2;
+ }
+
// Prepare required input-data
Config config = ConfigUtils.createConfig();
config.global().setCoordinateSystem(crs.getInputCRS());
@@ -223,7 +226,7 @@ public Integer call() throws Exception {
}
scenario = ScenarioUtils.loadScenario(config);
- geom = shp.getGeometry();
+ geom = shp.getGeometry(crs.getInputCRS());
geomBuffer = geom.buffer(buffer);
for (String mode : modes)
@@ -240,7 +243,7 @@ public Integer call() throws Exception {
manager.addHandler(tt);
manager.initProcessing();
- EventsUtils.readEvents(manager, eventPath.toString());
+ EventsUtils.readEvents(manager, eventPath);
manager.finishProcessing();
}
@@ -257,18 +260,32 @@ public Integer call() throws Exception {
}
}
+ log.info("Links in shape: {} out of {}", linksToKeep.size(), scenario.getNetwork().getLinks().size());
+
+ if (linksToKeep.isEmpty()) {
+ log.error("No links are in the resulting network. Check your input shape file and coordinate system");
+ log.error("If using EPSG:4326 (WGS84), -Dorg.geotools.referencing.forceXY=true might help");
+ return 1;
+ }
+
// Cut out the population and mark needed network parts
ParallelPersonAlgorithmUtils.run(scenario.getPopulation(), Runtime.getRuntime().availableProcessors(), this);
//Population
+ log.info("Persons in the original population: {}", scenario.getPopulation().getPersons().size());
log.info("Persons to delete: {}", personsToDelete.size());
for (Id personId : personsToDelete) {
scenario.getPopulation().removePerson(personId);
}
- //Network
- log.info("Links to add: {}", linksToKeep.size());
+ log.info("Persons in the resulting scenario: {}", scenario.getPopulation().getPersons().size());
+
+ if (scenario.getPopulation().getPersons().isEmpty()) {
+ log.error("No persons are in the resulting population. Check if your input shape file and coordinate system is correct. Exiting ...");
+ return 1;
+ }
+ // Network
log.info("Additional links from routes to include: {}", linksToInclude.size());
log.info("number of links in original network: {}", scenario.getNetwork().getLinks().size());
@@ -295,8 +312,7 @@ public Integer call() throws Exception {
ParallelPersonAlgorithmUtils.run(scenario.getPopulation(), Runtime.getRuntime().availableProcessors(), new CleanPersonLinkIds());
- log.info("Persons in the scenario: {}", scenario.getPopulation().getPersons().size());
- PopulationUtils.writePopulation(scenario.getPopulation(), outputPopulation.toString());
+ PopulationUtils.writePopulation(scenario.getPopulation(), outputPopulation);
if (facilityPath != null) {
@@ -310,10 +326,10 @@ public Integer call() throws Exception {
if (eventPath != null) {
List events = generateNetworkChangeEvents(changeEventsInterval);
- new NetworkChangeEventsWriter().write(outputEvents.toString(), events);
+ new NetworkChangeEventsWriter().write(outputEvents, events);
}
- NetworkUtils.writeNetwork(scenario.getNetwork(), outputNetwork.toString());
+ NetworkUtils.writeNetwork(scenario.getNetwork(), outputNetwork);
return 0;
}
@@ -346,7 +362,7 @@ private void filterFacilities() {
}
// Expensive check last
- if (f.getCoord() != null && geom.contains(MGC.coord2Point(f.getCoord())))
+ if (f.getCoord() != null && geom.contains(MGC.coord2Point(f.getCoord())))
facilitiesToInclude.add(f.getId());
}
@@ -435,7 +451,13 @@ private Coord getActivityCoord(Activity activity) {
if (scenario.getActivityFacilities() != null && activity.getFacilityId() != null && scenario.getActivityFacilities().getFacilities().containsKey(activity.getFacilityId()))
return scenario.getActivityFacilities().getFacilities().get(activity.getFacilityId()).getCoord();
- return activity.getCoord();
+ if (activity.getCoord() != null)
+ return activity.getCoord();
+
+ if (activity.getLinkId() != null && scenario.getNetwork().getLinks().containsKey(activity.getLinkId()))
+ return scenario.getNetwork().getLinks().get(activity.getLinkId()).getCoord();
+
+ return null;
}
/**
@@ -483,34 +505,44 @@ public void run(Person person) {
boolean keepPerson = false;
List trips = TripStructureUtils.getTrips(person.getSelectedPlan());
-
+ List activities = TripStructureUtils.getActivities(person.getSelectedPlan(), TripStructureUtils.StageActivityHandling.ExcludeStageActivities);
Set> linkIds = new HashSet<>();
Set> facilityIds = new HashSet<>();
- for (Trip trip : trips) {
- Coord originCoord = getActivityCoord(trip.getOriginActivity());
- Coord destinationCoord = getActivityCoord(trip.getDestinationActivity());
-
- if (originCoord == null || destinationCoord == null) {
- if (noActCoordsWarnings++ < 10)
- log.info("Activity coords of trip is null. Skipping Trip...");
+ // Check activities first, some agent might be stationary
+ for (Activity act : activities) {
+ Coord coord = getActivityCoord(act);
- continue;
+ if (coord == null && noActCoordsWarnings++ < 10) {
+ log.info("Activity coords for agent {} are null. Skipping Trip...", person.getId());
}
- // keep all agents starting or ending in area
- if (geom.contains(MGC.coord2Point(originCoord)) || geom.contains(MGC.coord2Point(destinationCoord))) {
+ if (coord != null && geom.contains(MGC.coord2Point(coord))) {
keepPerson = true;
}
- LineString line = geoFactory.createLineString(new Coordinate[]{
- MGC.coord2Coordinate(originCoord),
- MGC.coord2Coordinate(destinationCoord)
- });
+ if (act.getFacilityId() != null)
+ facilityIds.add(act.getFacilityId());
- // also keep persons traveling through or close to area (beeline)
- if (line.intersects(geom)) {
- keepPerson = true;
+ if (act.getLinkId() != null)
+ linkIds.add(act.getLinkId());
+
+ }
+
+ for (Trip trip : trips) {
+ Coord originCoord = getActivityCoord(trip.getOriginActivity());
+ Coord destinationCoord = getActivityCoord(trip.getDestinationActivity());
+
+ if (originCoord != null && destinationCoord != null) {
+ LineString line = geoFactory.createLineString(new Coordinate[]{
+ MGC.coord2Coordinate(originCoord),
+ MGC.coord2Coordinate(destinationCoord)
+ });
+
+ // also keep persons traveling through or close to area (beeline)
+ if (line.intersects(geom)) {
+ keepPerson = true;
+ }
}
//Save route links
@@ -546,20 +578,6 @@ public void run(Person person) {
}
// There is no additional link freespeed information, that we could save. So we are finished here
}
-
- if (trip.getOriginActivity().getFacilityId() != null)
- facilityIds.add(trip.getOriginActivity().getFacilityId());
-
- if (trip.getDestinationActivity().getFacilityId() != null)
- facilityIds.add(trip.getDestinationActivity().getFacilityId());
-
- if (trip.getOriginActivity().getLinkId() != null) {
- linkIds.add(trip.getOriginActivity().getLinkId());
- }
-
- if (trip.getDestinationActivity().getLinkId() != null) {
- linkIds.add(trip.getDestinationActivity().getLinkId());
- }
}
}
diff --git a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DefaultJobDurationCalculator.java b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DefaultJobDurationCalculator.java
new file mode 100644
index 00000000000..42ddbc4068a
--- /dev/null
+++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DefaultJobDurationCalculator.java
@@ -0,0 +1,37 @@
+package org.matsim.freightDemandGeneration;
+
+import org.matsim.api.core.v01.Scenario;
+
+public class DefaultJobDurationCalculator implements JobDurationCalculator {
+ @Override
+ public double calculateServiceDuration(Integer serviceTimePerUnit, int demandForThisService) {
+ return getDefaultCalculation(serviceTimePerUnit, demandForThisService);
+ }
+
+ @Override
+ public double calculatePickupDuration(Integer pickupDurationPerUnit, int demandForThisShipment) {
+ return getDefaultCalculation(pickupDurationPerUnit, demandForThisShipment);
+ }
+
+ @Override
+ public double calculateDeliveryDuration(Integer deliveryDurationPerUnit, int demandForThisShipment) {
+ return getDefaultCalculation(deliveryDurationPerUnit, demandForThisShipment);
+ }
+
+ @Override
+ public void recalculateJobDurations(Scenario scenario) {
+ // do nothing
+ }
+
+ /**
+ * @param timePerUnit time per unit
+ * @param demandForThisService demand for this service
+ * @return default calculation
+ */
+ private int getDefaultCalculation(int timePerUnit, int demandForThisService) {
+ if (demandForThisService == 0)
+ return timePerUnit;
+ else
+ return timePerUnit * demandForThisService;
+ }
+}
diff --git a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java
index e39eedd9ad4..63179128cc4 100644
--- a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java
+++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java
@@ -324,16 +324,18 @@ public String getTypeOfDemand() {
* @param crsTransformationNetworkAndShape CoordinateTransformation for the network and shape file
* @param population Population
* @param shapeCategory Column name in the shape file for the data connection in the csv files
- * @throws IOException if the csv file cannot be read
+ * @param jobDurationCalculator Calculator for the job duration
+ * @throws IOException if the csv file cannot be read
*/
static void readAndCreateDemand(Scenario scenario, Path csvLocationDemand,
ShpOptions.Index indexShape, boolean combineSimilarJobs,
- CoordinateTransformation crsTransformationNetworkAndShape, Population population, String shapeCategory) throws IOException {
+ CoordinateTransformation crsTransformationNetworkAndShape, Population population, String shapeCategory,
+ JobDurationCalculator jobDurationCalculator) throws IOException {
Set demandInformation = readDemandInformation(csvLocationDemand);
checkNewDemand(scenario, demandInformation, indexShape, shapeCategory);
createDemandForCarriers(scenario, indexShape, demandInformation, population, combineSimilarJobs,
- crsTransformationNetworkAndShape);
+ crsTransformationNetworkAndShape, jobDurationCalculator);
}
/**
@@ -538,42 +540,45 @@ static void checkNewDemand(Scenario scenario, Set dema
/**
* Creates for every demand information the services/shipments for the carriers
*
- * @param scenario Scenario
- * @param indexShape ShpOptions.Index for the shape file
- * @param demandInformation Set with the demand information
- * @param population Population
- * @param combineSimilarJobs boolean if the jobs of the same carrier with same location and time will be combined
- * @param crsTransformationNetworkAndShape CoordinateTransformation for the network and shape file
+ * @param scenario Scenario
+ * @param indexShape ShpOptions.Index for the shape file
+ * @param demandInformation Set with the demand information
+ * @param population Population
+ * @param combineSimilarJobs boolean if the jobs of the same carrier with same location and time will be combined
+ * @param crsTransformationNetworkAndShape CoordinateTransformation for the network and shape file
+ * @param jobDurationCalculator Calculator for the job duration
*/
static void createDemandForCarriers(Scenario scenario, ShpOptions.Index indexShape,
- Set demandInformation, Population population, boolean combineSimilarJobs,
- CoordinateTransformation crsTransformationNetworkAndShape) {
+ Set demandInformation, Population population, boolean combineSimilarJobs,
+ CoordinateTransformation crsTransformationNetworkAndShape, JobDurationCalculator jobDurationCalculator) {
for (DemandInformationElement newDemandInformationElement : demandInformation) {
log.info("Create demand for carrier {}", newDemandInformationElement.getCarrierName());
if (newDemandInformationElement.getTypeOfDemand().equals("service"))
- createServices(scenario, newDemandInformationElement, indexShape, population, combineSimilarJobs,
- crsTransformationNetworkAndShape);
+ createServices(scenario, newDemandInformationElement, indexShape, population,
+ crsTransformationNetworkAndShape, jobDurationCalculator);
else if (newDemandInformationElement.getTypeOfDemand().equals("shipment"))
- createShipments(scenario, newDemandInformationElement, indexShape, population, combineSimilarJobs,
- crsTransformationNetworkAndShape);
+ createShipments(scenario, newDemandInformationElement, indexShape, population,
+ crsTransformationNetworkAndShape, jobDurationCalculator);
}
-
+ if (combineSimilarJobs)
+ combineSimilarJobs(scenario);
+ jobDurationCalculator.recalculateJobDurations(scenario);
}
/**
* Creates the services.
*
- * @param scenario Scenario
- * @param newDemandInformationElement single DemandInformationElement
- * @param indexShape ShpOptions.Index
- * @param population Population
- * @param combineSimilarJobs boolean if the jobs of the same carrier with same location and time will be combined
- * @param crsTransformationNetworkAndShape CoordinateTransformation for the network and shape file
+ * @param scenario Scenario
+ * @param newDemandInformationElement single DemandInformationElement
+ * @param indexShape ShpOptions.Index
+ * @param population Population
+ * @param crsTransformationNetworkAndShape CoordinateTransformation for the network and shape file
+ * @param jobDurationCalculator Calculator for the job duration
*/
private static void createServices(Scenario scenario, DemandInformationElement newDemandInformationElement,
- ShpOptions.Index indexShape, Population population, boolean combineSimilarJobs,
- CoordinateTransformation crsTransformationNetworkAndShape) {
+ ShpOptions.Index indexShape, Population population,
+ CoordinateTransformation crsTransformationNetworkAndShape, JobDurationCalculator jobDurationCalculator) {
int countOfLinks = 1;
int distributedDemand = 0;
@@ -643,8 +648,8 @@ else if (samplingOption.equals("changeNumberOfLocationsWithDemand")) {
Link link = findNextUsedLink(scenario, indexShape, possibleLinksForService, numberOfJobs,
areasForServiceLocations, locationsOfServices, usedServiceLocations,
possiblePersonsForService, nearestLinkPerPerson, crsTransformationNetworkAndShape, i);
- double serviceTime = newDemandInformationElement.getFirstJobElementTimePerUnit();
int demandForThisLink = 1;
+ double serviceTime = jobDurationCalculator.calculateServiceDuration(newDemandInformationElement.getFirstJobElementTimePerUnit(), demandForThisLink);
usedServiceLocations.add(link.getId().toString());
Id idNewService = Id.create(
createJobId(scenario, newDemandInformationElement, link.getId(), null),
@@ -673,13 +678,19 @@ else if (samplingOption.equals("changeNumberOfLocationsWithDemand")) {
countOfLinks++;
Carrier thisCarrier = CarriersUtils.getCarriers(scenario).getCarriers()
.get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class));
- int numberOfJobsForDemand = calculateNumberOfJobsForDemand(thisCarrier, demandForThisLink);
- for (int i = 0; i < numberOfJobsForDemand; i++) {
- int singleDemandForThisLink = demandForThisLink / numberOfJobsForDemand;
- if (i == numberOfJobsForDemand - 1)
- singleDemandForThisLink = demandForThisLink - (numberOfJobsForDemand - 1) * singleDemandForThisLink;
- double serviceTime = newDemandInformationElement.getFirstJobElementTimePerUnit()
- * singleDemandForThisLink;
+ int handledDemand = 0;
+ //the number of jobs on this link is calculated based on the available vehicles
+ double largestPossibleDemandSize = getLargestVehicleCapacity(thisCarrier);
+ while (handledDemand < demandForThisLink) {
+ int singleDemandForThisLink;
+ if (demandForThisLink - handledDemand < largestPossibleDemandSize)
+ singleDemandForThisLink = demandForThisLink - handledDemand;
+ else
+ singleDemandForThisLink = (int)largestPossibleDemandSize;
+ handledDemand = handledDemand + singleDemandForThisLink;
+ double serviceTime = jobDurationCalculator.calculateServiceDuration(
+ newDemandInformationElement.getFirstJobElementTimePerUnit(), singleDemandForThisLink);
+
Id idNewService = Id.create(
createJobId(scenario, newDemandInformationElement, link.getId(), null),
CarrierService.class);
@@ -718,16 +729,18 @@ else if (samplingOption.equals("changeNumberOfLocationsWithDemand")) {
int demandForThisLink = calculateDemandForThisLink(demandToDistribute, numberOfJobs, distributedDemand, i);
Carrier thisCarrier = CarriersUtils.getCarriers(scenario).getCarriers()
.get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class));
- int numberOfJobsForDemand = calculateNumberOfJobsForDemand(thisCarrier, demandForThisLink);
- for (int j = 0; j < numberOfJobsForDemand; j++) {
- int singleDemandForThisLink = demandForThisLink / numberOfJobsForDemand;
- if (j == numberOfJobsForDemand - 1)
- singleDemandForThisLink = demandForThisLink - (numberOfJobsForDemand - 1) * singleDemandForThisLink;
- double serviceTime;
- if (singleDemandForThisLink == 0)
- serviceTime = newDemandInformationElement.getFirstJobElementTimePerUnit();
+ int handledDemand = 0;
+ //the number of jobs on this link is calculated based on the available vehicles
+ double largestPossibleDemandSize = getLargestVehicleCapacity(thisCarrier);
+ while (handledDemand < demandForThisLink || demandToDistribute == 0) {
+ int singleDemandForThisLink;
+ if (demandForThisLink - handledDemand < largestPossibleDemandSize)
+ singleDemandForThisLink = demandForThisLink - handledDemand;
else
- serviceTime = newDemandInformationElement.getFirstJobElementTimePerUnit() * demandForThisLink;
+ singleDemandForThisLink = (int)largestPossibleDemandSize;
+ handledDemand = handledDemand + singleDemandForThisLink;
+ double serviceTime = jobDurationCalculator.calculateServiceDuration(
+ newDemandInformationElement.getFirstJobElementTimePerUnit(), singleDemandForThisLink);
usedServiceLocations.add(link.getId().toString());
Id idNewService = Id.create(
@@ -740,28 +753,28 @@ else if (samplingOption.equals("changeNumberOfLocationsWithDemand")) {
CarriersUtils.getCarriers(scenario).getCarriers()
.get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)).getServices()
.put(thisService.getId(), thisService);
+ if (demandToDistribute == 0)
+ break;
}
}
distributedDemand = distributedDemand + demandForThisLink;
}
}
- if (combineSimilarJobs)
- reduceNumberOfJobsIfSameCharacteristics(scenario, newDemandInformationElement);
}
/**
* Creates the shipments of a carrier.
*
- * @param scenario Scenario
- * @param newDemandInformationElement single DemandInformationElement
- * @param indexShape ShpOptions.Index for the shape file
- * @param population Population
- * @param combineSimilarJobs boolean if the jobs of the same carrier with same location and time will be combined
- * @param crsTransformationNetworkAndShape CoordinateTransformation for the network and shape file
+ * @param scenario Scenario
+ * @param newDemandInformationElement single DemandInformationElement
+ * @param indexShape ShpOptions.Index for the shape file
+ * @param population Population
+ * @param crsTransformationNetworkAndShape CoordinateTransformation for the network and shape file
+ * @param jobDurationCalculator Calculator for the job duration
*/
private static void createShipments(Scenario scenario, DemandInformationElement newDemandInformationElement,
- ShpOptions.Index indexShape, Population population, boolean combineSimilarJobs,
- CoordinateTransformation crsTransformationNetworkAndShape) {
+ ShpOptions.Index indexShape, Population population,
+ CoordinateTransformation crsTransformationNetworkAndShape, JobDurationCalculator jobDurationCalculator) {
int countOfLinks = 1;
int distributedDemand = 0;
@@ -900,7 +913,7 @@ else if (population == null)
if (!usedDeliveryLocations.contains(linkDelivery.getId().toString()))
usedDeliveryLocations.add(linkDelivery.getId().toString());
- createSingleShipment(scenario, newDemandInformationElement, linkPickup, linkDelivery, demandForThisLink);
+ createSingleShipment(scenario, newDemandInformationElement, linkPickup, linkDelivery, demandForThisLink, jobDurationCalculator);
}
} else
// creates a demand on each link, demand depends on the length of the link
@@ -968,7 +981,7 @@ else if (numberOfPickupLocations != null) {
if (demandForThisLink > 0) {
createSingleShipment(scenario, newDemandInformationElement, linkPickup, linkDelivery,
- demandForThisLink);
+ demandForThisLink, jobDurationCalculator);
}
distributedDemand = distributedDemand + demandForThisLink;
}
@@ -998,52 +1011,52 @@ else if (numberOfPickupLocations != null) {
usedDeliveryLocations.add(linkDelivery.getId().toString());
createSingleShipment(scenario, newDemandInformationElement, linkPickup, linkDelivery,
- demandForThisLink);
+ demandForThisLink, jobDurationCalculator);
distributedDemand = distributedDemand + demandForThisLink;
}
}
- if (combineSimilarJobs)
- reduceNumberOfJobsIfSameCharacteristics(scenario, newDemandInformationElement);
}
- /** Creates a single shipment.
+ /**
+ * Creates a single shipment.
+ *
* @param scenario Scenario
* @param newDemandInformationElement single DemandInformationElement
* @param linkPickup Link for the pickup
* @param linkDelivery Link for the delivery
* @param demandForThisLink Demand for this link
+ * @param jobDurationCalculator Calculator for the job duration
*/
private static void createSingleShipment(Scenario scenario, DemandInformationElement newDemandInformationElement,
- Link linkPickup, Link linkDelivery, int demandForThisLink) {
+ Link linkPickup, Link linkDelivery, int demandForThisLink, JobDurationCalculator jobDurationCalculator) {
Carrier thisCarrier = CarriersUtils.getCarriers(scenario).getCarriers()
.get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class));
- int numberOfJobsForDemand = calculateNumberOfJobsForDemand(thisCarrier, demandForThisLink);
-
+ double largestPossibleDemandSize = getLargestVehicleCapacity(thisCarrier);
+ int handledDemand = 0;
TimeWindow timeWindowPickup = newDemandInformationElement.getFirstJobElementTimeWindow();
TimeWindow timeWindowDelivery = newDemandInformationElement.getSecondJobElementTimeWindow();
- for (int i = 0; i < numberOfJobsForDemand; i++) {
+ while (handledDemand < demandForThisLink || demandForThisLink == 0) {
Id idNewShipment = Id.create(createJobId(scenario, newDemandInformationElement,
linkPickup.getId(), linkDelivery.getId()), CarrierShipment.class);
- double serviceTimePickup;
- double serviceTimeDelivery;
- int singleDemandForThisLink = Math.round ((float) demandForThisLink / numberOfJobsForDemand);
- if (i == numberOfJobsForDemand - 1)
- singleDemandForThisLink = demandForThisLink - (numberOfJobsForDemand - 1) * singleDemandForThisLink;
- if (singleDemandForThisLink == 0) {
- serviceTimePickup = newDemandInformationElement.getFirstJobElementTimePerUnit();
- serviceTimeDelivery = newDemandInformationElement.getSecondJobElementTimePerUnit();
- } else {
- serviceTimePickup = newDemandInformationElement.getFirstJobElementTimePerUnit() * singleDemandForThisLink;
- serviceTimeDelivery = newDemandInformationElement.getSecondJobElementTimePerUnit() * singleDemandForThisLink;
- }
+ int singleDemandForThisLink;
+ if (demandForThisLink - handledDemand < largestPossibleDemandSize)
+ singleDemandForThisLink = demandForThisLink - handledDemand;
+ else
+ singleDemandForThisLink = (int)largestPossibleDemandSize;
+ handledDemand = handledDemand + singleDemandForThisLink;
+ double serviceTimePickup = jobDurationCalculator.calculatePickupDuration(newDemandInformationElement.getFirstJobElementTimePerUnit(), singleDemandForThisLink);
+ double serviceTimeDelivery = jobDurationCalculator.calculateDeliveryDuration(newDemandInformationElement.getSecondJobElementTimePerUnit(), singleDemandForThisLink);
+
CarrierShipment thisShipment = CarrierShipment.Builder
.newInstance(idNewShipment, linkPickup.getId(), linkDelivery.getId(), singleDemandForThisLink)
.setPickupServiceTime(serviceTimePickup).setPickupTimeWindow(timeWindowPickup)
.setDeliveryServiceTime(serviceTimeDelivery).setDeliveryTimeWindow(timeWindowDelivery)
.build();
thisCarrier.getShipments().put(thisShipment.getId(), thisShipment);
+ if (demandForThisLink == 0)
+ break;
}
}
@@ -1051,21 +1064,16 @@ private static void createSingleShipment(Scenario scenario, DemandInformationEle
* Method calculates the number of jobs for a demand on one link based on the largest vehicle capacity of the carrier.
*
* @param thisCarrier the carrier of a job
- * @param demandForThisLink Demand for this link
* @return Number of jobs for this demand
*/
- private static int calculateNumberOfJobsForDemand(Carrier thisCarrier, int demandForThisLink) {
+ private static double getLargestVehicleCapacity(Carrier thisCarrier) {
double largestVehicleCapacity = 0;
for (CarrierVehicle vehicle : thisCarrier.getCarrierCapabilities().getCarrierVehicles().values()) {
if (vehicle.getType().getCapacity().getOther() > largestVehicleCapacity) {
largestVehicleCapacity = vehicle.getType().getCapacity().getOther();
}
}
- if (demandForThisLink > largestVehicleCapacity) {
- log.info("Demand {} is larger than the largest vehicle capacity ({}). Splitting demand into multiple jobs.", demandForThisLink, largestVehicleCapacity);
- return (int) Math.ceil((double) demandForThisLink / largestVehicleCapacity);
- }
- return 1;
+ return largestVehicleCapacity;
}
/**
@@ -1160,109 +1168,102 @@ private static int calculateDemandBasedOnLinkLength(int countOfLinks, int distri
* If jobs of a carrier have the same characteristics (time window, location),
* they will be combined to one job.
*
- * @param scenario Scenario
- * @param newDemandInformationElement single DemandInformationElement
+ * @param scenario Scenario
*/
- private static void reduceNumberOfJobsIfSameCharacteristics(Scenario scenario,
- DemandInformationElement newDemandInformationElement) {
+ private static void combineSimilarJobs(Scenario scenario) {
log.warn(
"The number of Jobs will be reduced if jobs have the same characteristics (e.g. time, location, carrier)");
- int connectedJobs = 0;
- if (newDemandInformationElement.getTypeOfDemand().equals("shipment")) {
- HashMap, CarrierShipment> shipmentsToRemove = new HashMap<>();
- ArrayList shipmentsToAdd = new ArrayList<>();
- Carrier thisCarrier = CarriersUtils.getCarriers(scenario).getCarriers()
- .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class));
- for (Id baseShipmentId : thisCarrier.getShipments().keySet()) {
- if (!shipmentsToRemove.containsKey(baseShipmentId)) {
- CarrierShipment baseShipment = thisCarrier.getShipments().get(baseShipmentId);
- HashMap, CarrierShipment> shipmentsToConnect = new HashMap<>();
- shipmentsToConnect.put(baseShipmentId, baseShipment);
- for (Id thisShipmentId : thisCarrier.getShipments().keySet()) {
- if (!shipmentsToRemove.containsKey(thisShipmentId)) {
- CarrierShipment thisShipment = thisCarrier.getShipments().get(thisShipmentId);
- if (baseShipment.getId() != thisShipment.getId()
+ for (Carrier thisCarrier : CarriersUtils.getCarriers(scenario).getCarriers().values()) {
+ if (!thisCarrier.getShipments().isEmpty()) {
+ int shipmentsBeforeConnection = thisCarrier.getShipments().size();
+ HashMap, CarrierShipment> shipmentsToRemove = new HashMap<>();
+ ArrayList shipmentsToAdd = new ArrayList<>();
+ for (Id baseShipmentId : thisCarrier.getShipments().keySet()) {
+ if (!shipmentsToRemove.containsKey(baseShipmentId)) {
+ CarrierShipment baseShipment = thisCarrier.getShipments().get(baseShipmentId);
+ HashMap, CarrierShipment> shipmentsToConnect = new HashMap<>();
+ shipmentsToConnect.put(baseShipmentId, baseShipment);
+ for (Id thisShipmentId : thisCarrier.getShipments().keySet()) {
+ if (!shipmentsToRemove.containsKey(thisShipmentId)) {
+ CarrierShipment thisShipment = thisCarrier.getShipments().get(thisShipmentId);
+ if (baseShipment.getId() != thisShipment.getId()
&& baseShipment.getFrom() == thisShipment.getFrom()
&& baseShipment.getTo() == thisShipment.getTo()
&& baseShipment.getPickupTimeWindow() == thisShipment.getPickupTimeWindow()
&& baseShipment.getDeliveryTimeWindow() == thisShipment.getDeliveryTimeWindow())
- shipmentsToConnect.put(thisShipmentId, thisShipment);
+ shipmentsToConnect.put(thisShipmentId, thisShipment);
+ }
}
- }
- Id idNewShipment = baseShipment.getId();
- int demandForThisLink = 0;
- double serviceTimePickup = 0;
- double serviceTimeDelivery = 0;
- for (CarrierShipment carrierShipment : shipmentsToConnect.values()) {
- demandForThisLink = demandForThisLink + carrierShipment.getSize();
- serviceTimePickup = serviceTimePickup + carrierShipment.getPickupServiceTime();
- serviceTimeDelivery = serviceTimeDelivery + carrierShipment.getDeliveryServiceTime();
- shipmentsToRemove.put(carrierShipment.getId(), carrierShipment);
- connectedJobs++;
- }
- CarrierShipment newShipment = CarrierShipment.Builder
+ Id idNewShipment = baseShipment.getId();
+ int demandForThisLink = 0;
+ double serviceTimePickup = 0;
+ double serviceTimeDelivery = 0;
+ for (CarrierShipment carrierShipment : shipmentsToConnect.values()) {
+ demandForThisLink = demandForThisLink + carrierShipment.getSize();
+ serviceTimePickup = serviceTimePickup + carrierShipment.getPickupServiceTime();
+ serviceTimeDelivery = serviceTimeDelivery + carrierShipment.getDeliveryServiceTime();
+ shipmentsToRemove.put(carrierShipment.getId(), carrierShipment);
+ }
+ CarrierShipment newShipment = CarrierShipment.Builder
.newInstance(idNewShipment, baseShipment.getFrom(), baseShipment.getTo(), demandForThisLink)
.setPickupServiceTime(serviceTimePickup)
.setPickupTimeWindow(baseShipment.getPickupTimeWindow())
.setDeliveryServiceTime(serviceTimeDelivery)
.setDeliveryTimeWindow(baseShipment.getDeliveryTimeWindow()).build();
+ shipmentsToAdd.add(newShipment);
+ }
+ }
+ for (CarrierShipment id : shipmentsToRemove.values())
+ thisCarrier.getShipments().remove(id.getId(), id);
- shipmentsToAdd.add(newShipment);
- connectedJobs++;
+ for (CarrierShipment carrierShipment : shipmentsToAdd) {
+ thisCarrier.getShipments().put(carrierShipment.getId(), carrierShipment);
}
- }
- for (CarrierShipment id : shipmentsToRemove.values())
- thisCarrier.getShipments().remove(id.getId(), id);
- for (CarrierShipment carrierShipment : shipmentsToAdd) {
- thisCarrier.getShipments().put(carrierShipment.getId(), carrierShipment);
+ log.warn("Number of reduced shipments for carrier {}: {}", thisCarrier.getId().toString(), shipmentsBeforeConnection - thisCarrier.getShipments().size());
}
- log.warn("Number of reduced shipments: {}", connectedJobs);
- }
- if (newDemandInformationElement.getTypeOfDemand().equals("service")) {
- HashMap, CarrierService> servicesToRemove = new HashMap<>();
- ArrayList servicesToAdd = new ArrayList<>();
- Carrier thisCarrier = CarriersUtils.getCarriers(scenario).getCarriers()
- .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class));
- for (Id baseServiceId : thisCarrier.getServices().keySet()) {
- if (!servicesToRemove.containsKey(baseServiceId)) {
- CarrierService baseService = thisCarrier.getServices().get(baseServiceId);
- HashMap, CarrierService> servicesToConnect = new HashMap<>();
- servicesToConnect.put(baseServiceId, baseService);
- for (Id thisServiceId : thisCarrier.getServices().keySet()) {
- if (!servicesToRemove.containsKey(thisServiceId)) {
- CarrierService thisService = thisCarrier.getServices().get(thisServiceId);
- if (baseService.getId() != thisService.getId()
+ if (!thisCarrier.getServices().isEmpty()) {
+ int servicesBeforeConnection = thisCarrier.getServices().size();
+ HashMap, CarrierService> servicesToRemove = new HashMap<>();
+ ArrayList servicesToAdd = new ArrayList<>();
+ for (Id baseServiceId : thisCarrier.getServices().keySet()) {
+ if (!servicesToRemove.containsKey(baseServiceId)) {
+ CarrierService baseService = thisCarrier.getServices().get(baseServiceId);
+ HashMap, CarrierService> servicesToConnect = new HashMap<>();
+ servicesToConnect.put(baseServiceId, baseService);
+ for (Id thisServiceId : thisCarrier.getServices().keySet()) {
+ if (!servicesToRemove.containsKey(thisServiceId)) {
+ CarrierService thisService = thisCarrier.getServices().get(thisServiceId);
+ if (baseService.getId() != thisService.getId()
&& baseService.getLocationLinkId() == thisService.getLocationLinkId() && baseService
- .getServiceStartTimeWindow() == thisService.getServiceStartTimeWindow())
- servicesToConnect.put(thisServiceId, thisService);
+ .getServiceStartTimeWindow() == thisService.getServiceStartTimeWindow())
+ servicesToConnect.put(thisServiceId, thisService);
+ }
}
- }
- Id idNewService = baseService.getId();
- int demandForThisLink = 0;
- double serviceTimeService = 0;
- for (CarrierService carrierService : servicesToConnect.values()) {
- demandForThisLink = demandForThisLink + carrierService.getCapacityDemand();
- serviceTimeService = serviceTimeService + carrierService.getServiceDuration();
- servicesToRemove.put(carrierService.getId(), carrierService);
- connectedJobs++;
- }
- CarrierService newService = CarrierService.Builder
+ Id idNewService = baseService.getId();
+ int demandForThisLink = 0;
+ double serviceTimeService = 0;
+ for (CarrierService carrierService : servicesToConnect.values()) {
+ demandForThisLink = demandForThisLink + carrierService.getCapacityDemand();
+ serviceTimeService = serviceTimeService + carrierService.getServiceDuration();
+ servicesToRemove.put(carrierService.getId(), carrierService);
+ }
+ CarrierService newService = CarrierService.Builder
.newInstance(idNewService, baseService.getLocationLinkId())
.setServiceDuration(serviceTimeService)
.setServiceStartTimeWindow(baseService.getServiceStartTimeWindow())
.setCapacityDemand(demandForThisLink).build();
- servicesToAdd.add(newService);
- connectedJobs++;
+ servicesToAdd.add(newService);
+ }
}
+ for (CarrierService id : servicesToRemove.values())
+ thisCarrier.getServices().remove(id.getId(), id);
+ for (CarrierService carrierService : servicesToAdd) {
+ thisCarrier.getServices().put(carrierService.getId(), carrierService);
+ }
+ log.warn("Number of reduced services for carrier {}: {}", thisCarrier.getId().toString(), servicesBeforeConnection - thisCarrier.getServices().size());
}
- for (CarrierService id : servicesToRemove.values())
- thisCarrier.getServices().remove(id.getId(), id);
- for (CarrierService carrierService : servicesToAdd) {
- thisCarrier.getServices().put(carrierService.getId(), carrierService);
- }
- log.warn("Number of reduced shipments: {}", connectedJobs);
}
}
diff --git a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java
index 368dddaad69..d01a6226691 100644
--- a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java
+++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java
@@ -37,8 +37,8 @@
import org.matsim.core.scenario.ScenarioUtils;
import org.matsim.core.utils.geometry.CoordinateTransformation;
import org.matsim.freight.carriers.*;
-import org.matsim.freight.carriers.controler.CarrierModule;
-import org.matsim.freight.carriers.controler.CarrierScoringFunctionFactory;
+import org.matsim.freight.carriers.controller.CarrierModule;
+import org.matsim.freight.carriers.controller.CarrierScoringFunctionFactory;
import org.matsim.freight.carriers.usecases.chessboard.CarrierScoringFunctionFactoryImpl;
import picocli.CommandLine;
@@ -62,6 +62,8 @@
+ " * these files are given in the example project. See: TODO", showDefaultValues = true)
public class FreightDemandGeneration implements MATSimAppCommand {
+ private final JobDurationCalculator jobDurationCalculator;
+
private enum CarrierInputOptions {
readCarrierFile, createCarriersFromCSV, addCSVDataToExistingCarrierFileData
}
@@ -154,6 +156,16 @@ private enum OptionsOfVRPSolutions {
@CommandLine.Option(names = "--defaultJspritIterations", description = "Set the default number of jsprit iterations.")
private int defaultJspritIterations;
+ public FreightDemandGeneration() {
+ this.jobDurationCalculator = new DefaultJobDurationCalculator();
+ log.info("Using default {} for job duration calculation", jobDurationCalculator.getClass().getSimpleName());
+ }
+
+ public FreightDemandGeneration(JobDurationCalculator jobDurationCalculator) {
+ this.jobDurationCalculator = jobDurationCalculator;
+ log.info("Using {} for job duration calculation", jobDurationCalculator.getClass().getSimpleName());
+ }
+
public static void main(String[] args) {
System.exit(new CommandLine(new FreightDemandGeneration()).execute(args));
}
@@ -353,7 +365,7 @@ private void createDemand(DemandGenerationOptions selectedDemandGenerationOption
case createDemandFromCSV ->
// creates the demand by using the information given in the read csv file
DemandReaderFromCSV.readAndCreateDemand(scenario, csvLocationDemand, indexShape, combineSimilarJobs,
- crsTransformationNetworkAndShape, null, shapeCategory);
+ crsTransformationNetworkAndShape, null, shapeCategory, jobDurationCalculator);
case createDemandFromCSVAndUsePopulation -> {
/*
* Option creates the demand by using the information given in the read csv file
@@ -399,14 +411,14 @@ private void createDemand(DemandGenerationOptions selectedDemandGenerationOption
case useHolePopulation:
// uses the hole population as possible demand locations
DemandReaderFromCSV.readAndCreateDemand(scenario, csvLocationDemand, indexShape,
- combineSimilarJobs, crsTransformationNetworkAndShape, population, shapeCategory);
+ combineSimilarJobs, crsTransformationNetworkAndShape, population, shapeCategory, jobDurationCalculator);
break;
case usePopulationInShape:
// uses only the population with home location in the given shape file
FreightDemandGenerationUtils.reducePopulationToShapeArea(population,
shp.createIndex(populationCRS, "_"));
DemandReaderFromCSV.readAndCreateDemand(scenario, csvLocationDemand, indexShape,
- combineSimilarJobs, crsTransformationNetworkAndShape, population, shapeCategory);
+ combineSimilarJobs, crsTransformationNetworkAndShape, population, shapeCategory, jobDurationCalculator);
break;
default:
throw new RuntimeException("No valid population option selected!");
diff --git a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGenerationUtils.java b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGenerationUtils.java
index c60a8a39390..ede28ace76d 100644
--- a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGenerationUtils.java
+++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGenerationUtils.java
@@ -152,7 +152,7 @@ static void createDemandLocationsFile(Controler controler) {
writer.flush();
} catch (IOException e) {
- e.printStackTrace();
+ log.error("Could not write job locations file under " + "/outputLocationFile.xml.gz");
}
log.info("Wrote job locations file under " + "/outputLocationFile.xml.gz");
}
diff --git a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/JobDurationCalculator.java b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/JobDurationCalculator.java
new file mode 100644
index 00000000000..85d30908fa0
--- /dev/null
+++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/JobDurationCalculator.java
@@ -0,0 +1,39 @@
+package org.matsim.freightDemandGeneration;
+
+import org.matsim.api.core.v01.Scenario;
+
+public interface JobDurationCalculator {
+ /**
+ * Calculates the duration of a service in seconds.
+ *
+ * @param serviceDurationPerUnit in seconds
+ * @param demandForThisService amount of demand for this service
+ * @return duration in seconds
+ */
+ double calculateServiceDuration(Integer serviceDurationPerUnit, int demandForThisService);
+
+ /**
+ * Calculates the duration of a pickup in seconds.
+ *
+ * @param pickupDurationPerUnit in seconds
+ * @param demandForThisShipment amount of demand for this shipment
+ * @return duration in seconds
+ */
+ double calculatePickupDuration(Integer pickupDurationPerUnit, int demandForThisShipment);
+
+ /**
+ * Calculates the duration of a delivery in seconds.
+ *
+ * @param deliveryDurationPerUnit in seconds
+ * @param demandForThisShipment amount of demand for this shipment
+ * @return duration in seconds
+ */
+ double calculateDeliveryDuration(Integer deliveryDurationPerUnit, int demandForThisShipment);
+
+ /**
+ * Recalculates the job durations for all jobs in the scenario. The devault implementation does nothing.
+ *
+ * @param scenario scenario
+ */
+ void recalculateJobDurations(Scenario scenario);
+}
diff --git a/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java b/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java
index c27b251afc4..9cd21c16d9d 100644
--- a/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java
+++ b/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java
@@ -79,10 +79,10 @@ void demandCreationWithSampleWithChangeNumberOfLocations() throws IOException {
String populationLocation = utils.getPackageInputDirectory() + "testPopulation.xml";
Population population = PopulationUtils.readPopulation(populationLocation);
FreightDemandGenerationUtils.preparePopulation(population, 0.5, 1.0, "changeNumberOfLocationsWithDemand");
-
+ Boolean combineSimilarJobs = false;
// run methods
createDemandAndCheckCarrier(carrierCSVLocation, scenario, freightCarriersConfigGroup, indexShape, demandCSVLocation, shapeCategory,
- population);
+ population, combineSimilarJobs);
Network network = scenario.getNetwork();
@@ -147,10 +147,11 @@ void demandCreationWithSampleWithDemandOnLocation() throws IOException {
String populationLocation = utils.getPackageInputDirectory() + "testPopulation.xml";
Population population = PopulationUtils.readPopulation(populationLocation);
FreightDemandGenerationUtils.preparePopulation(population, 0.5, 1.0, "changeDemandOnLocation");
+ Boolean combineSimilarJobs = false;
- createDemandAndCheckCarrier(carrierCSVLocation, scenario, freightCarriersConfigGroup, indexShape, demandCSVLocation, shapeCategory, population);
+ createDemandAndCheckCarrier(carrierCSVLocation, scenario, freightCarriersConfigGroup, indexShape, demandCSVLocation, shapeCategory,
+ population, combineSimilarJobs);
- // check carrier 1
Network network = scenario.getNetwork();
checkCarrier1and2(scenario, network, indexShape);
@@ -194,6 +195,74 @@ void demandCreationWithSampleWithDemandOnLocation() throws IOException {
}
}
+ @Test
+ void demandCreationWithSampleWithDemandOnLocationWithCombiningJobs() throws IOException {
+ // read inputs
+ Config config = ConfigUtils.createConfig();
+ config.network().setInputFile(
+ "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml");
+ Scenario scenario = ScenarioUtils.loadScenario(config);
+ FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(scenario.getConfig(),
+ FreightCarriersConfigGroup.class);
+ freightCarriersConfigGroup.setCarriersVehicleTypesFile(utils.getPackageInputDirectory() + "testVehicleTypes.xml");
+ Path carrierCSVLocation = Path.of(utils.getPackageInputDirectory() + "testCarrierCSV.csv");
+ Path demandCSVLocation = Path.of(utils.getPackageInputDirectory() + "testDemandCSV.csv");
+ Path shapeFilePath = Path.of(utils.getPackageInputDirectory() + "testShape/testShape.shp");
+ ShpOptions shp = new ShpOptions(shapeFilePath, "WGS84", null);
+ String shapeCategory = "Ortsteil";
+ ShpOptions.Index indexShape = shp.createIndex("Ortsteil");
+ String populationLocation = utils.getPackageInputDirectory() + "testPopulation.xml";
+ Population population = PopulationUtils.readPopulation(populationLocation);
+ FreightDemandGenerationUtils.preparePopulation(population, 0.5, 1.0, "changeDemandOnLocation");
+ Boolean combineSimilarJobs = true;
+
+ createDemandAndCheckCarrier(carrierCSVLocation, scenario, freightCarriersConfigGroup, indexShape, demandCSVLocation, shapeCategory,
+ population, combineSimilarJobs);
+
+ Network network = scenario.getNetwork();
+
+ checkCarrier1and2WithCombiningJobs(scenario, network, indexShape);
+ int countDemand;
+ Object2IntMap countShipmentsWithCertainDemand;
+ Map> locationsPerShipmentElement;
+
+ // check carrier 3
+ Carrier testCarrier3 = CarriersUtils.getCarriers(scenario).getCarriers()
+ .get(Id.create("testCarrier3", Carrier.class));
+ Assertions.assertEquals(0, testCarrier3.getServices().size());
+ Assertions.assertEquals(2, testCarrier3.getShipments().size());
+ countShipmentsWithCertainDemand = new Object2IntOpenHashMap<>();
+ locationsPerShipmentElement = new HashMap<>();
+ countDemand = 0;
+ for (CarrierShipment shipment : testCarrier3.getShipments().values()) {
+ countShipmentsWithCertainDemand.merge((Integer) shipment.getSize(), 1, Integer::sum);
+ countDemand = countDemand + shipment.getSize();
+ Assertions.assertEquals(10, shipment.getSize());
+ Assertions.assertEquals(4000, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON);
+ Assertions.assertEquals(2500, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON);
+ Assertions.assertEquals(TimeWindow.newInstance(8000, 50000), shipment.getPickupTimeWindow());
+ Assertions.assertEquals(TimeWindow.newInstance(10000, 60000), shipment.getDeliveryTimeWindow());
+ locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_pickup", (k) -> new HashSet<>())
+ .add(shipment.getFrom().toString());
+ locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_delivery", (k) -> new HashSet<>())
+ .add(shipment.getTo().toString());
+ }
+ Assertions.assertEquals(20, countDemand);
+ Assertions.assertEquals(2, countShipmentsWithCertainDemand.getInt(10));
+ Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmentElement1_pickup").size());
+ Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmentElement1_delivery").size());
+ for (String locationsOfShipmentElement : locationsPerShipmentElement.get("ShipmentElement1_delivery")) {
+ Link link = network.getLinks().get(Id.createLinkId(locationsOfShipmentElement));
+ Assertions.assertTrue(
+ FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, null, null));
+ Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape,
+ new String[] { "area1" }, null));
+ Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape,
+ new String[] { "area2" }, null));
+ }
+ }
+
+
@Test
void demandCreationNoSampling() throws IOException {
// read inputs
@@ -213,10 +282,11 @@ void demandCreationNoSampling() throws IOException {
String populationLocation = utils.getPackageInputDirectory() + "testPopulation.xml";
Population population = PopulationUtils.readPopulation(populationLocation);
FreightDemandGenerationUtils.preparePopulation(population, 0.5, 0.5, "changeDemandOnLocation");
+ Boolean combineSimilarJobs = false;
// run methods
createDemandAndCheckCarrier(carrierCSVLocation, scenario, freightCarriersConfigGroup, indexShape, demandCSVLocation, shapeCategory,
- population);
+ population, combineSimilarJobs);
// check carrier 1
Network network = scenario.getNetwork();
@@ -367,7 +437,8 @@ void csvDemandReader() throws IOException {
private static void createDemandAndCheckCarrier(Path carrierCSVLocation, Scenario scenario, FreightCarriersConfigGroup freightCarriersConfigGroup,
ShpOptions.Index indexShape, Path demandCSVLocation, String shapeCategory,
- Population population) throws IOException {
+ Population population, Boolean combineSimilarJobs) throws IOException {
+ JobDurationCalculator jobDurationCalculator = new DefaultJobDurationCalculator();
// run methods
Set allNewCarrierInformation = CarrierReaderFromCSV
.readCarrierInformation(carrierCSVLocation);
@@ -375,8 +446,8 @@ private static void createDemandAndCheckCarrier(Path carrierCSVLocation, Scenari
indexShape, 1, null);
Set demandInformation = DemandReaderFromCSV.readDemandInformation(demandCSVLocation);
DemandReaderFromCSV.checkNewDemand(scenario, demandInformation, indexShape, shapeCategory);
- DemandReaderFromCSV.createDemandForCarriers(scenario, indexShape, demandInformation, population, false,
- null);
+ DemandReaderFromCSV.createDemandForCarriers(scenario, indexShape, demandInformation, population, combineSimilarJobs,
+ null, jobDurationCalculator);
Assertions.assertEquals(3, CarriersUtils.getCarriers(scenario).getCarriers().size());
Assertions.assertTrue(
CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier1", Carrier.class)));
@@ -491,4 +562,89 @@ private static void checkCarrier1and2(Scenario scenario, Network network, ShpOpt
Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmentElement2_pickup").size());
Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmentElement2_delivery").size());
}
+
+ /**
+ * Results after combing jobs.
+ *
+ * @param scenario the scenario
+ * @param network the network
+ * @param indexShape the index of the shape
+ */
+ private static void checkCarrier1and2WithCombiningJobs(Scenario scenario, Network network, ShpOptions.Index indexShape) {
+ Carrier testCarrier1 = CarriersUtils.getCarriers(scenario).getCarriers()
+ .get(Id.create("testCarrier1", Carrier.class));
+ Assertions.assertEquals(8, testCarrier1.getServices().size());
+ Assertions.assertEquals(0, testCarrier1.getShipments().size());
+ Object2IntMap countServicesWithCertainDemand = new Object2IntOpenHashMap<>();
+ Map> locationsPerServiceElement = new HashMap<>();
+ int countDemand = 0;
+ for (CarrierService service : testCarrier1.getServices().values()) {
+ countServicesWithCertainDemand.merge((Integer) service.getCapacityDemand(), 1, Integer::sum);
+ countDemand = countDemand + service.getCapacityDemand();
+ if (service.getCapacityDemand() == 0) {
+ Assertions.assertEquals(180, service.getServiceDuration(), MatsimTestUtils.EPSILON);
+ Assertions.assertEquals(TimeWindow.newInstance(3000, 13000), service.getServiceStartTimeWindow());
+ locationsPerServiceElement.computeIfAbsent("serviceElement1", (k) -> new HashSet<>())
+ .add(service.getLocationLinkId().toString());
+ } else {
+ Assertions.assertEquals(service.getCapacityDemand() * 100, service.getServiceDuration(), MatsimTestUtils.EPSILON);
+ Assertions.assertEquals(TimeWindow.newInstance(5000, 20000), service.getServiceStartTimeWindow());
+ locationsPerServiceElement.computeIfAbsent("serviceElement2", (k) -> new HashSet<>())
+ .add(service.getLocationLinkId().toString());
+ }
+ }
+ Assertions.assertEquals(12, countDemand);
+ Assertions.assertEquals(4, countServicesWithCertainDemand.getInt(0));
+ Assertions.assertEquals(4, locationsPerServiceElement.get("serviceElement1").size());
+ for (String locationsOfServiceElement : locationsPerServiceElement.get("serviceElement1")) {
+ Link link = network.getLinks().get(Id.createLinkId(locationsOfServiceElement));
+ Assertions.assertTrue(
+ FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, null, null));
+ Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape,
+ new String[] { "area1" }, null));
+ Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape,
+ new String[] { "area2" }, null));
+ }
+ Assertions.assertEquals(4, locationsPerServiceElement.get("serviceElement2").size());
+ Assertions.assertTrue(locationsPerServiceElement.get("serviceElement2").contains("i(2,0)"));
+
+ // check carrier 2
+ Carrier testCarrier2 = CarriersUtils.getCarriers(scenario).getCarriers()
+ .get(Id.create("testCarrier2", Carrier.class));
+ Assertions.assertEquals(0, testCarrier2.getServices().size());
+ Assertions.assertEquals(6, testCarrier2.getShipments().size());
+ Object2IntMap countShipmentsWithCertainDemand = new Object2IntOpenHashMap<>();
+ Map> locationsPerShipmentElement = new HashMap<>();
+ countDemand = 0;
+ for (CarrierShipment shipment : testCarrier2.getShipments().values()) {
+ countShipmentsWithCertainDemand.merge((Integer) shipment.getSize(), 1, Integer::sum);
+ countDemand = countDemand + shipment.getSize();
+ if (shipment.getSize() == 0) {
+ Assertions.assertEquals(300, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON);
+ Assertions.assertEquals(350, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON);
+ Assertions.assertEquals(TimeWindow.newInstance(10000, 45000), shipment.getPickupTimeWindow());
+ Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getDeliveryTimeWindow());
+ locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_pickup", (k) -> new HashSet<>())
+ .add(shipment.getFrom().toString());
+ locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_delivery", (k) -> new HashSet<>())
+ .add(shipment.getTo().toString());
+ } else {
+ Assertions.assertEquals(shipment.getSize() * 200, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON);
+ Assertions.assertEquals(shipment.getSize() * 200, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON);
+ Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getPickupTimeWindow());
+ Assertions.assertEquals(TimeWindow.newInstance(20000, 40000), shipment.getDeliveryTimeWindow());
+ locationsPerShipmentElement.computeIfAbsent("ShipmentElement2_pickup", (k) -> new HashSet<>())
+ .add(shipment.getFrom().toString());
+ locationsPerShipmentElement.computeIfAbsent("ShipmentElement2_delivery", (k) -> new HashSet<>())
+ .add(shipment.getTo().toString());
+ }
+ }
+ Assertions.assertEquals(15, countDemand);
+ Assertions.assertEquals(4, countShipmentsWithCertainDemand.getInt(0));
+ Assertions.assertEquals(4, locationsPerShipmentElement.get("ShipmentElement1_pickup").size());
+ Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmentElement1_delivery").size());
+ Assertions.assertTrue(locationsPerShipmentElement.get("ShipmentElement1_delivery").contains("i(2,0)"));
+ Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmentElement2_pickup").size());
+ Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmentElement2_delivery").size());
+ }
}
diff --git a/contribs/av/pom.xml b/contribs/av/pom.xml
index 1536e9e78ef..590c8f7e7a1 100644
--- a/contribs/av/pom.xml
+++ b/contribs/av/pom.xml
@@ -16,19 +16,19 @@
org.matsim.contribdvrp
- 2025.0-SNAPSHOT
+ ${project.parent.version}compileorg.matsim.contribtaxi
- 2025.0-SNAPSHOT
+ ${project.parent.version}compileorg.matsim.contribdrt
- 2025.0-SNAPSHOT
+ ${project.parent.version}compile
diff --git a/contribs/bicycle/pom.xml b/contribs/bicycle/pom.xml
index f3ffdc96601..9bd3a41df5e 100644
--- a/contribs/bicycle/pom.xml
+++ b/contribs/bicycle/pom.xml
@@ -23,7 +23,7 @@
org.matsim.contribosm
- 2025.0-SNAPSHOT
+ ${project.parent.version}compile
diff --git a/contribs/cadytsIntegration/pom.xml b/contribs/cadytsIntegration/pom.xml
index 2d4b716db7e..5fba4fc8e57 100644
--- a/contribs/cadytsIntegration/pom.xml
+++ b/contribs/cadytsIntegration/pom.xml
@@ -17,7 +17,7 @@
org.matsim.contribanalysis
- 2025.0-SNAPSHOT
+ ${project.parent.version}2012
diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/car/PlansTranslatorBasedOnEvents.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/car/PlansTranslatorBasedOnEvents.java
index 90327b37b1e..1a325f8b4fe 100644
--- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/car/PlansTranslatorBasedOnEvents.java
+++ b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/car/PlansTranslatorBasedOnEvents.java
@@ -59,8 +59,6 @@ public final class PlansTranslatorBasedOnEvents implements PlansTranslator
private int iteration = -1;
- // this is _only_ there for output:
- Set plansEverSeen = new HashSet<>();
private static final String STR_PLANSTEPFACTORY = "planStepFactory";
private static final String STR_ITERATION = "iteration";
@@ -167,9 +165,6 @@ private PlanBuilder getPlanStepFactoryForPlan(final Plan selectedPlan) {
// construct a new PlanBulder and attach it to the plan:
planStepFactory = new PlanBuilder();
selectedPlan.getCustomAttributes().put(STR_PLANSTEPFACTORY, planStepFactory);
-
- // memorize the plan as being seen:
- this.plansEverSeen.add(selectedPlan);
}
return planStepFactory;
diff --git a/contribs/carsharing/pom.xml b/contribs/carsharing/pom.xml
index 2580047b892..54eb37ac992 100644
--- a/contribs/carsharing/pom.xml
+++ b/contribs/carsharing/pom.xml
@@ -12,7 +12,7 @@
org.matsim.contribdvrp
- 2025.0-SNAPSHOT
+ ${project.parent.version}
diff --git a/contribs/commercialTrafficApplications/pom.xml b/contribs/commercialTrafficApplications/pom.xml
index 2d6f1061274..4804f34b6d9 100644
--- a/contribs/commercialTrafficApplications/pom.xml
+++ b/contribs/commercialTrafficApplications/pom.xml
@@ -14,13 +14,13 @@
org.matsim.contribfreight
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribdrt
- 2025.0-SNAPSHOT
+ ${project.parent.version}
diff --git a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TestScenarioGeneration.java b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TestScenarioGeneration.java
index 1d6b845a665..601038f2f73 100644
--- a/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TestScenarioGeneration.java
+++ b/contribs/commercialTrafficApplications/src/test/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TestScenarioGeneration.java
@@ -126,8 +126,6 @@ private static CarrierVehicle getLightVehicle(Id> id, VehicleType type, Id zones = new IdMap<>(Zone.class);
- private final IdMap> zoneToLinksMap = new IdMap<>(Zone.class);
+ private final Map> index2Links;
private final Network network;
@@ -76,6 +77,7 @@ public SquareGridZoneSystem(Network network, double cellSize, boolean filterByNe
this.rows = Math.max(1, (int) Math.ceil((maxY - minY) / cellSize));
this.cols = Math.max(1, (int)Math.ceil((maxX - minX) / cellSize));
this.internalZones = new Zone[rows * cols +1];
+ this.index2Links = getIndexToLink(network);
if(filterByNetwork) {
network.getLinks().values().forEach(l -> getOrCreateZone(l.getToNode().getCoord()));
@@ -111,7 +113,7 @@ public Optional getZoneForCoord(Coord coord) {
@Override
public List getLinksForZoneId(Id zone) {
- return zoneToLinksMap.get(zone);
+ return this.index2Links.get(Integer.parseInt(zone.toString()));
}
private Optional getOrCreateZone(Coord coord) {
@@ -126,13 +128,6 @@ private Optional getOrCreateZone(Coord coord) {
if(zoneFilter.test(zone)) {
internalZones[index] = zone;
zones.put(zone.getId(), zone);
-
- for (Link link : network.getLinks().values()) {
- if (getIndex(link.getToNode().getCoord()) == index) {
- List links = zoneToLinksMap.computeIfAbsent(zone.getId(), zoneId -> new ArrayList<>());
- links.add(link);
- }
- }
} else {
return Optional.empty();
}
@@ -140,6 +135,11 @@ private Optional getOrCreateZone(Coord coord) {
return Optional.of(zone);
}
+ private Map> getIndexToLink(Network network) {
+ return network.getLinks().values().stream()
+ .collect(Collectors.groupingBy(link -> getIndex(link.getToNode().getCoord())));
+ }
+
private PreparedPolygon getGeometry(int r, int c) {
List coords = new ArrayList<>();
coords.add(new Coord(minX + c * cellSize, minY + r * cellSize));
diff --git a/contribs/decongestion/pom.xml b/contribs/decongestion/pom.xml
index 62d2f912040..992bd7c6a12 100644
--- a/contribs/decongestion/pom.xml
+++ b/contribs/decongestion/pom.xml
@@ -8,7 +8,7 @@
org.matsim.contribotfvis
- ${parent.version}
+ ${project.parent.version}test
diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/DeterminismTest.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/DeterminismTest.java
new file mode 100644
index 00000000000..bebc456de8f
--- /dev/null
+++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/DeterminismTest.java
@@ -0,0 +1,55 @@
+package org.matsim.contrib.discrete_mode_choice;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.jupiter.api.Test;
+import org.matsim.api.core.v01.Scenario;
+import org.matsim.contribs.discrete_mode_choice.modules.DiscreteModeChoiceModule;
+import org.matsim.contribs.discrete_mode_choice.modules.ModeAvailabilityModule;
+import org.matsim.contribs.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup;
+import org.matsim.core.config.Config;
+import org.matsim.core.config.ConfigUtils;
+import org.matsim.core.controler.Controler;
+import org.matsim.core.controler.OutputDirectoryHierarchy;
+import org.matsim.core.gbl.MatsimRandom;
+import org.matsim.core.scenario.ScenarioUtils;
+import org.matsim.core.utils.io.IOUtils;
+import org.matsim.core.utils.misc.CRCChecksum;
+import org.matsim.examples.ExamplesUtils;
+
+import java.net.URL;
+
+public class DeterminismTest {
+ private static void runConfig(URL configUrl, String outputDirectory) {
+ Config config = ConfigUtils.loadConfig(configUrl, new DiscreteModeChoiceConfigGroup());
+ config.controller().setLastIteration(2);
+ config.controller().setOutputDirectory(outputDirectory);
+ config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists);
+ Scenario scenario = ScenarioUtils.createScenario(config);
+ ScenarioUtils.loadScenario(scenario);
+ Controler controler = new Controler(scenario);
+ controler.addOverridingModule(new DiscreteModeChoiceModule());
+ controler.addOverridingModule(new ModeAvailabilityModule());
+ controler.run();
+ }
+
+
+ @Test
+ public void testSimulationDeterminism() {
+ Logger logger = LogManager.getLogger(DeterminismTest.class);
+ logger.info("Testing simulation determinism");
+ URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("siouxfalls-2014"), "config_default.xml");
+ int samples = 10;
+ for(int i=0; iorg.matsim.contribdrt
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribev
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribinformed-mode-choice
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribsimwrapper
- 2025.0-SNAPSHOT
+ ${project.parent.version}
@@ -45,7 +45,7 @@
org.matsim.contribvsp
- 2025.0-SNAPSHOT
+ ${project.parent.version}test
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/dashboards/DrtDashboard.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/dashboards/DrtDashboard.java
index 6131d9f0edd..d20c0192c3e 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/dashboards/DrtDashboard.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/dashboards/DrtDashboard.java
@@ -134,7 +134,7 @@ public void configure(Header header, Layout layout) {
viz.title = "Spatial rejection distribution";
viz.description = "Requested (and rejected) origins and destinations.";
viz.projection = this.crs;
- viz.file = data.output("ITERS/it." + lastIteration + "/*rejections_" + drtConfigGroup.mode + ".csv");
+ viz.file = data.output("*rejections_" + drtConfigGroup.mode + ".csv");
viz.addAggregation("rejections", "origins", "fromX", "fromY", "destinations", "toX", "toY");
viz.center = data.context().getCenter();
@@ -222,7 +222,7 @@ public void configure(Header header, Layout layout) {
.el(Area.class, (viz, data) -> {
viz.title = "Vehicle occupancy"; //actually, without title the area plot won't work
viz.description = "Number of passengers on board at a time";
- viz.dataset = data.output("ITERS/it." + lastIteration + "/*occupancy_time_profiles_" + drtConfigGroup.mode + ".txt");
+ viz.dataset = data.output("/*occupancy_time_profiles_" + drtConfigGroup.mode + ".txt");
viz.x = "time";
viz.xAxisName = "Time";
viz.yAxisName = "Vehicles [1]";
diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java
index 120cff4f5a3..1c46945920b 100644
--- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java
+++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java
@@ -139,7 +139,7 @@ void test() {
config.controller().setWriteEventsInterval(1);
config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists);
- config.controller().setOutputDirectory("test/output/holzkirchen_shifts");
+ config.controller().setOutputDirectory("test/output/RunFissDrtScenarioIT");
DrtOperationsParams operationsParams = (DrtOperationsParams) drtWithShiftsConfigGroup.createParameterSet(DrtOperationsParams.SET_NAME);
ShiftsParams shiftsParams = (ShiftsParams) operationsParams.createParameterSet(ShiftsParams.SET_NAME);
diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunPrebookingShiftDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunPrebookingShiftDrtScenarioIT.java
index 01f5e27b837..61e3a64a97a 100644
--- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunPrebookingShiftDrtScenarioIT.java
+++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunPrebookingShiftDrtScenarioIT.java
@@ -71,7 +71,7 @@ void testWithReattempts() {
MultiModeDrtConfigGroup multiModeDrtConfigGroup = new MultiModeDrtConfigGroup(DrtWithExtensionsConfigGroup::new);
DrtWithExtensionsConfigGroup drtWithShiftsConfigGroup = (DrtWithExtensionsConfigGroup) multiModeDrtConfigGroup.createParameterSet("drt");
- final Controler run = prepare(drtWithShiftsConfigGroup, multiModeDrtConfigGroup);
+ final Controler run = prepare(drtWithShiftsConfigGroup, multiModeDrtConfigGroup, "_testWithReattempts");
Multiset> submittedPersons = HashMultiset.create();
Multiset> scheduledPersons = HashMultiset.create();
@@ -125,7 +125,7 @@ void testWithoutReattempts() {
MultiModeDrtConfigGroup multiModeDrtConfigGroup = new MultiModeDrtConfigGroup(DrtWithExtensionsConfigGroup::new);
DrtWithExtensionsConfigGroup drtWithShiftsConfigGroup = (DrtWithExtensionsConfigGroup) multiModeDrtConfigGroup.createParameterSet("drt");
- final Controler run = prepare(drtWithShiftsConfigGroup, multiModeDrtConfigGroup);
+ final Controler run = prepare(drtWithShiftsConfigGroup, multiModeDrtConfigGroup, "_testWithoutReattempts");
Multiset> submittedPersons = HashMultiset.create();
Multiset> scheduledPersons = HashMultiset.create();
@@ -175,7 +175,7 @@ public void install() {
}
@NotNull
- private Controler prepare(DrtWithExtensionsConfigGroup drtWithShiftsConfigGroup, MultiModeDrtConfigGroup multiModeDrtConfigGroup) {
+ private Controler prepare(DrtWithExtensionsConfigGroup drtWithShiftsConfigGroup, MultiModeDrtConfigGroup multiModeDrtConfigGroup, String outputSuffix) {
drtWithShiftsConfigGroup.mode = TransportMode.drt;
DefaultDrtOptimizationConstraintsSet defaultConstraintsSet =
(DefaultDrtOptimizationConstraintsSet) drtWithShiftsConfigGroup.addOrGetDrtOptimizationConstraintsParams()
@@ -245,7 +245,7 @@ private Controler prepare(DrtWithExtensionsConfigGroup drtWithShiftsConfigGroup,
config.controller().setWriteEventsInterval(1);
config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists);
- config.controller().setOutputDirectory("test/output/prebooking_shifts");
+ config.controller().setOutputDirectory("test/output/prebooking_shifts"+outputSuffix);
DrtOperationsParams operationsParams = (DrtOperationsParams) drtWithShiftsConfigGroup.createParameterSet(DrtOperationsParams.SET_NAME);
ShiftsParams shiftsParams = (ShiftsParams) operationsParams.createParameterSet(ShiftsParams.SET_NAME);
diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunShiftDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunShiftDrtScenarioIT.java
index acfc878a000..6f10693a452 100644
--- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunShiftDrtScenarioIT.java
+++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunShiftDrtScenarioIT.java
@@ -132,7 +132,7 @@ void test() {
config.controller().setWriteEventsInterval(1);
config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists);
- config.controller().setOutputDirectory("test/output/holzkirchen_shifts");
+ config.controller().setOutputDirectory("test/output/RunShiftDrtScenarioIT");
DrtOperationsParams operationsParams = (DrtOperationsParams) drtWithShiftsConfigGroup.createParameterSet(DrtOperationsParams.SET_NAME);
ShiftsParams shiftsParams = (ShiftsParams) operationsParams.createParameterSet(ShiftsParams.SET_NAME);
diff --git a/contribs/drt/pom.xml b/contribs/drt/pom.xml
index 7790f252b3c..99fd9d77ec7 100644
--- a/contribs/drt/pom.xml
+++ b/contribs/drt/pom.xml
@@ -15,19 +15,19 @@
org.matsim.contribdvrp
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribotfvis
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribcommon
- 2025.0-SNAPSHOT
+ ${project.parent.version}
diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalWaitTimesAnalyzer.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalWaitTimesAnalyzer.java
index ce140ce1772..610511c61e2 100644
--- a/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalWaitTimesAnalyzer.java
+++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/analysis/zonal/DrtZonalWaitTimesAnalyzer.java
@@ -37,6 +37,7 @@
import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector;
import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector.EventSequence;
import org.matsim.contrib.drt.run.DrtConfigGroup;
+import org.matsim.contrib.dvrp.optimizer.Request;
import org.matsim.core.controler.events.IterationEndsEvent;
import org.matsim.core.controler.events.ShutdownEvent;
import org.matsim.core.controler.listener.IterationEndsListener;
@@ -79,7 +80,7 @@ public void notifyIterationEnds(IterationEndsEvent event) {
}
public void write(String fileName) {
- Map, DescriptiveStatistics> zoneStats = createZonalStats();
+ Map, ZonalStatistics> zoneStats = createZonalStats();
BufferedWriter bw = IOUtils.getBufferedWriter(fileName);
try {
DecimalFormat format = new DecimalFormat();
@@ -90,7 +91,8 @@ public void write(String fileName) {
String header = new StringJoiner(delimiter)
.add("zone").add("centerX").add("centerY").add("nRequests")
.add("sumWaitTime").add("meanWaitTime").add("min").add("max")
- .add("p95").add("p90").add("p80").add("p75").add("p50").toString();
+ .add("p95").add("p90").add("p80").add("p75").add("p50")
+ .add("rejections").add("rejectionRate").toString();
bw.append(header);
// sorted output
SortedSet> zoneIdsAndOutside = new TreeSet<>(zones.getZones().keySet());
@@ -100,7 +102,8 @@ public void write(String fileName) {
Zone drtZone = zones.getZones().get(zoneId);
String centerX = drtZone != null ? String.valueOf(drtZone.getCentroid().getX()) : notAvailableString;
String centerY = drtZone != null ? String.valueOf(drtZone.getCentroid().getY()) : notAvailableString;
- DescriptiveStatistics stats = zoneStats.get(zoneId);
+ DescriptiveStatistics stats = zoneStats.get(zoneId).waitStats;
+ Set> rejections = zoneStats.get(zoneId).rejections;
bw.newLine();
bw.append(
new StringJoiner(delimiter)
@@ -116,7 +119,10 @@ public void write(String fileName) {
.add(String.valueOf(stats.getPercentile(90)))
.add(String.valueOf(stats.getPercentile(80)))
.add(String.valueOf(stats.getPercentile(75)))
- .add(String.valueOf(stats.getPercentile(50))).toString()
+ .add(String.valueOf(stats.getPercentile(50)))
+ .add(String.valueOf(rejections.size()))
+ .add(String.valueOf(rejections.size() / (double) (rejections.size() + stats.getN())))
+ .toString()
);
}
bw.flush();
@@ -126,13 +132,15 @@ public void write(String fileName) {
}
}
- private Map, DescriptiveStatistics> createZonalStats() {
- Map, DescriptiveStatistics> zoneStats = new IdMap<>(Zone.class);
+ record ZonalStatistics(DescriptiveStatistics waitStats, Set> rejections){}
+
+ private Map, ZonalStatistics> createZonalStats() {
+ Map, ZonalStatistics> zoneStats = new IdMap<>(Zone.class);
// prepare stats for all zones
for (Id zoneId : zones.getZones().keySet()) {
- zoneStats.put(zoneId, new DescriptiveStatistics());
+ zoneStats.put(zoneId, new ZonalStatistics(new DescriptiveStatistics(), new HashSet<>()));
}
- zoneStats.put(zoneIdForOutsideOfZonalSystem, new DescriptiveStatistics());
+ zoneStats.put(zoneIdForOutsideOfZonalSystem, new ZonalStatistics(new DescriptiveStatistics(), new HashSet<>()));
for (EventSequence seq : requestAnalyzer.getPerformedRequestSequences().values()) {
for (Map.Entry, EventSequence.PersonEvents> entry : seq.getPersonEvents().entrySet()) {
@@ -140,10 +148,17 @@ private Map, DescriptiveStatistics> createZonalStats() {
Id zone = zones.getZoneForLinkId(seq.getSubmitted().getFromLinkId())
.map(Identifiable::getId).orElse(zoneIdForOutsideOfZonalSystem);
double waitTime = entry.getValue().getPickedUp().get() .getTime() - seq.getSubmitted().getTime();
- zoneStats.get(zone).addValue(waitTime);
+ zoneStats.get(zone).waitStats.addValue(waitTime);
}
}
}
+
+ for (EventSequence seq : requestAnalyzer.getRejectedRequestSequences().values()) {
+ Id zone = zones.getZoneForLinkId(seq.getSubmitted().getFromLinkId())
+ .map(Identifiable::getId).orElse(zoneIdForOutsideOfZonalSystem);
+ zoneStats.get(zone).rejections.add(seq.getSubmitted().getRequestId());
+ }
+
return zoneStats;
}
@@ -191,16 +206,19 @@ private Collection convertGeometriesToSimpleFeatures(String targe
simpleFeatureBuilder.add("p80", Double.class);
simpleFeatureBuilder.add("p75", Double.class);
simpleFeatureBuilder.add("p50", Double.class);
+ simpleFeatureBuilder.add("rejections", Double.class);
+ simpleFeatureBuilder.add("rejectRate", Double.class);
SimpleFeatureBuilder builder = new SimpleFeatureBuilder(simpleFeatureBuilder.buildFeatureType());
Collection features = new ArrayList<>();
- Map, DescriptiveStatistics> zoneStats = createZonalStats();
+ Map, ZonalStatistics> zoneStats = createZonalStats();
for (Zone zone : zones.getZones().values()) {
- Object[] routeFeatureAttributes = new Object[14];
+ Object[] routeFeatureAttributes = new Object[16];
Geometry geometry = zone.getPreparedGeometry() != null ? zone.getPreparedGeometry().getGeometry() : null;
- DescriptiveStatistics stats = zoneStats.get(zone.getId());
+ DescriptiveStatistics stats = zoneStats.get(zone.getId()).waitStats;
+ Set> rejections = zoneStats.get(zone.getId()).rejections;
routeFeatureAttributes[0] = geometry;
routeFeatureAttributes[1] = zone.getId();
routeFeatureAttributes[2] = zone.getCentroid().getX();
@@ -215,6 +233,8 @@ private Collection convertGeometriesToSimpleFeatures(String targe
routeFeatureAttributes[11] = stats.getPercentile(80);
routeFeatureAttributes[12] = stats.getPercentile(75);
routeFeatureAttributes[13] = stats.getPercentile(50);
+ routeFeatureAttributes[14] = rejections.size();
+ routeFeatureAttributes[15] = rejections.size() / (double) (rejections.size() + stats.getN());
try {
features.add(builder.buildFeature(zone.getId().toString(), routeFeatureAttributes));
diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/plusOne/PlusOneRebalancingStrategy.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/plusOne/PlusOneRebalancingStrategy.java
index 2c67ee8640f..12469c783fb 100644
--- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/plusOne/PlusOneRebalancingStrategy.java
+++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/plusOne/PlusOneRebalancingStrategy.java
@@ -99,7 +99,9 @@ public void handleEvent(DrtRequestSubmittedEvent event) {
public void handleEvent(PassengerRequestScheduledEvent event) {
if (event.getMode().equals(mode)) {
Id linkId = potentialTargetLinks.remove(event.getRequestId());
- targets.add(new Target(linkId, event.getTime()));
+ if(linkId != null) {
+ targets.add(new Target(linkId, event.getTime()));
+ }
}
}
diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingManager.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingManager.java
index 04d8df45161..a5dad2f114b 100644
--- a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingManager.java
+++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingManager.java
@@ -395,13 +395,23 @@ private void processRejections(double now) {
if(abortRejectedPrebookings) {
for (Id passengerId : item.request.getPassengerIds()) {
MobsimAgent agent = internalInterface.getMobsim().getAgents().get(passengerId);
- PlanElement planElement = WithinDayAgentUtils.getCurrentPlanElement(agent);
- if(planElement instanceof Activity activity) {
- activity.setEndTime(Double.POSITIVE_INFINITY);
- activity.setMaximumDurationUndefined();
- ((HasModifiablePlan) agent).resetCaches();
- internalInterface.getMobsim().rescheduleActivityEnd(agent);
+
+ int index = WithinDayAgentUtils.getCurrentPlanElementIndex(agent);
+ Plan plan = WithinDayAgentUtils.getModifiablePlan(agent);
+ PlanElement planElement = plan.getPlanElements().get(index);
+ Activity activity;
+ if(planElement instanceof Activity currentActivity) {
+ activity = currentActivity;
+ } else {
+ // If the current element is a leg, the agent is walking towards the pickup location
+ // We make the agent stuck at the interaction activity
+ activity = (Activity) plan.getPlanElements().get(index+1);
}
+ activity.setEndTime(Double.POSITIVE_INFINITY);
+ activity.setMaximumDurationUndefined();
+
+ ((HasModifiablePlan) agent).resetCaches();
+ internalInterface.getMobsim().rescheduleActivityEnd(agent);
eventsManager.processEvent(new PersonStuckEvent(now, agent.getId(), agent.getCurrentLinkId(),
this.mode));
internalInterface.getMobsim().getAgentCounter().incLost();
diff --git a/contribs/dvrp/pom.xml b/contribs/dvrp/pom.xml
index 716fab806f2..e6fc424004c 100644
--- a/contribs/dvrp/pom.xml
+++ b/contribs/dvrp/pom.xml
@@ -24,17 +24,17 @@
org.matsim.contribotfvis
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribcommon
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribev
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.apache.commons
diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/router/DvrpModeRoutingNetworkModule.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/router/DvrpModeRoutingNetworkModule.java
index 076ce4876ec..3b8463a1119 100644
--- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/router/DvrpModeRoutingNetworkModule.java
+++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/router/DvrpModeRoutingNetworkModule.java
@@ -20,6 +20,7 @@
package org.matsim.contrib.dvrp.router;
+import java.io.File;
import java.util.Collections;
import java.util.Set;
@@ -32,6 +33,7 @@
import org.matsim.contrib.zone.skims.FreeSpeedTravelTimeMatrix;
import org.matsim.contrib.zone.skims.TravelTimeMatrix;
import org.matsim.core.config.Config;
+import org.matsim.core.config.ConfigGroup;
import org.matsim.core.config.groups.GlobalConfigGroup;
import org.matsim.core.config.groups.QSimConfigGroup;
import org.matsim.core.network.NetworkUtils;
@@ -86,9 +88,16 @@ public void install() {
DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams();
ZoneSystem zoneSystem = ZoneSystemUtils.createZoneSystem(getConfig().getContext(), network,
matrixParams.getZoneSystemParams(), getConfig().global().getCoordinateSystem(), zone -> true);
- return FreeSpeedTravelTimeMatrix.createFreeSpeedMatrix(network, zoneSystem,
- matrixParams, globalConfigGroup.getNumberOfThreads(),
- qSimConfigGroup.getTimeStepSize());
+
+
+ if (matrixParams.cachePath == null) {
+ return FreeSpeedTravelTimeMatrix.createFreeSpeedMatrix(network, zoneSystem, matrixParams, globalConfigGroup.getNumberOfThreads(),
+ qSimConfigGroup.getTimeStepSize());
+ } else {
+ File cachePath = new File(ConfigGroup.getInputFileURL(getConfig().getContext(), matrixParams.cachePath).getPath());
+ return FreeSpeedTravelTimeMatrix.createFreeSpeedMatrixFromCache(network, zoneSystem, matrixParams, globalConfigGroup.getNumberOfThreads(),
+ qSimConfigGroup.getTimeStepSize(), cachePath);
+ }
})).in(Singleton.class);
} else {
//use DVRP-routing (dvrp-global) network
diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpModule.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpModule.java
index d31fe11499d..769ea423515 100644
--- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpModule.java
+++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/run/DvrpModule.java
@@ -19,7 +19,7 @@
package org.matsim.contrib.dvrp.run;
-import jakarta.inject.Provider;
+import java.io.File;
import org.matsim.api.core.v01.network.Network;
import org.matsim.contrib.common.zones.ZoneSystem;
@@ -33,6 +33,7 @@
import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams;
import org.matsim.contrib.zone.skims.FreeSpeedTravelTimeMatrix;
import org.matsim.contrib.zone.skims.TravelTimeMatrix;
+import org.matsim.core.config.ConfigGroup;
import org.matsim.core.config.groups.QSimConfigGroup;
import org.matsim.core.controler.AbstractModule;
import org.matsim.core.mobsim.framework.MobsimTimer;
@@ -44,6 +45,8 @@
import com.google.inject.name.Named;
import com.google.inject.name.Names;
+import jakarta.inject.Provider;
+
/**
* This module initialises generic (i.e. not taxi or drt-specific) AND global (not mode-specific) dvrp objects.
*
@@ -90,8 +93,15 @@ public TravelTimeMatrix get() {
DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams();
ZoneSystem zoneSystem = ZoneSystemUtils.createZoneSystem(getConfig().getContext(), network,
matrixParams.getZoneSystemParams(), getConfig().global().getCoordinateSystem(), zone -> true);
- return FreeSpeedTravelTimeMatrix.createFreeSpeedMatrix(network, zoneSystem, params, numberOfThreads,
+
+ if (params.cachePath == null) {
+ return FreeSpeedTravelTimeMatrix.createFreeSpeedMatrix(network, zoneSystem, params, numberOfThreads,
qSimConfigGroup.getTimeStepSize());
+ } else {
+ File cachePath = new File(ConfigGroup.getInputFileURL(getConfig().getContext(), params.cachePath).getPath());
+ return FreeSpeedTravelTimeMatrix.createFreeSpeedMatrixFromCache(network, zoneSystem, params, numberOfThreads,
+ qSimConfigGroup.getTimeStepSize(), cachePath);
+ }
}
}).in(Singleton.class);
diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java
index 52c3c332f09..9b959a87ba2 100644
--- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java
+++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java
@@ -28,6 +28,7 @@
import org.matsim.contrib.common.zones.systems.grid.GISFileZoneSystemParams;
import org.matsim.contrib.common.zones.systems.grid.h3.H3GridZoneSystemParams;
import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams;
+import org.matsim.core.config.ReflectiveConfigGroup.Parameter;
/**
* @author Michal Maciejewski (michalm)
@@ -59,6 +60,9 @@ public class DvrpTravelTimeMatrixParams extends ReflectiveConfigGroupWithConfigu
@NotNull
private ZoneSystemParams zoneSystemParams;
+ @Parameter
+ @Comment("Caches the travel time matrix data into a binary file. If the file exists, the matrix will be read from the file, if not, the file will be created.")
+ public String cachePath = null;
public DvrpTravelTimeMatrixParams() {
super(SET_NAME);
diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java
index 6351dd3bce8..356625f4295 100644
--- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java
+++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrix.java
@@ -20,14 +20,34 @@
package org.matsim.contrib.zone.skims;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.IdSet;
import org.matsim.api.core.v01.network.Network;
import org.matsim.api.core.v01.network.Node;
+import org.matsim.contrib.common.zones.Zone;
import org.matsim.contrib.common.zones.ZoneSystem;
import org.matsim.contrib.common.zones.ZoneSystemUtils;
import org.matsim.contrib.dvrp.router.TimeAsTravelDisutility;
import org.matsim.contrib.dvrp.trafficmonitoring.QSimFreeSpeedTravelTime;
+import org.matsim.contrib.zone.skims.SparseMatrix.NodeAndTime;
+import org.matsim.contrib.zone.skims.SparseMatrix.SparseRow;
import org.matsim.core.router.util.TravelTime;
+import com.google.common.base.Verify;
+import com.google.common.collect.Sets;
+
/**
* @author Michal Maciejewski (michalm)
*/
@@ -68,4 +88,151 @@ public int getTravelTime(Node fromNode, Node toNode, double departureTime) {
public int getZonalTravelTime(Node fromNode, Node toNode, double departureTime) {
return freeSpeedTravelTimeMatrix.get(zoneSystem.getZoneForNodeId(fromNode.getId()).orElseThrow(), zoneSystem.getZoneForNodeId(toNode.getId()).orElseThrow());
}
+
+ public static FreeSpeedTravelTimeMatrix createFreeSpeedMatrixFromCache(Network dvrpNetwork, ZoneSystem zoneSystem, DvrpTravelTimeMatrixParams params, int numberOfThreads, double qSimTimeStepSize, File cachePath) {
+ boolean exists = cachePath.exists();
+
+ final FreeSpeedTravelTimeMatrix matrix;
+ if (exists) {
+ matrix = new FreeSpeedTravelTimeMatrix(dvrpNetwork, zoneSystem, cachePath);
+ } else {
+ matrix = createFreeSpeedMatrix(dvrpNetwork, zoneSystem, params, numberOfThreads, qSimTimeStepSize);
+ matrix.write(cachePath, dvrpNetwork);
+ }
+
+ return matrix;
+ }
+
+ public FreeSpeedTravelTimeMatrix(Network dvrpNetwork, ZoneSystem zoneSystem, File cachePath) {
+ this.zoneSystem = zoneSystem;
+
+ try (DataInputStream inputStream = new DataInputStream(new FileInputStream(cachePath))) {
+ // number of zones
+ int numberOfZones = inputStream.readInt();
+ Verify.verify(numberOfZones == zoneSystem.getZones().size());
+
+ // read zone list
+ List> zoneIds = new ArrayList<>(numberOfZones);
+ for (int i = 0; i < numberOfZones; i++) {
+ zoneIds.add(Id.create(inputStream.readUTF(), Zone.class));
+ }
+
+ IdSet systemZones = new IdSet<>(Zone.class);
+ systemZones.addAll(zoneSystem.getZones().keySet());
+
+ IdSet dataZones = new IdSet<>(Zone.class);
+ dataZones.addAll(zoneIds);
+
+ Verify.verify(Sets.difference(systemZones, dataZones).size() == 0);
+ Verify.verify(Sets.difference(dataZones, systemZones).size() == 0);
+
+ // fill matrix
+ freeSpeedTravelTimeMatrix = new Matrix(new HashSet<>(zoneSystem.getZones().values()));
+
+ for (var from : zoneIds) {
+ for (var to : zoneIds) {
+ Zone fromZone = zoneSystem.getZones().get(from);
+ Zone toZone = zoneSystem.getZones().get(to);
+ freeSpeedTravelTimeMatrix.set(fromZone, toZone, inputStream.readInt());
+ }
+ }
+
+ // sparse matrix available?
+ boolean hasSparseMatrix = inputStream.readBoolean();
+
+ if (!hasSparseMatrix) {
+ freeSpeedTravelTimeSparseMatrix = null;
+ } else {
+ freeSpeedTravelTimeSparseMatrix = new SparseMatrix();
+
+ // read nodes
+ int numberOfNodes = inputStream.readInt();
+ Verify.verify(numberOfNodes == dvrpNetwork.getNodes().size());
+
+ List nodes = new ArrayList<>(numberOfNodes);
+ for (int i = 0; i < numberOfNodes; i++) {
+ Id nodeId = Id.createNodeId(inputStream.readUTF());
+ nodes.add(Objects.requireNonNull(dvrpNetwork.getNodes().get(nodeId)));
+ }
+
+ // read rows
+ for (int i = 0; i < numberOfNodes; i++) {
+ Node from = nodes.get(i);
+ int numberOfElements = inputStream.readInt();
+
+ if (numberOfElements > 0) {
+ List nodeTimeList = new ArrayList<>(numberOfElements);
+
+ for (int j = 0; j < numberOfElements; j++) {
+ Node to = nodes.get(inputStream.readInt());
+ int value = inputStream.readInt();
+
+ nodeTimeList.add(new NodeAndTime(to.getId().index(), value));
+ }
+
+ SparseRow row = new SparseRow(nodeTimeList);
+ freeSpeedTravelTimeSparseMatrix.setRow(from, row);
+ }
+ }
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ public void write(File outputPath, Network dvrpNetwork) {
+ try (DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(outputPath))) {
+ // obtain fixed order of zones
+ List zones = new ArrayList<>(zoneSystem.getZones().values());
+ outputStream.writeInt(zones.size());
+ for (Zone zone : zones) {
+ outputStream.writeUTF(zone.getId().toString());
+ }
+
+ // write matrix
+ for (var from : zones) {
+ for (var to : zones) {
+ int value = freeSpeedTravelTimeMatrix.get(from, to);
+ outputStream.writeInt(value);
+ }
+ }
+
+ // write if sparse exists
+ outputStream.writeBoolean(freeSpeedTravelTimeSparseMatrix != null);
+
+ if (freeSpeedTravelTimeSparseMatrix != null) {
+ // obtain fixed order of nodes
+ List nodes = new ArrayList<>(dvrpNetwork.getNodes().values());
+ outputStream.writeInt(nodes.size());
+ for (Node node : nodes) {
+ outputStream.writeUTF(node.getId().toString());
+ }
+
+ for (Node from : nodes) {
+ // write size of the matrix row
+ int rowSize = 0;
+
+ for (Node to : nodes) {
+ int value = freeSpeedTravelTimeSparseMatrix.get(from, to);
+ if (value >= 0) {
+ rowSize++;
+ }
+ }
+
+ outputStream.writeInt(rowSize);
+
+ // write matrix row
+ for (Node to : nodes) {
+ int value = freeSpeedTravelTimeSparseMatrix.get(from, to);
+ if (value >= 0) {
+ outputStream.writeInt(nodes.indexOf(to));
+ outputStream.writeInt(value);
+ }
+ }
+ }
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
}
diff --git a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrixTest.java b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrixTest.java
index 8aaf6001258..2cf4cc30934 100644
--- a/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrixTest.java
+++ b/contribs/dvrp/src/test/java/org/matsim/contrib/zone/skims/FreeSpeedTravelTimeMatrixTest.java
@@ -22,7 +22,10 @@
import static org.assertj.core.api.Assertions.assertThat;
+import java.io.File;
+
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Network;
@@ -30,12 +33,16 @@
import org.matsim.contrib.common.zones.ZoneSystem;
import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystem;
import org.matsim.core.network.NetworkUtils;
+import org.matsim.testcases.MatsimTestUtils;
/**
* @author Michal Maciejewski (michalm)
*/
public class FreeSpeedTravelTimeMatrixTest {
+ @RegisterExtension
+ MatsimTestUtils utils = new MatsimTestUtils();
+
private final Network network = NetworkUtils.createNetwork();
private final Node nodeA = NetworkUtils.createAndAddNode(network, Id.createNodeId("A"), new Coord(0, 0));
private final Node nodeB = NetworkUtils.createAndAddNode(network, Id.createNodeId("B"), new Coord(150, 150));
@@ -66,6 +73,23 @@ void matrix() {
assertThat(matrix.getTravelTime(nodeC, nodeA, 0)).isEqualTo(0);
assertThat(matrix.getTravelTime(nodeB, nodeC, 0)).isEqualTo(20 + 1); // 1 s for moving over nodes
assertThat(matrix.getTravelTime(nodeC, nodeB, 0)).isEqualTo(10 + 1); // 1 s for moving over nodes
+
+ // write and read cache
+ File cachePath = new File(utils.getOutputDirectory(), "cache.bin");
+ matrix.write(cachePath, network);
+ matrix = FreeSpeedTravelTimeMatrix.createFreeSpeedMatrixFromCache(network, zoneSystem, null, 1, 1, cachePath);
+
+ // distances between central nodes: A and B
+ assertThat(matrix.getTravelTime(nodeA, nodeA, 0)).isEqualTo(0);
+ assertThat(matrix.getTravelTime(nodeA, nodeB, 0)).isEqualTo(10 + 1); // 1 s for moving over nodes
+ assertThat(matrix.getTravelTime(nodeB, nodeA, 0)).isEqualTo(20 + 1); // 1 s for moving over nodes
+ assertThat(matrix.getTravelTime(nodeB, nodeB, 0)).isEqualTo(0);
+
+ // non-central node: C and A are in the same zone; A is the central node
+ assertThat(matrix.getTravelTime(nodeA, nodeC, 0)).isEqualTo(0);
+ assertThat(matrix.getTravelTime(nodeC, nodeA, 0)).isEqualTo(0);
+ assertThat(matrix.getTravelTime(nodeB, nodeC, 0)).isEqualTo(20 + 1); // 1 s for moving over nodes
+ assertThat(matrix.getTravelTime(nodeC, nodeB, 0)).isEqualTo(10 + 1); // 1 s for moving over nodes
}
@Test
@@ -87,5 +111,22 @@ void sparseMatrix() {
assertThat(matrix.getTravelTime(nodeC, nodeA, 0)).isEqualTo(9 + 1); // 1 s for moving over nodes
assertThat(matrix.getTravelTime(nodeB, nodeC, 0)).isEqualTo(20 + 11 + 2); // 2 s for moving over nodes
assertThat(matrix.getTravelTime(nodeC, nodeB, 0)).isEqualTo(10 + 9 + 2); // 2 s for moving over nodes
+
+ // write and read cache
+ File cachePath = new File(utils.getOutputDirectory(), "cache.bin");
+ matrix.write(cachePath, network);
+ matrix = FreeSpeedTravelTimeMatrix.createFreeSpeedMatrixFromCache(network, zoneSystem, null, 1, 1, cachePath);
+
+ // distances between central nodes: A and B
+ assertThat(matrix.getTravelTime(nodeA, nodeA, 0)).isEqualTo(0);
+ assertThat(matrix.getTravelTime(nodeA, nodeB, 0)).isEqualTo(10 + 1); // 1 s for moving over nodes
+ assertThat(matrix.getTravelTime(nodeB, nodeA, 0)).isEqualTo(20 + 1); // 1 s for moving over nodes
+ assertThat(matrix.getTravelTime(nodeB, nodeB, 0)).isEqualTo(0);
+
+ // non-central node: C and A are in the same zone; A is the central node
+ assertThat(matrix.getTravelTime(nodeA, nodeC, 0)).isEqualTo(11 + 1); // 1 s for moving over nodes
+ assertThat(matrix.getTravelTime(nodeC, nodeA, 0)).isEqualTo(9 + 1); // 1 s for moving over nodes
+ assertThat(matrix.getTravelTime(nodeB, nodeC, 0)).isEqualTo(20 + 11 + 2); // 2 s for moving over nodes
+ assertThat(matrix.getTravelTime(nodeC, nodeB, 0)).isEqualTo(10 + 9 + 2); // 2 s for moving over nodes
}
}
diff --git a/contribs/emissions/pom.xml b/contribs/emissions/pom.xml
index 16d87bc8cdb..98daccca22b 100644
--- a/contribs/emissions/pom.xml
+++ b/contribs/emissions/pom.xml
@@ -58,7 +58,7 @@
org.matsim.contribanalysis
- 2025.0-SNAPSHOT
+ ${project.parent.version}com.fasterxml.jackson.core
diff --git a/contribs/emissions/src/main/java/org/matsim/contrib/emissions/OsmHbefaMapping.java b/contribs/emissions/src/main/java/org/matsim/contrib/emissions/OsmHbefaMapping.java
index ccce2492711..fb492e2bfd3 100644
--- a/contribs/emissions/src/main/java/org/matsim/contrib/emissions/OsmHbefaMapping.java
+++ b/contribs/emissions/src/main/java/org/matsim/contrib/emissions/OsmHbefaMapping.java
@@ -85,6 +85,8 @@ public static OsmHbefaMapping build() {
mapping.put("residential", new Hbefa("Access",30,50));
mapping.put("service", new Hbefa("Access",30,50));
mapping.put("living", new Hbefa("Access",30,50));
+ mapping.put("cycleway", new Hbefa("Access",30,50));
+ mapping.put("path", new Hbefa("Access",30,50));
return mapping;
}
diff --git a/contribs/emissions/src/main/java/org/matsim/contrib/emissions/events/EmissionEvent.java b/contribs/emissions/src/main/java/org/matsim/contrib/emissions/events/EmissionEvent.java
index ae7c9c59e2a..180e79ca9fc 100644
--- a/contribs/emissions/src/main/java/org/matsim/contrib/emissions/events/EmissionEvent.java
+++ b/contribs/emissions/src/main/java/org/matsim/contrib/emissions/events/EmissionEvent.java
@@ -25,6 +25,7 @@
import org.matsim.api.core.v01.events.Event;
import org.matsim.api.core.v01.network.Link;
import org.matsim.contrib.emissions.Pollutant;
+import org.matsim.core.utils.io.XmlUtils;
import org.matsim.vehicles.Vehicle;
import java.util.Map;
@@ -67,4 +68,20 @@ public Map getAttributes() {
}
return attributes;
}
+
+ @Override
+ public void writeAsXML(StringBuilder out) {
+ // Writes common attributes
+ writeXMLStart(out);
+
+ XmlUtils.writeEncodedAttributeKeyValue(out, ATTRIBUTE_LINK_ID, this.linkId.toString());
+ XmlUtils.writeEncodedAttributeKeyValue(out, ATTRIBUTE_VEHICLE_ID, this.vehicleId.toString());
+
+ for (Map.Entry entry : emissions.entrySet()) {
+ out.append(entry.getKey().name()).append("=\"");
+ out.append((double) entry.getValue()).append("\" ");
+ }
+
+ writeXMLEnd(out);
+ }
}
diff --git a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestPositionEmissionModule.java b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestPositionEmissionModule.java
index a3059795499..1f0ccd3eaf5 100644
--- a/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestPositionEmissionModule.java
+++ b/contribs/emissions/src/test/java/org/matsim/contrib/emissions/TestPositionEmissionModule.java
@@ -201,7 +201,7 @@ public void handleEvent(Event event) {
}
private VehicleType createVehicleType() {
- VehicleType vehicleType = VehicleUtils.createVehicleType(Id.create("dieselCarFullSpecified", VehicleType.class));
+ VehicleType vehicleType = VehicleUtils.createVehicleType(Id.create("dieselCarFullSpecified", VehicleType.class), TransportMode.car);
EngineInformation engineInformation = vehicleType.getEngineInformation();
VehicleUtils.setHbefaVehicleCategory(engineInformation, "PASSENGER_CAR");
VehicleUtils.setHbefaTechnology(engineInformation, "diesel");
diff --git a/contribs/ev/pom.xml b/contribs/ev/pom.xml
index e1c5144d706..120d63dfbe3 100644
--- a/contribs/ev/pom.xml
+++ b/contribs/ev/pom.xml
@@ -14,7 +14,7 @@
org.matsim.contribcommon
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.apache.commons
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/Charger.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/Charger.java
index 9bd2ef5bde9..921b950e41c 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/Charger.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/Charger.java
@@ -24,8 +24,9 @@
import org.matsim.api.core.v01.Identifiable;
import org.matsim.api.core.v01.network.Link;
import org.matsim.contrib.ev.charging.ChargingLogic;
+import org.matsim.utils.objectattributes.attributable.Attributable;
-public interface Charger extends BasicLocation, Identifiable {
+public interface Charger extends BasicLocation, Identifiable, Attributable {
ChargerSpecification getSpecification();
ChargingLogic getLogic();
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerDefaultImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerDefaultImpl.java
index d2efb68578d..7ceb1007f92 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerDefaultImpl.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerDefaultImpl.java
@@ -26,6 +26,7 @@
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.contrib.ev.charging.ChargingLogic;
+import org.matsim.utils.objectattributes.attributable.Attributes;
import com.google.common.base.Preconditions;
@@ -77,6 +78,11 @@ public int getPlugCount() {
return specification.getPlugCount();
}
+ @Override
+ public Attributes getAttributes() {
+ return specification.getAttributes();
+ }
+
//TODO in order to add a separate coord: adapt DTD, ChargerSpecification and ChargerReader/Writer
// Additionally, the reader and writer should convert coordinates if CRS different than that of the network
@Override
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerReader.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerReader.java
index 9864622b4cb..b3d6a4d6c36 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerReader.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerReader.java
@@ -20,19 +20,33 @@
package org.matsim.contrib.ev.infrastructure;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Optional;
import java.util.Stack;
import org.matsim.api.core.v01.Id;
import org.matsim.contrib.ev.EvUnits;
+import org.matsim.contrib.ev.infrastructure.ImmutableChargerSpecification.ChargerSpecificationBuilder;
import org.matsim.core.utils.io.MatsimXmlParser;
+import org.matsim.utils.objectattributes.AttributeConverter;
+import org.matsim.utils.objectattributes.attributable.AttributesImpl;
+import org.matsim.utils.objectattributes.attributable.AttributesXmlReaderDelegate;
import org.xml.sax.Attributes;
public final class ChargerReader extends MatsimXmlParser {
private final static String CHARGER = "charger";
+ private final static String ATTRIBUTES = "attributes";
+ private final static String ATTRIBUTE = "attribute";
private final ChargingInfrastructureSpecification chargingInfrastructure;
+ private Map, AttributeConverter>> attributeConverters = new HashMap<>();
+ private final AttributesXmlReaderDelegate attributesReader = new AttributesXmlReaderDelegate();
+
+ private ChargerSpecificationBuilder currentBuilder = null;
+ private AttributesImpl currentAttributes = null;
+
public ChargerReader(ChargingInfrastructureSpecification chargingInfrastructure) {
super(ValidationType.DTD_ONLY);
this.chargingInfrastructure = chargingInfrastructure;
@@ -41,15 +55,30 @@ public ChargerReader(ChargingInfrastructureSpecification chargingInfrastructure)
@Override
public void startTag(String name, Attributes atts, Stack context) {
if (CHARGER.equals(name)) {
- chargingInfrastructure.addChargerSpecification(createSpecification(atts));
+ currentBuilder = createSpecification(atts);
+ } else if (ATTRIBUTES.equals(name)) {
+ currentAttributes = new AttributesImpl();
+ attributesReader.startTag(name, atts, context, currentAttributes);
+ } else if (ATTRIBUTE.equals(name)) {
+ attributesReader.startTag(name, atts, context, currentAttributes);
}
}
@Override
public void endTag(String name, String content, Stack context) {
+ if (CHARGER.equals(name)) {
+ chargingInfrastructure.addChargerSpecification(currentBuilder.build());
+ currentBuilder = null;
+ } else if (ATTRIBUTES.equals(name)) {
+ attributesReader.endTag(name, content, context);
+ currentBuilder.attributes(currentAttributes);
+ currentAttributes = null;
+ } else if (ATTRIBUTE.equals(name)) {
+ attributesReader.endTag(name, content, context);
+ }
}
- private ChargerSpecification createSpecification(Attributes atts) {
+ private ChargerSpecificationBuilder createSpecification(Attributes atts) {
return ImmutableChargerSpecification.newBuilder()
.id(Id.create(atts.getValue("id"), Charger.class))
.linkId(Id.createLinkId(atts.getValue("link")))
@@ -58,7 +87,14 @@ private ChargerSpecification createSpecification(Attributes atts) {
.plugPower(EvUnits.kW_to_W(Double.parseDouble(atts.getValue("plug_power"))))
.plugCount(Optional.ofNullable(atts.getValue("plug_count"))
.map(Integer::parseInt)
- .orElse(ChargerSpecification.DEFAULT_PLUG_COUNT))
- .build();
+ .orElse(ChargerSpecification.DEFAULT_PLUG_COUNT));
}
+
+ public void putAttributeConverters(Map, AttributeConverter>> converters) {
+ this.attributeConverters.putAll(converters);
+ }
+
+ public void putAttributeConverter(Class> key, AttributeConverter> converter) {
+ this.attributeConverters.put(key, converter);
+ }
}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerSpecification.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerSpecification.java
index 14aafb14d12..73272087d0a 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerSpecification.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerSpecification.java
@@ -23,6 +23,7 @@
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Identifiable;
import org.matsim.api.core.v01.network.Link;
+import org.matsim.utils.objectattributes.attributable.Attributable;
/**
* ChargerSpecification is assumed to be immutable.
@@ -34,7 +35,7 @@
*
* @author Michal Maciejewski (michalm)
*/
-public interface ChargerSpecification extends Identifiable {
+public interface ChargerSpecification extends Identifiable, Attributable {
String DEFAULT_CHARGER_TYPE = "default";
int DEFAULT_PLUG_COUNT = 1;
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerWriter.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerWriter.java
index 8955b266984..f62ee0729f6 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerWriter.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerWriter.java
@@ -20,18 +20,27 @@
package org.matsim.contrib.ev.infrastructure;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.stream.Stream;
import org.matsim.contrib.ev.EvUnits;
import org.matsim.core.utils.collections.Tuple;
import org.matsim.core.utils.io.MatsimXmlWriter;
+import org.matsim.utils.objectattributes.AttributeConverter;
+import org.matsim.utils.objectattributes.attributable.AttributesXmlWriterDelegate;
public final class ChargerWriter extends MatsimXmlWriter {
private final Stream extends ChargerSpecification> chargerSpecifications;
+ private Map, AttributeConverter>> attributeConverters = new HashMap<>();
+ private final AttributesXmlWriterDelegate attributesWriter = new AttributesXmlWriterDelegate();
+
public ChargerWriter(Stream extends ChargerSpecification> chargerSpecifications) {
this.chargerSpecifications = chargerSpecifications;
}
@@ -45,13 +54,34 @@ public void write(String file) {
close();
}
- private void writeChargers() {
+ private void writeChargers() throws UncheckedIOException {
chargerSpecifications.forEach(c -> {
List> atts = Arrays.asList(Tuple.of("id", c.getId().toString()),
Tuple.of("link", c.getLinkId() + ""), Tuple.of("type", c.getChargerType()),
Tuple.of("plug_power", EvUnits.W_to_kW(c.getPlugPower()) + ""),
Tuple.of("plug_count", c.getPlugCount() + ""));
- writeStartTag("charger", atts, true);
+ if (c.getAttributes().size() == 0) {
+ writeStartTag("charger", atts, true);
+ } else {
+ writeStartTag("charger", atts, false);
+
+ try {
+ this.writer.write("\n");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+
+ attributesWriter.writeAttributes("\t\t", this.writer, c.getAttributes(), false);
+ writeEndTag("charger");
+ }
});
}
+
+ public void putAttributeConverters(Map, AttributeConverter>> converters) {
+ this.attributeConverters.putAll(converters);
+ }
+
+ public void putAttributeConverter(Class> key, AttributeConverter> converter) {
+ this.attributeConverters.put(key, converter);
+ }
}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureModule.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureModule.java
index f44bee53f11..dd85c2bb83b 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureModule.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureModule.java
@@ -20,12 +20,16 @@
package org.matsim.contrib.ev.infrastructure;
+import java.util.Collections;
+import java.util.Map;
+
import org.matsim.api.core.v01.network.Network;
import org.matsim.contrib.ev.EvConfigGroup;
import org.matsim.contrib.ev.charging.ChargingLogic;
import org.matsim.core.config.ConfigGroup;
import org.matsim.core.controler.AbstractModule;
import org.matsim.core.mobsim.qsim.AbstractQSimModule;
+import org.matsim.utils.objectattributes.AttributeConverter;
import com.google.inject.Inject;
import com.google.inject.Key;
@@ -55,11 +59,20 @@ public ChargingInfrastructureModule(Key networkKey) {
public void install() {
bind(Network.class).annotatedWith(Names.named(CHARGERS)).to(networkKey).asEagerSingleton();
- bind(ChargingInfrastructureSpecification.class).toProvider(() -> {
- ChargingInfrastructureSpecification chargingInfrastructureSpecification = new ChargingInfrastructureSpecificationDefaultImpl();
- new ChargerReader(chargingInfrastructureSpecification).parse(
- ConfigGroup.getInputFileURL(getConfig().getContext(), evCfg.chargersFile));
- return chargingInfrastructureSpecification;
+ bind(ChargingInfrastructureSpecification.class).toProvider(new Provider<>() {
+ @Inject
+ private Map,AttributeConverter>> attributeConverters = Collections.emptyMap();
+
+ public ChargingInfrastructureSpecification get() {
+ ChargingInfrastructureSpecification chargingInfrastructureSpecification = new ChargingInfrastructureSpecificationDefaultImpl();
+
+ ChargerReader reader = new ChargerReader(chargingInfrastructureSpecification);
+ reader.putAttributeConverters(attributeConverters);
+ reader.parse(
+ ConfigGroup.getInputFileURL(getConfig().getContext(), evCfg.chargersFile));
+
+ return chargingInfrastructureSpecification;
+ }
}).asEagerSingleton();
installQSimModule(new AbstractQSimModule() {
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ImmutableChargerSpecification.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ImmutableChargerSpecification.java
index a3d7192b793..2987fe88677 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ImmutableChargerSpecification.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ImmutableChargerSpecification.java
@@ -24,6 +24,8 @@
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
+import org.matsim.utils.objectattributes.attributable.Attributes;
+import org.matsim.utils.objectattributes.attributable.AttributesImpl;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
@@ -39,6 +41,7 @@ public class ImmutableChargerSpecification implements ChargerSpecification {
private final String chargerType;
private final double plugPower;
private final int plugCount;
+ private final Attributes attributes;
private ImmutableChargerSpecification( ChargerSpecificationBuilder builder ) {
id = Objects.requireNonNull(builder.id);
@@ -46,6 +49,7 @@ private ImmutableChargerSpecification( ChargerSpecificationBuilder builder ) {
chargerType = Objects.requireNonNull(builder.chargerType);
plugPower = Objects.requireNonNull(builder.plugPower);
plugCount = Objects.requireNonNull(builder.plugCount);
+ attributes = builder.attributes != null ? builder.attributes : new AttributesImpl();
Preconditions.checkArgument(plugPower >= 0, "Negative plugPower of charger: %s", id);
Preconditions.checkArgument(plugCount >= 0, "Negative plugCount of charger: %s", id);
@@ -90,6 +94,11 @@ public int getPlugCount() {
return plugCount;
}
+ @Override
+ public Attributes getAttributes() {
+ return attributes;
+ }
+
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
@@ -107,6 +116,7 @@ public static final class ChargerSpecificationBuilder{
private String chargerType;
private Double plugPower;
private Integer plugCount;
+ private Attributes attributes;
private ChargerSpecificationBuilder() {
}
@@ -136,6 +146,11 @@ public ChargerSpecificationBuilder plugCount( int val ) {
return this;
}
+ public ChargerSpecificationBuilder attributes( Attributes val ) {
+ attributes = val;
+ return this;
+ }
+
public ImmutableChargerSpecification build() {
return new ImmutableChargerSpecification(this);
}
diff --git a/contribs/ev/src/test/java/org/matsim/contrib/ev/infrastructure/ChargerReaderWriterTest.java b/contribs/ev/src/test/java/org/matsim/contrib/ev/infrastructure/ChargerReaderWriterTest.java
new file mode 100644
index 00000000000..eb6e0f5c65f
--- /dev/null
+++ b/contribs/ev/src/test/java/org/matsim/contrib/ev/infrastructure/ChargerReaderWriterTest.java
@@ -0,0 +1,108 @@
+package org.matsim.contrib.ev.infrastructure;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.matsim.api.core.v01.Id;
+import org.matsim.testcases.MatsimTestUtils;
+import org.matsim.utils.objectattributes.attributable.AttributesImpl;
+
+public class ChargerReaderWriterTest {
+ @RegisterExtension
+ MatsimTestUtils utils = new MatsimTestUtils();
+
+ @Test
+ public void testReadWriteChargers() {
+ ChargingInfrastructureSpecificationDefaultImpl infrastructure = new ChargingInfrastructureSpecificationDefaultImpl();
+
+ infrastructure.addChargerSpecification(ImmutableChargerSpecification.newBuilder()
+ .id(Id.create("charger1", Charger.class)) //
+ .chargerType("type1") //
+ .linkId(Id.createLinkId("link1")) //
+ .plugCount(1) //
+ .plugPower(1000.0) //
+ .build());
+
+ infrastructure.addChargerSpecification(ImmutableChargerSpecification.newBuilder()
+ .id(Id.create("charger2", Charger.class)) //
+ .chargerType("type2") //
+ .linkId(Id.createLinkId("link2")) //
+ .plugCount(2) //
+ .plugPower(2000.0) //
+ .build());
+
+ String path = utils.getOutputDirectory() + "/chargers.xml";
+ new ChargerWriter(infrastructure.getChargerSpecifications().values().stream()).write(path);
+
+ ChargingInfrastructureSpecificationDefaultImpl readInfrastructure = new ChargingInfrastructureSpecificationDefaultImpl();
+ new ChargerReader(readInfrastructure).readFile(path);
+
+ ChargerSpecification spec1 = readInfrastructure.getChargerSpecifications()
+ .get(Id.create("charger1", Charger.class));
+ assertEquals("type1", spec1.getChargerType());
+ assertEquals(Id.createLinkId("link1"), spec1.getLinkId());
+ assertEquals(1, spec1.getPlugCount());
+ assertEquals(1000.0, spec1.getPlugPower());
+
+ ChargerSpecification spec2 = readInfrastructure.getChargerSpecifications()
+ .get(Id.create("charger2", Charger.class));
+ assertEquals("type2", spec2.getChargerType());
+ assertEquals(Id.createLinkId("link2"), spec2.getLinkId());
+ assertEquals(2, spec2.getPlugCount());
+ assertEquals(2000.0, spec2.getPlugPower());
+ }
+
+ @Test
+ public void testReadWriteChargersWithAttributes() {
+ ChargingInfrastructureSpecificationDefaultImpl infrastructure = new ChargingInfrastructureSpecificationDefaultImpl();
+
+ AttributesImpl attributes1 = new AttributesImpl();
+ attributes1.putAttribute("attribute1", "value1");
+
+ infrastructure.addChargerSpecification(ImmutableChargerSpecification.newBuilder()
+ .id(Id.create("charger1", Charger.class)) //
+ .chargerType("type1") //
+ .linkId(Id.createLinkId("link1")) //
+ .plugCount(1) //
+ .plugPower(1000.0) //
+ .attributes(attributes1) //
+ .build());
+
+ AttributesImpl attributes2 = new AttributesImpl();
+ attributes2.putAttribute("attribute2", "value2");
+
+ infrastructure.addChargerSpecification(ImmutableChargerSpecification.newBuilder()
+ .id(Id.create("charger2", Charger.class)) //
+ .chargerType("type2") //
+ .linkId(Id.createLinkId("link2")) //
+ .plugCount(2) //
+ .plugPower(2000.0) //
+ .attributes(attributes2) //
+ .build());
+
+ String path = utils.getOutputDirectory() + "/chargers_with_attributes.xml";
+ new ChargerWriter(infrastructure.getChargerSpecifications().values().stream()).write(path);
+
+ ChargingInfrastructureSpecificationDefaultImpl readInfrastructure = new ChargingInfrastructureSpecificationDefaultImpl();
+ new ChargerReader(readInfrastructure).readFile(path);
+
+ ChargerSpecification spec1 = readInfrastructure.getChargerSpecifications()
+ .get(Id.create("charger1", Charger.class));
+ assertEquals("type1", spec1.getChargerType());
+ assertEquals(Id.createLinkId("link1"), spec1.getLinkId());
+ assertEquals(1, spec1.getPlugCount());
+ assertEquals(1000.0, spec1.getPlugPower());
+
+ assertEquals("value1", (String) spec1.getAttributes().getAttribute("attribute1"));
+
+ ChargerSpecification spec2 = readInfrastructure.getChargerSpecifications()
+ .get(Id.create("charger2", Charger.class));
+ assertEquals("type2", spec2.getChargerType());
+ assertEquals(Id.createLinkId("link2"), spec2.getLinkId());
+ assertEquals(2, spec2.getPlugCount());
+ assertEquals(2000.0, spec2.getPlugPower());
+
+ assertEquals("value2", (String) spec2.getAttributes().getAttribute("attribute2"));
+ }
+}
diff --git a/contribs/freight/README.md b/contribs/freight/README.md
index afdcbcd4abc..746cdba1bc1 100644
--- a/contribs/freight/README.md
+++ b/contribs/freight/README.md
@@ -1,10 +1,25 @@
# Freight
-Package that plugs freight algorithms (programmed in external package jsprit) into matsim.
+This contrib contains the following packages:
+
+## Carriers
+(This is formally knows as 'freight contrib')
+
+Package that plugs vehicle routing problem algorithms (programmed in external package jsprit) into MATSim.
A good starting point for jsprit is [ https://github.com/graphhopper/jsprit](https://github.com/graphhopper/jsprit).
-For runnable code see, e.g., the packages org.matsim.contrib.freight.usecases.* above .
+For runnable code see, e.g., the packages org.matsim.contrib.freight.carriers.usecases.* above .
+
+## Logistics
+(This code comes from [https://github.com/matsim-vsp/logistics/](https://github.com/matsim-vsp/logistics/) )
+
+This code deals with creating logistics chains for freight transport.
+
+Here the decision agent is the logistics service provider (LSP) who decides on the logistics chain to be used for a given freight transport request.
+Therefore, it can use carriers (see above) and hubs.
+
+This package bases on work in the dfg-freight project.
\ No newline at end of file
diff --git a/contribs/freight/pom.xml b/contribs/freight/pom.xml
index cfd34b6d514..c1df7ab953a 100644
--- a/contribs/freight/pom.xml
+++ b/contribs/freight/pom.xml
@@ -55,15 +55,23 @@
org.matsim.contribroadpricing
- 2025.0-SNAPSHOT
+ ${project.parent.version}org.matsim.contribotfvis
- 2025.0-SNAPSHOT
+ ${project.parent.version}
+
+
+
+
+
+
+
+
org.mockitomockito-core
@@ -77,7 +85,7 @@
org.matsimmatsim-examples
- 2025.0-SNAPSHOT
+ ${project.parent.version}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/Carrier.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/Carrier.java
index 8ee9e1812e5..e80fbb6c9fa 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/Carrier.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/Carrier.java
@@ -21,13 +21,12 @@
package org.matsim.freight.carriers;
+import java.util.List;
+import java.util.Map;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.population.HasPlansAndId;
import org.matsim.utils.objectattributes.attributable.Attributable;
-import java.util.List;
-import java.util.Map;
-
/**
* A carrier.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierCapabilities.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierCapabilities.java
index fa14ddfd9bb..879017be0f4 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierCapabilities.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierCapabilities.java
@@ -21,12 +21,11 @@
package org.matsim.freight.carriers;
+import java.util.*;
import org.matsim.api.core.v01.Id;
import org.matsim.vehicles.Vehicle;
import org.matsim.vehicles.VehicleType;
-import java.util.*;
-
/**
* This contains the capabilities/resources a carrier has/can deploy.
*
@@ -65,7 +64,7 @@ public Builder setFleetSize(FleetSize fleetSize){
/**
* @deprecated Since the vehicle type is in the {@link CarrierVehicleTypes}
* container, it should not be duplicated here. It is also not written
- * to file when writing {@link CarrierPlanXmlWriterV2}.
+ * to file when writing.
*/
@Deprecated
public Builder addType( VehicleType type ){
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierImpl.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierImpl.java
index 8dcc53adc75..54bebb6b9d2 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierImpl.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierImpl.java
@@ -21,14 +21,13 @@
package org.matsim.freight.carriers;
-import org.matsim.api.core.v01.Id;
-import org.matsim.utils.objectattributes.attributable.Attributes;
-import org.matsim.utils.objectattributes.attributable.AttributesImpl;
-
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import org.matsim.api.core.v01.Id;
+import org.matsim.utils.objectattributes.attributable.Attributes;
+import org.matsim.utils.objectattributes.attributable.AttributesImpl;
/**
* This is a carrier that has capabilities and resources, jobs and plans to fulfill its obligations.
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierJob.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierJob.java
new file mode 100644
index 00000000000..3654fbff36a
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierJob.java
@@ -0,0 +1,19 @@
+package org.matsim.freight.carriers;
+
+import org.matsim.utils.objectattributes.attributable.Attributable;
+
+/**
+ * A job that a {@link Carrier} can do.
+ *
+ * In a first step this is more or less a marker interface.
+ *
+ * In the next steps it will be extended, as follows
+ * 1) existing common methods of {@link CarrierShipment} and {@link
+ * CarrierService} where moved up here
+ * 2) some similiar, but differently named methods of {@link
+ * CarrierShipment} and {@link CarrierService} were renamed to the same name and moved up here
+ * ...
+ * future) It maybe gets generalized in way, that we only have one job definition with 1 or 2
+ * location(s). This then defines, if jsprit takes the job as a service or as a shipment.
+ */
+public interface CarrierJob extends Attributable {}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlan.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlan.java
index 9c51aac159e..e1f56c19d4a 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlan.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlan.java
@@ -21,13 +21,12 @@
package org.matsim.freight.carriers;
+import java.util.Collection;
import org.matsim.api.core.v01.population.BasicPlan;
import org.matsim.utils.objectattributes.attributable.Attributable;
import org.matsim.utils.objectattributes.attributable.Attributes;
import org.matsim.utils.objectattributes.attributable.AttributesImpl;
-import java.util.Collection;
-
/**
*
* A specific plan of a carrier, and its score.
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanReaderV1.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanReaderV1.java
index 4e13ad599b6..4bb90047d86 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanReaderV1.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanReaderV1.java
@@ -21,6 +21,7 @@
package org.matsim.freight.carriers;
+import java.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -34,8 +35,6 @@
import org.matsim.vehicles.VehicleType;
import org.xml.sax.Attributes;
-import java.util.*;
-
/**
* A reader that reads carriers and their plans.
*
@@ -82,7 +81,7 @@ class CarrierPlanReaderV1 extends MatsimXmlParser {
* Constructs a reader with an empty carriers-container for the carriers to be constructed.
*
* @param carriers which is a map that stores carriers
- * @param carrierVehicleTypes
+ * @param carrierVehicleTypes which is a map that stores carrierVehicleTypes
*/
public CarrierPlanReaderV1( Carriers carriers, CarrierVehicleTypes carrierVehicleTypes ) {
super(ValidationType.DTD_OR_XSD);
@@ -188,7 +187,7 @@ public void startTag(String name, Attributes attributes, Stack context)
{
String vehicleId = attributes.getValue("vehicleId");
currentVehicle = vehicles.get(vehicleId);
- currentTourBuilder = Tour.Builder.newInstance();
+ currentTourBuilder = Tour.Builder.newInstance(Id.create("unknown", Tour.class));
break ;
}
case "leg":
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanWriter.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanWriter.java
index 3d7922d9489..888bfcf5289 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanWriter.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanWriter.java
@@ -22,9 +22,8 @@
package org.matsim.freight.carriers;
import com.google.inject.Inject;
-import org.matsim.utils.objectattributes.AttributeConverter;
-
import java.util.Map;
+import org.matsim.utils.objectattributes.AttributeConverter;
/**
* @author mrieser / Simunto
@@ -47,31 +46,6 @@ public void write(String filename) {
this.writeV2_1(filename);
}
- /**
- * @deprecated The underlining {@Link{CarrierPlanXmlWriterV1} is deprecated since April21
- */
- @Deprecated
- public void writeV1(String filename) {
- new CarrierPlanXmlWriterV1(this.carriers.getCarriers().values()).write(filename);
- }
-
-
- /**
- * Writes out the Carriers file in version 2.
- * Please use the method {@link #write(String)} instead to always ensure writing out to the newest format.
- *
- * @deprecated The underlining {@Link{CarrierPlanXmlWriterV2} is deprecated since Sep'22
- *
- * @param filename Name of the file that should be written.
- */
- @Deprecated public void writeV2(String filename) {
- CarrierPlanXmlWriterV2 writer = new CarrierPlanXmlWriterV2(this.carriers);
- if (this.attributeConverters != null) {
- writer.putAttributeConverters(this.attributeConverters);
- }
- writer.write(filename);
- }
-
/**
* Writes out the Carriers file in version 2.1.
* Please use the method {@link #write(String)} to always ensure writing out to the newest format.
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlParserV2.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlParserV2.java
index a63697cfab4..271871b0970 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlParserV2.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlParserV2.java
@@ -21,7 +21,10 @@
package org.matsim.freight.carriers;
+import static org.matsim.freight.carriers.CarrierConstants.*;
+
import com.google.inject.Inject;
+import java.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -40,10 +43,6 @@
import org.matsim.vehicles.VehicleType;
import org.xml.sax.Attributes;
-import java.util.*;
-
-import static org.matsim.freight.carriers.CarrierConstants.*;
-
class CarrierPlanXmlParserV2 extends MatsimXmlParser {
public static final Logger logger = LogManager.getLogger(CarrierPlanXmlParserV2.class);
@@ -78,7 +77,7 @@ class CarrierPlanXmlParserV2 extends MatsimXmlParser {
* Constructs a reader with an empty carriers-container for the carriers to be constructed.
*
* @param carriers which is a map that stores carriers
- * @param carrierVehicleTypes
+ * @param carrierVehicleTypes which is a map that stores vehicle types
*/
CarrierPlanXmlParserV2( Carriers carriers, CarrierVehicleTypes carrierVehicleTypes ) {
super(ValidationType.XSD_ONLY);
@@ -234,7 +233,7 @@ public void startTag(String name, Attributes atts, Stack context) {
currentVehicle = vehicles.get(vehicleId);
if (currentVehicle == null)
throw new IllegalStateException("vehicle to vehicleId " + vehicleId + " is missing.");
- currentTourBuilder = Tour.Builder.newInstance();
+ currentTourBuilder = Tour.Builder.newInstance(Id.create("unknown", Tour.class));
break;
case "leg":
String depTime = atts.getValue("expected_dep_time");
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlParserV2_1.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlParserV2_1.java
index 8503eb4acad..9c3f2b7a1e6 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlParserV2_1.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlParserV2_1.java
@@ -21,7 +21,10 @@
package org.matsim.freight.carriers;
+import static org.matsim.freight.carriers.CarrierConstants.*;
+
import com.google.inject.Inject;
+import java.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -40,10 +43,6 @@
import org.matsim.vehicles.VehicleType;
import org.xml.sax.Attributes;
-import java.util.*;
-
-import static org.matsim.freight.carriers.CarrierConstants.*;
-
class CarrierPlanXmlParserV2_1 extends MatsimXmlParser {
public static final Logger logger = LogManager.getLogger(CarrierPlanXmlParserV2_1.class);
@@ -77,7 +76,7 @@ class CarrierPlanXmlParserV2_1 extends MatsimXmlParser {
* Constructs a reader with an empty carriers-container for the carriers to be constructed.
*
* @param carriers which is a map that stores carriers
- * @param carrierVehicleTypes
+ * @param carrierVehicleTypes which is a map that stores vehicle types
*/
CarrierPlanXmlParserV2_1(Carriers carriers, CarrierVehicleTypes carrierVehicleTypes ) {
super(ValidationType.XSD_ONLY);
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlReader.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlReader.java
index 5155f5bdebc..4842ab434f9 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlReader.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlReader.java
@@ -21,6 +21,9 @@
package org.matsim.freight.carriers;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Stack;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.core.api.internal.MatsimReader;
@@ -28,10 +31,6 @@
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Stack;
-
/**
* A reader that reads carriers and their plans.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlWriterV1.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlWriterV1.java
deleted file mode 100644
index 510ea9b1ac3..00000000000
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlWriterV1.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * *********************************************************************** *
- * project: org.matsim.*
- * *********************************************************************** *
- * *
- * copyright : (C) by the members listed in the COPYING, *
- * LICENSE and WARRANTY file. *
- * email : info at matsim dot org *
- * *
- * *********************************************************************** *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * See also COPYING, LICENSE and WARRANTY file *
- * *
- * ***********************************************************************
- *
- */
-
-package org.matsim.freight.carriers;
-
-import com.graphhopper.jsprit.core.problem.job.Shipment;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.matsim.api.core.v01.Id;
-import org.matsim.api.core.v01.network.Link;
-import org.matsim.core.population.routes.NetworkRoute;
-import org.matsim.core.utils.io.MatsimXmlWriter;
-import org.matsim.core.utils.misc.Time;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A writer that writes carriers and their plans in a xml-file.
- *
- * @author sschroeder
- *
- * @deprecated Use {@link CarrierPlanWriter} instead which writes the newest format
- */
-@Deprecated
-public class CarrierPlanXmlWriterV1 extends MatsimXmlWriter {
-
- @SuppressWarnings("unused")
- private static final Logger logger = LogManager.getLogger(CarrierPlanXmlWriterV1.class);
-
- private final Collection carriers;
- private int idCounter = 0;
- private final Map> registeredShipments = new HashMap<>();
-
- /**
- * Constructs the writer with the carriers to be written.
- *
- * @param carriers to be written
- */
- public CarrierPlanXmlWriterV1(Collection carriers) {
- super();
- this.carriers = carriers;
- }
-
- /**
- * Writes carriers and their plans into a xml-file.
- *
- * @param filename should be the target xml-file
- */
- public void write(String filename) {
- logger.info("write carrier plans");
- try {
- openFile(filename);
- writeXmlHead();
- startCarriers(this.writer);
- for (Carrier carrier : carriers) {
- startCarrier(carrier, this.writer);
- writeVehicles(carrier, this.writer);
- writeShipments(carrier, this.writer);
- writePlans(carrier, this.writer);
- endCarrier(this.writer);
- }
- endCarriers(this.writer);
- close();
- logger.info("done");
- } catch (IOException e) {
- e.printStackTrace();
- logger.error(e);
- System.exit(1);
- }
- }
-
- private void startCarriers(BufferedWriter writer) throws IOException {
- writer.write("\t\n");
- }
-
- private void startCarrier(Carrier carrier, BufferedWriter writer)
- throws IOException {
- writer.write("\t\t\n");
- }
-
- private void writeVehicles(Carrier carrier, BufferedWriter writer)
- throws IOException {
- writer.write("\t\t\t\n");
- for (CarrierVehicle v : carrier.getCarrierCapabilities().getCarrierVehicles().values()) {
- writer.write("\t\t\t\t\n");
- }
- writer.write("\t\t\t\n\n");
- }
-
- private void writeShipments(Carrier carrier, BufferedWriter writer)
- throws IOException {
- writer.write("\t\t\t\n");
- for (CarrierShipment s : carrier.getShipments().values()) {
- // CarrierShipment s = contract.getShipment();
- Id shipmentId = Id.create(++idCounter, Shipment.class);
- registeredShipments.put(s, shipmentId);
- writer.write("\t\t\t\t\n");
- }
- writer.write("\t\t\t\n\n");
- }
-
- private String getTime(double time) {
- return Time.writeTime(time);
- }
-
- private void writePlans(Carrier carrier, BufferedWriter writer)
- throws IOException {
- if (carrier.getSelectedPlan() == null) {
- return;
- }
-
- for(CarrierPlan plan : carrier.getPlans()){
- writer.write("\t\t\t\n");
-
- for (ScheduledTour tour : plan.getScheduledTours()) {
- writer.write("\t\t\t\t\n");
- writer.write("\t\t\t\t\t\n");
- for (Tour.TourElement tourElement : tour.getTour().getTourElements()) {
- if (tourElement instanceof Tour.Leg leg) {
- writer.write("\t\t\t\t\t");
- if (leg.getRoute() != null) {
- writer.write("\n");
- writer.write("\t\t\t\t\t\t");
- boolean firstLink = true;
- for (Id id : ((NetworkRoute) leg.getRoute()).getLinkIds()) {
- if (firstLink) {
- writer.write(id.toString());
- firstLink = false;
- } else {
- writer.write(" " + id.toString());
- }
- }
- writer.write("\n");
- writer.write("\t\t\t\t\t\n");
- } else {
- writer.write("\n");
- }
- }
- if (tourElement instanceof Tour.ShipmentBasedActivity act) {
- writer.write("\t\t\t\t\t\n");
- }
-
- }
- writer.write("\t\t\t\t\t\n");
- writer.write("\t\t\t\t\n");
- }
- writer.write("\t\t\t\n\n");
- }
-
- }
-
- private void endCarrier(BufferedWriter writer) throws IOException {
- writer.write("\t\t\n\n");
- registeredShipments.clear();
- }
-
- private void endCarriers(BufferedWriter writer) throws IOException {
- writer.write("\t\n");
-
- }
-}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlWriterV2.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlWriterV2.java
deleted file mode 100644
index b78af8aa3e6..00000000000
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlWriterV2.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * *********************************************************************** *
- * project: org.matsim.*
- * *********************************************************************** *
- * *
- * copyright : (C) by the members listed in the COPYING, *
- * LICENSE and WARRANTY file. *
- * email : info at matsim dot org *
- * *
- * *********************************************************************** *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * See also COPYING, LICENSE and WARRANTY file *
- * *
- * ***********************************************************************
- *
- */
-
-package org.matsim.freight.carriers;
-
-import com.google.inject.Inject;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.matsim.api.core.v01.Id;
-import org.matsim.api.core.v01.network.Link;
-import org.matsim.core.population.routes.NetworkRoute;
-import org.matsim.core.utils.collections.Tuple;
-import org.matsim.core.utils.io.MatsimXmlWriter;
-import org.matsim.core.utils.misc.Time;
-import org.matsim.freight.carriers.Tour.Leg;
-import org.matsim.freight.carriers.Tour.ServiceActivity;
-import org.matsim.freight.carriers.Tour.ShipmentBasedActivity;
-import org.matsim.freight.carriers.Tour.TourElement;
-import org.matsim.utils.objectattributes.AttributeConverter;
-import org.matsim.utils.objectattributes.attributable.AttributesXmlWriterDelegate;
-import org.matsim.vehicles.VehicleType;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * A writer that writes carriers and their plans in a xml-file.
- *
- * @author sschroeder
- *
- * @deprecated Use {@link CarrierPlanWriter} instead which writes the newest format
- */
-@Deprecated
-public class CarrierPlanXmlWriterV2 extends MatsimXmlWriter {
-
- @SuppressWarnings("unused")
- private static final Logger logger = LogManager.getLogger(CarrierPlanXmlWriterV2.class);
-
- private final Collection carriers;
-
- private final Map> registeredShipments = new HashMap<>();
-
- private final Map> serviceMap = new HashMap<>();
-
- private final AttributesXmlWriterDelegate attributesWriter = new AttributesXmlWriterDelegate();
- private final List> atts = new ArrayList<>();
-
-
- /**
- * Constructs the writer with the carriers to be written.
- *
- * @param carriers to be written
- */
- public CarrierPlanXmlWriterV2(Carriers carriers) {
- super();
- this.carriers = carriers.getCarriers().values();
- }
-
- @Inject
- public void putAttributeConverters( final Map, AttributeConverter>> converters ) {
- attributesWriter.putAttributeConverters( converters );
- }
-
- /**
- * Writes carriers and their plans into a xml-file.
- *
- * @param filename should be the target xml-file
- */
- public void write(String filename) {
- logger.info("write carrier plans");
- try {
- openFile(filename);
- writeXmlHead();
-
- startCarriers(this.writer);
- for (Carrier carrier : carriers) {
- startCarrier(carrier, this.writer);
- writeVehiclesAndTheirTypes(carrier, this.writer);
- writeShipments(carrier, this.writer);
- writeServices(carrier,this.writer);
- writePlans(carrier, this.writer);
- endCarrier(this.writer);
- }
- endCarriers(this.writer);
- close();
- logger.info("done");
- } catch (IOException e) {
- e.printStackTrace();
- logger.error(e);
- System.exit(1);
- }
- }
-
- private void startCarriers(BufferedWriter writer) throws IOException {
- writer.write("\t\n");
- }
-
- private void startCarrier(Carrier carrier, BufferedWriter writer)
- throws IOException {
- writer.write("\t\t\n");
- attributesWriter.writeAttributes("\t\t\t", writer, carrier.getAttributes());
- }
-
- private void writeVehiclesAndTheirTypes(Carrier carrier, BufferedWriter writer)throws IOException {
- writer.write("\t\t\t\n");
- //vehicles
- writer.write("\t\t\t\t\n");
- for (CarrierVehicle v : carrier.getCarrierCapabilities().getCarrierVehicles().values()) {
- Id vehicleTypeId = v.getVehicleTypeId();
- if(vehicleTypeId == null) vehicleTypeId = v.getType() == null ? null : v.getType().getId();
- if(vehicleTypeId == null) throw new IllegalStateException("vehicleTypeId is missing.");
- writer.write("\t\t\t\t\t\n");
- }
- writer.write("\t\t\t\t\n\n");
- writer.write("\t\t\t\n\n");
- }
-
- private void writeShipments(Carrier carrier, BufferedWriter writer) throws IOException {
- if(carrier.getShipments().isEmpty()) return;
- writer.write("\t\t\t\n");
- for (CarrierShipment s : carrier.getShipments().values()) {
- // CarrierShipment s = contract.getShipment();
- Id shipmentId = s.getId();
- registeredShipments.put(s, shipmentId);
- writer.write("\t\t\t\t\n");
- } else {
- writer.write("\">\n");
- this.attributesWriter.writeAttributes("\t\t\t\t\t", writer, s.getAttributes());
- writer.write("\t\t\t\t\n");
- }
- }
- writer.write("\t\t\t\n\n");
- }
-
- private void writeServices(Carrier carrier, BufferedWriter writer) throws IOException {
- writer.write("\t\t\t\n");
- for (CarrierService s : carrier.getServices().values()) {
- serviceMap.put(s, s.getId());
- writer.write("\t\t\t\t\n");
- } else {
- writer.write("\">\n");
- this.attributesWriter.writeAttributes("\t\t\t\t\t", writer, s.getAttributes());
- writer.write("\t\t\t\t\n");
- }
-
- }
- writer.write("\t\t\t\n\n");
-
- }
-
- private String getTime(double time) {
- return Time.writeTime(time);
- }
-
- private void writePlans(Carrier carrier, BufferedWriter writer)
- throws IOException {
- if (carrier.getSelectedPlan() == null) {
- return;
- }
-
- for(CarrierPlan plan : carrier.getPlans()){
- writer.write("\t\t\t\n");
-
- for (ScheduledTour tour : plan.getScheduledTours()) {
- writer.write("\t\t\t\t\n");
- writer.write("\t\t\t\t\t\n");
- for (TourElement tourElement : tour.getTour().getTourElements()) {
- if (tourElement instanceof Leg leg) {
- writer.write("\t\t\t\t\t");
- if (leg.getRoute() != null) {
- writer.write("\n");
- writer.write("\t\t\t\t\t\t");
- boolean firstLink = true;
- for (Id id : ((NetworkRoute) leg.getRoute())
- .getLinkIds()) {
- if (firstLink) {
- writer.write(id.toString());
- firstLink = false;
- } else {
- writer.write(" " + id.toString());
- }
- }
- writer.write("\n");
- writer.write("\t\t\t\t\t\n");
- } else {
- writer.write("\n");
- }
- }
- else if (tourElement instanceof ShipmentBasedActivity act) {
- writer.write("\t\t\t\t\t\n");
- }
- else if (tourElement instanceof ServiceActivity act){
- writer.write("\t\t\t\t\t\n");
- }
-
- }
- writer.write("\t\t\t\t\t\n");
- writer.write("\t\t\t\t\n");
- }
- writer.write("\t\t\t\n\n");
- }
-
- }
-
- private void endCarrier(BufferedWriter writer) throws IOException {
- writer.write("\t\t\n\n");
- registeredShipments.clear();
- }
-
- private void endCarriers(BufferedWriter writer) throws IOException {
- writer.write("\t\n");
-
- }
-}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlWriterV2_1.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlWriterV2_1.java
index 92699982378..6195fb3834f 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlWriterV2_1.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierPlanXmlWriterV2_1.java
@@ -21,7 +21,16 @@
package org.matsim.freight.carriers;
+import static org.matsim.freight.carriers.CarrierConstants.*;
+
import com.google.inject.Inject;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -34,16 +43,6 @@
import org.matsim.utils.objectattributes.attributable.AttributesXmlWriterDelegate;
import org.matsim.vehicles.VehicleType;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import static org.matsim.freight.carriers.CarrierConstants.*;
-
/**
* A writer that writes carriers and their plans in a xml-file.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierService.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierService.java
index b7106fa6de9..69a5ce75e42 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierService.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierService.java
@@ -27,8 +27,7 @@
import org.matsim.utils.objectattributes.attributable.Attributes;
import org.matsim.utils.objectattributes.attributable.AttributesImpl;
-
-public final class CarrierService implements Attributable {
+public final class CarrierService implements CarrierJob {
public static class Builder {
@@ -56,10 +55,10 @@ public Builder setName(String name){
}
/**
- * By default it is [0.0,Integer.MaxValue].
+ * By default, it is [0.0,Integer.MaxValue].
*
- * @param serviceDuration
- * @return
+ * @param serviceDuration duration of the service
+ * @return the builder
*/
public Builder setServiceDuration(double serviceDuration){
this.serviceTime = serviceDuration;
@@ -72,8 +71,8 @@ public Builder setServiceDuration(double serviceDuration){
*
Note that the time-window restricts the start-time of the service (i.e. serviceActivity). If one works with hard time-windows (which means that
* time-windows must be met) than the service is allowed to start between startTimeWindow.getStart() and startTimeWindow.getEnd().
*
- * @param startTimeWindow
- * @return
+ * @param startTimeWindow time-window for the service
+ * @return the builder
*/
public Builder setServiceStartTimeWindow(TimeWindow startTimeWindow){
this.timeWindow = startTimeWindow;
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierShipment.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierShipment.java
index 9472ffaac91..b378db94620 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierShipment.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierShipment.java
@@ -36,7 +36,7 @@
* @author sschroeder
*
*/
-public final class CarrierShipment implements Attributable {
+public final class CarrierShipment implements CarrierJob {
/**
* A builder that builds shipments.
@@ -54,10 +54,10 @@ public static class Builder {
*
The builder is init with the shipment's origin (from), destination (to) and with the shipment's size.
* The default-value for serviceTime is 0.0. The default-value for a timeWindow is [start=0.0, end=Double.maxValue()].
*
- * @param from
- * @param to
- * @param size
- * @return the builder
+ * @param from the origin
+ * @param to the destination
+ * @param size size of the shipment
+ * @return the builder
*/
@Deprecated
public static Builder newInstance(Id from, Id to, int size){
@@ -70,11 +70,11 @@ public static Builder newInstance(Id from, Id to, int size){
*
The builder is init with the shipment's origin (from), destination (to) and with the shipment's size.
* The default-value for serviceTime is 0.0. The default-value for a timeWindow is [start=0.0, end=Double.maxValue()].
*
- * @param id
- * @param from
- * @param to
- * @param size
- * @return the builder
+ * @param id the id of the shipment
+ * @param from the origin
+ * @param to the destination
+ * @param size size of the shipment
+ * @return the builder
*/
public static Builder newInstance(Id id, Id from, Id to, int size){
return new Builder(id, from,to,size);
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicle.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicle.java
index 917052a65fe..7d317af7d26 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicle.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicle.java
@@ -46,8 +46,8 @@ public final class CarrierVehicle implements Vehicle {
*
* The default values for other fields (being implicitly set) are [capacity=0][earliestStart=0.0][latestEnd=Integer.MaxValue()].
*
- * @param vehicleId
- * @param locationId
+ * @param vehicleId the vehicle id
+ * @param locationId the location id
* @return CarrierVehicle
* @see CarrierVehicle
*/
@@ -68,9 +68,9 @@ public static class Builder {
*
* The default values for other fields (being implicitly set) are [capacity=0][earliestStart=0.0][latestEnd=Integer.MaxValue()].
*
- * @param vehicleId
- * @param locationId
- * @param vehicleType
+ * @param vehicleId the vehicle id
+ * @param locationId the location id
+ * @param vehicleType the vehicle type
* @return a new vehicle builder
*/
public static Builder newInstance( Id vehicleId, Id locationId, VehicleType vehicleType ){
@@ -91,29 +91,6 @@ public Builder( Id vehicleId, Id locationId, VehicleType vehicleT
this.type = vehicleType;
}
- /**
- * @param type
- * @deprecated The vehicleType need now to be set in the constructor kai/kai jan'22
- */
- @Deprecated
- public Builder setType( VehicleType type ){
- log.warn(".setType has no functionality anymore and is deprecated");
-// this.type=type;
- return this;
- }
-
- /**
- * @param typeId
- * @deprecated The vehicleTypeId is no longer needed and was confusing -> Use getType().getId kai/kai jan'22
- */
- @Deprecated
- public Builder setTypeId(Id typeId ){
- log.warn(".setTypeId has no functionality anymore and is deprecated");
-// this.typeId = typeId;
- return this;
- }
-
-
public Builder setEarliestStart(double earliestStart){
this.earliestStart=earliestStart;
return this;
@@ -151,10 +128,7 @@ private CarrierVehicle(Builder builder){
public Id getLinkId() {
return locationId;
}
- /**
- * @deprecated -- please inline. kai, jul'22
- */
- @Deprecated public Id getLocation() { return getLinkId(); }
+
@Override
public Id getId() {
return vehicleId;
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleType.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleType.java
index 16b7e92a03d..7033a3454d7 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleType.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleType.java
@@ -57,30 +57,13 @@ public static class Builder {
*
* The defaults are [fix=0.0][perDistanceUnit=1.0][perTimeUnit=0.0].
*
- * @param typeId
+ * @param typeId the type id
* @return a type builder
*/
public static Builder newInstance(Id typeId){
return new Builder(typeId);
}
- /**
- * Returns a new instance of builder initialized with the typeId and the values the given from existing CarrierVehicleType.
- *
- * Can be used for create a new, modified CarrierVehicleType basing on an existing one.
- * Values can be changed within the builder afterwards.
- *
- * @param carrierVehicleType
- * @param typeId
- * @return a type builder
- *
- * @deprecated Use {@link #newInstance(Id)} instead
- */
- @Deprecated(since = "sep'19", forRemoval = true)
- public static Builder newInstance(Id typeId, CarrierVehicleType carrierVehicleType){
- throw new RuntimeException("not implemented") ;
- }
-
private Builder(Id typeId){
this.delegate = VehicleUtils.getFactory().createVehicleType( typeId ) ;
}
@@ -89,8 +72,8 @@ private Builder(Id typeId){
* Sets fixed costs of vehicle.
*
*
By default it is 0.
- * @param fix
- * @return
+ * @param fix fixed costs
+ * @return this builder
*/
public Builder setFixCost(double fix){
this.delegate.getCostInformation().setFixedCost( fix ) ;
@@ -102,8 +85,8 @@ public Builder setFixCost(double fix){
*
*
By default it is 1.
*
- * @param perDistanceUnit
- * @return
+ * @param perDistanceUnit costs per distance-unit
+ * @return this builder
*/
public Builder setCostPerDistanceUnit(double perDistanceUnit){
this.delegate.getCostInformation().setCostsPerMeter( perDistanceUnit ) ;
@@ -115,8 +98,8 @@ public Builder setCostPerDistanceUnit(double perDistanceUnit){
*
*
By default it is 0.
*
- * @param perTimeUnit
- * @return
+ * @param perTimeUnit costs per time-unit
+ * @return this builder
*/
public Builder setCostPerTimeUnit(double perTimeUnit){
this.delegate.getCostInformation().setCostsPerSecond( perTimeUnit ) ;
@@ -126,8 +109,8 @@ public Builder setCostPerTimeUnit(double perTimeUnit){
/**
* Sets description.
*
- * @param description
- * @return this builder
+ * @param description the description
+ * @return this builder
*/
public Builder setDescription(String description){
this.delegate.setDescription( description ) ;
@@ -139,8 +122,8 @@ public Builder setDescription(String description){
*
*
By default, the capacity is 0.
*
- * @param capacity
- * @return this builder
+ * @param capacity the capacity of the vehicle-type
+ * @return this builder
*/
public Builder setCapacity(int capacity){
this.delegate.getCapacity().setOther( capacity );
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeReader.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeReader.java
index f10e5fc9bd5..0d8d070c5c6 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeReader.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeReader.java
@@ -21,6 +21,10 @@
package org.matsim.freight.carriers;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Map;
+import java.util.Stack;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -33,11 +37,6 @@
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Map;
-import java.util.Stack;
-
/**
* Reader reading carrierVehicleTypes from a xml-file.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeReaderV1.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeReaderV1.java
index 61718d49850..f1cb66dac45 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeReaderV1.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeReaderV1.java
@@ -21,9 +21,11 @@
package org.matsim.freight.carriers;
+import java.util.Stack;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.TransportMode;
import org.matsim.core.gbl.Gbl;
import org.matsim.core.utils.io.MatsimXmlParser;
import org.matsim.vehicles.CostInformation;
@@ -32,8 +34,6 @@
import org.matsim.vehicles.VehicleUtils;
import org.xml.sax.Attributes;
-import java.util.Stack;
-
class CarrierVehicleTypeReaderV1 extends MatsimXmlParser {
private static final Logger log = LogManager.getLogger(CarrierVehicleTypeReaderV1.class) ;
@@ -54,6 +54,9 @@ public void startTag( String name, Attributes attributes, Stack context
if(name.equals("vehicleType")){
Id currentTypeId = Id.create( attributes.getValue( "id" ), VehicleType.class );
this.currentType = VehicleUtils.getFactory().createVehicleType( currentTypeId ) ;
+ // If no network mode is given, assume car, this is to be backwards compatible
+ // The v2 format will not make this assumption, and the network mode will be required
+ this.currentType.setNetworkMode(TransportMode.car);
}
if(name.equals("allowableWeight")){
// String weight = atts.getValue("weight");
@@ -69,9 +72,8 @@ public void startTag( String name, Attributes attributes, Stack context
}
if(name.equals("engineInformation")){
EngineInformation engineInfo = this.currentType.getEngineInformation() ;
- VehicleUtils.setFuelConsumption(this.currentType, Double.parseDouble(attributes.getValue( "gasConsumption" )));
- engineInfo.setFuelConsumption( Double.parseDouble( attributes.getValue( "gasConsumption" ) ) );
- engineInfo.setFuelType( EngineInformation.FuelType.valueOf( attributes.getValue( "fuelType" ) ) );
+ VehicleUtils.setHbefaTechnology(engineInfo, attributes.getValue( "fuelType"));
+ VehicleUtils.setFuelConsumptionLitersPerMeter(engineInfo, Double.parseDouble(attributes.getValue( "gasConsumption" )));
}
if(name.equals("costInformation")){
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeWriter.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeWriter.java
index 4fbd8d68bbb..573f8441cae 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeWriter.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeWriter.java
@@ -21,6 +21,7 @@
package org.matsim.freight.carriers;
+import java.util.Map;
import org.matsim.api.core.v01.Id;
import org.matsim.core.api.internal.MatsimWriter;
import org.matsim.vehicles.MatsimVehicleWriter;
@@ -28,8 +29,6 @@
import org.matsim.vehicles.VehicleUtils;
import org.matsim.vehicles.Vehicles;
-import java.util.Map;
-
/**
* A writer that writes carriers and their plans in a xml-file.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeWriterV1.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeWriterV1.java
deleted file mode 100644
index 823123e916a..00000000000
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeWriterV1.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * *********************************************************************** *
- * project: org.matsim.*
- * *********************************************************************** *
- * *
- * copyright : (C) by the members listed in the COPYING, *
- * LICENSE and WARRANTY file. *
- * email : info at matsim dot org *
- * *
- * *********************************************************************** *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * See also COPYING, LICENSE and WARRANTY file *
- * *
- * ***********************************************************************
- *
- */
-
-package org.matsim.freight.carriers;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.matsim.core.utils.io.MatsimXmlWriter;
-import org.matsim.vehicles.CostInformation;
-import org.matsim.vehicles.EngineInformation;
-import org.matsim.vehicles.VehicleType;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-
-@Deprecated // only there if someone insists on writing V1
-public final class CarrierVehicleTypeWriterV1 extends MatsimXmlWriter {
-
- @SuppressWarnings("unused")
- private static final Logger logger = LogManager.getLogger(CarrierVehicleTypeWriter.class );
-
- private final CarrierVehicleTypes vehicleTypes;
-
-
- public CarrierVehicleTypeWriterV1(CarrierVehicleTypes carrierVehicleTypes) {
- super();
- this.vehicleTypes = carrierVehicleTypes;
- }
-
-
- public void write(String filename) {
- logger.info("write vehicle-types");
- try {
- openFile(filename);
- writeXmlHead();
- writeTypes(this.writer);
- close();
- logger.info("done");
- } catch ( IOException e) {
- e.printStackTrace();
- logger.error(e);
- System.exit(1);
- }
- }
-
- private void writeTypes( BufferedWriter writer )throws IOException {
- writer.write("\t\n");
- for( VehicleType type : vehicleTypes.getVehicleTypes().values()){
- writer.write("\t\t\n");
- writer.write("\t\t\t" + type.getDescription() + "\n");
- EngineInformation engineInformation = type.getEngineInformation();
- if(engineInformation != null && !engineInformation.getAttributes().isEmpty()) {
- writer.write("\t\t\t\n");
- }
- writer.write("\t\t\t" + type.getCapacity().getWeightInTons() + "\n" );
- CostInformation vehicleCostInformation = type.getCostInformation();
- if(vehicleCostInformation == null) throw new IllegalStateException("vehicleCostInformation is missing.");
- writer.write("\t\t\t\n");
- writer.write("\t\t\n");
- }
- writer.write("\t\n\n");
- }
-
-
-
-}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypes.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypes.java
index e9900cdc6cb..0250412938a 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypes.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypes.java
@@ -21,11 +21,10 @@
package org.matsim.freight.carriers;
-import org.matsim.api.core.v01.Id;
-import org.matsim.vehicles.VehicleType;
-
import java.util.HashMap;
import java.util.Map;
+import org.matsim.api.core.v01.Id;
+import org.matsim.vehicles.VehicleType;
/**
* VehicleTypeContainer mapping all vehicleTypes.
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/Carriers.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/Carriers.java
index f13f0bc56ae..4512008b9e8 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/Carriers.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/Carriers.java
@@ -21,13 +21,12 @@
package org.matsim.freight.carriers;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.matsim.api.core.v01.Id;
-
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.matsim.api.core.v01.Id;
/**
* A container that maps carriers.
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarriersUtils.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarriersUtils.java
index 7c8e7220e3e..e99be9d98db 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarriersUtils.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarriersUtils.java
@@ -28,6 +28,10 @@
import com.graphhopper.jsprit.core.problem.job.Shipment;
import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import com.graphhopper.jsprit.core.util.Solutions;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.management.InvalidAttributeValueException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -44,11 +48,6 @@
import org.matsim.vehicles.Vehicle;
import org.matsim.vehicles.VehicleType;
-import javax.management.InvalidAttributeValueException;
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.AtomicInteger;
-
public class CarriersUtils {
static final String CARRIER_VEHICLE = "carrierVehicle";
@@ -338,7 +337,7 @@ public static Carriers getOrCreateCarriers(Scenario scenario) {
public static Carriers addOrGetCarriers(Scenario scenario) {
// I have separated getOrCreateCarriers and getCarriers, since when the
- // controler is started, it is better to fail if the carriers are not found.
+ // controller is started, it is better to fail if the carriers are not found.
// kai, oct'19
Carriers carriers = (Carriers) scenario.getScenarioElement(CARRIERS);
if (carriers == null) {
@@ -382,8 +381,6 @@ public static void loadCarriersAccordingToFreightConfig(Scenario scenario) {
Carriers carriers = addOrGetCarriers(scenario); // also registers with scenario
new CarrierPlanXmlReader(carriers, vehTypes).readURL(
IOUtils.extendUrl(scenario.getConfig().getContext(), freightCarriersConfigGroup.getCarriersFile()));
-
-// new CarrierVehicleTypeLoader( carriers ).loadVehicleTypes( vehTypes );
}
/**
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/FreightCarriersConfigGroup.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/FreightCarriersConfigGroup.java
index 1aed1a936f2..2474df19550 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/FreightCarriersConfigGroup.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/FreightCarriersConfigGroup.java
@@ -22,11 +22,10 @@
package org.matsim.freight.carriers;
import jakarta.validation.constraints.Positive;
-import org.matsim.core.config.ConfigGroup;
-import org.matsim.core.config.ReflectiveConfigGroup;
-
import java.net.URL;
import java.util.Map;
+import org.matsim.core.config.ConfigGroup;
+import org.matsim.core.config.ReflectiveConfigGroup;
public class FreightCarriersConfigGroup extends ReflectiveConfigGroup {
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/ScheduledTour.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/ScheduledTour.java
index 6a133ebc71c..84eeb1907a1 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/ScheduledTour.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/ScheduledTour.java
@@ -37,9 +37,9 @@ public class ScheduledTour {
*
Look at the builder. It might be easier to build a scheduled tour.
* You get the builder this way: ScheduledTour.Builder.newInstance(carrierVehicle).
*
- * @param tour
- * @param vehicle
- * @param departureTime
+ * @param tour The scheduled tour.
+ * @param vehicle The vehicle for the tour.
+ * @param departureTime The time when the vehicle starts the tour.
* @return a scheduledTour
* @see ScheduledTour
*/
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/TimeWindow.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/TimeWindow.java
index 8c5e9fc0d25..1eadbe077c0 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/TimeWindow.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/TimeWindow.java
@@ -24,7 +24,6 @@
import org.matsim.core.utils.misc.Time;
-
/**
* Q: What happens/should happen if the time window is not sufficient to unload, or
* the vehicle arrives after the time window?
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/Tour.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/Tour.java
index cb522e857fb..55f72325237 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/Tour.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/Tour.java
@@ -21,6 +21,7 @@
package org.matsim.freight.carriers;
+import java.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -30,8 +31,6 @@
import org.matsim.core.population.routes.NetworkRoute;
import org.matsim.core.population.routes.RouteUtils;
-import java.util.*;
-
/**
* This is a tour of a carrier which is a sequence of activities and legs.
*
@@ -62,21 +61,6 @@ public static class Builder {
private End end;
- /**
- * Returns a new tour builder.
- *
- * @deprecated
- * Please use {@link #newInstance(Id)} instead. kmt sep'22
- *
- *
- *
- * @return the builder including "unknown" as tourId
- */
- @Deprecated
- public static Builder newInstance(){
- return new Builder(Id.create("unknown", Tour.class));
- }
-
/**
* Returns a new tour builder.
* This now also includes an Id for this tour.
@@ -98,8 +82,8 @@ private Builder(Id tourId) {
*
*
Tour start should correspond to the locationId of the vehicle that runs the tour.
*
- * @param startLinkId
- * @return the builder again
+ * @param startLinkId linkId of the start location
+ * @return the builder again
*/
public Builder scheduleStart(Id startLinkId) {
scheduleStart(startLinkId, TimeWindow.newInstance(0.0, Double.MAX_VALUE));
@@ -121,7 +105,7 @@ public void scheduleEnd(Id endLinkId, TimeWindow timeWindow){
/**
* Schedules the end of the tour (in terms of locationId).
*
- * @param endLinkId
+ * @param endLinkId linkId of the end location
*/
public void scheduleEnd(Id endLinkId) {
scheduleEnd(endLinkId, TimeWindow.newInstance(0.0, Double.MAX_VALUE));
@@ -132,8 +116,8 @@ public void scheduleEnd(Id endLinkId) {
*
*
Consider that a leg follows an activity. Otherwise, an exception occurs.
*
- * @param leg
- * @throws IllegalStateException if leg is null or if previous element is not an activity.
+ * @param leg the leg to be added
+ * @throws IllegalStateException if leg is null or if previous element is not an activity.
*/
public Builder addLeg(Leg leg) {
Gbl.assertNotNull(leg);
@@ -156,9 +140,9 @@ public Leg createLeg(Route route, double dep_time, double transportTime) {
/**
* Inserts leg at the beginning of a tour.
*
- * @param leg
- * @return the builder
- * @throws IllegalStateException if leg is null
+ * @param leg the leg to be inserted
+ * @return the builder
+ * @throws IllegalStateException if leg is null
*/
@Deprecated
public Builder insertLegAtBeginning(Leg leg) {
@@ -170,9 +154,9 @@ public Builder insertLegAtBeginning(Leg leg) {
/**
* Schedules a pickup of the shipment right at the beginning of the tour.
*
- * @param shipment
- * @return the builder
- * @throws IllegalStateException if shipment is null or shipment has already been picked up.
+ * @param shipment the shipment to be picked up
+ * @return the builder
+ * @throws IllegalStateException if shipment is null or shipment has already been picked up.
*/
@Deprecated
public Builder schedulePickupAtBeginning(CarrierShipment shipment) {
@@ -218,8 +202,8 @@ private void assertLastElementIsLeg() {
/**
* Schedules a delivery of a shipment, i.e. adds a delivery activity to current tour.
*
- * @param shipment
- * @throws IllegalStateException if shipment is null or if shipment has not been picked up yet or if last element is not a leg.
+ * @param shipment the shipment to be delivered
+ * @throws IllegalStateException if shipment is null or if shipment has not been picked up yet or if last element is not a leg.
*/
public void scheduleDelivery(CarrierShipment shipment) {
Gbl.assertNotNull(shipment);
@@ -272,10 +256,10 @@ public Leg createLeg() {
/**
* Creates and returns a network route.
*
- * @param startLinkId
- * @param linkIds
- * @param endLinkId
- * @return NetworkRoute
+ * @param startLinkId start link id
+ * @param linkIds list of link ids that form the route
+ * @param endLinkId end link id
+ * @return NetworkRoute
* @see NetworkRoute
*/
public NetworkRoute createRoute(Id startLinkId, List> linkIds, Id endLinkId) {
diff --git a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java
similarity index 78%
rename from contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java
index 7e858ee725d..37a4651ce7e 100644
--- a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java
@@ -21,53 +21,47 @@
package org.matsim.freight.carriers.analysis;
+import static org.matsim.freight.carriers.events.CarrierEventAttributes.ATTRIBUTE_CAPACITYDEMAND;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
-import org.matsim.api.core.v01.events.Event;
import org.matsim.freight.carriers.Carriers;
import org.matsim.freight.carriers.events.CarrierShipmentDeliveryStartEvent;
import org.matsim.freight.carriers.events.CarrierShipmentPickupStartEvent;
-import org.matsim.core.events.handler.BasicEventHandler;
+import org.matsim.freight.carriers.events.eventhandler.CarrierShipmentDeliveryStartEventHandler;
+import org.matsim.freight.carriers.events.eventhandler.CarrierShipmentPickupStartEventHandler;
import org.matsim.vehicles.Vehicle;
import org.matsim.vehicles.VehicleType;
import org.matsim.vehicles.VehicleUtils;
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.Map;
-
-import static org.matsim.freight.carriers.events.CarrierEventAttributes.ATTRIBUTE_CAPACITYDEMAND;
-
/**
* @author Kai Martins-Turner (kturner)
*/
-public class CarrierLoadAnalysis implements BasicEventHandler {
+public class CarrierLoadAnalysis implements CarrierShipmentPickupStartEventHandler, CarrierShipmentDeliveryStartEventHandler {
private static final Logger log = LogManager.getLogger(CarrierLoadAnalysis.class);
-
+ private final String delimiter;
Carriers carriers;
private final Map, LinkedList> vehicle2Load = new LinkedHashMap<>();
- public CarrierLoadAnalysis(Carriers carriers) {
+ public CarrierLoadAnalysis(String delimiter, Carriers carriers) {
+ this.delimiter = delimiter;
this.carriers = carriers;
}
- @Override public void handleEvent(Event event) {
- if (event.getEventType().equals(CarrierShipmentPickupStartEvent.EVENT_TYPE)) {
- handlePickup( event);
- } if (event.getEventType().equals(CarrierShipmentDeliveryStartEvent.EVENT_TYPE)) {
- handleDelivery(event);
- }
- }
-
- private void handlePickup(Event event) {
+ @Override
+ public void handleEvent(CarrierShipmentPickupStartEvent event) {
Id vehicleId = Id.createVehicleId(event.getAttributes().get("vehicle"));
Integer demand = Integer.valueOf(event.getAttributes().get(ATTRIBUTE_CAPACITYDEMAND));
@@ -82,8 +76,8 @@ private void handlePickup(Event event) {
vehicle2Load.put(vehicleId, list);
}
-
- private void handleDelivery(Event event) {
+ @Override
+ public void handleEvent(CarrierShipmentDeliveryStartEvent event) {
Id vehicleId = Id.createVehicleId(event.getAttributes().get("vehicle"));
Integer demand = Integer.valueOf(event.getAttributes().get(ATTRIBUTE_CAPACITYDEMAND));
@@ -95,12 +89,16 @@ private void handleDelivery(Event event) {
void writeLoadPerVehicle(String analysisOutputDirectory, Scenario scenario) throws IOException {
log.info("Writing out vehicle load analysis ...");
//Load per vehicle
- String fileName = analysisOutputDirectory + "Load_perVehicle.tsv";
+ String fileName = Path.of(analysisOutputDirectory).resolve("Load_perVehicle.tsv").toString();
BufferedWriter bw1 = new BufferedWriter(new FileWriter(fileName));
//Write headline:
- bw1.write("vehicleId \t capacity \t maxLoad \t load state during tour");
+ bw1.write(String.join(delimiter,"vehicleId",
+ "vehicleTypeId",
+ "capacity",
+ "maxLoad",
+ "load state during tour"));
bw1.newLine();
for (Id vehicleId : vehicle2Load.keySet()) {
@@ -112,13 +110,14 @@ void writeLoadPerVehicle(String analysisOutputDirectory, Scenario scenario) thro
final Double capacity = vehicleType.getCapacity().getOther();
bw1.write(vehicleId.toString());
- bw1.write("\t" + capacity);
- bw1.write("\t" + maxLoad);
- bw1.write("\t" + load);
+ bw1.write(delimiter + vehicleType.getId().toString());
+ bw1.write(delimiter + capacity);
+ bw1.write(delimiter + maxLoad);
+ bw1.write(delimiter + load);
bw1.newLine();
}
bw1.close();
- log.info("Output written to " + fileName);
+ log.info("Output written to {}", fileName);
}
}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierPlanAnalysis.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierPlanAnalysis.java
new file mode 100644
index 00000000000..610c376a5db
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierPlanAnalysis.java
@@ -0,0 +1,156 @@
+/*
+ * *********************************************************************** *
+ * project: org.matsim.*
+ * *********************************************************************** *
+ * *
+ * copyright : (C) by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * ***********************************************************************
+ *
+ */
+
+package org.matsim.freight.carriers.analysis;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.TreeMap;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.matsim.api.core.v01.Id;
+import org.matsim.core.utils.misc.Time;
+import org.matsim.freight.carriers.*;
+
+/**
+ * Some basic analysis / data collection for {@link Carriers}(files)
+ *
+ * For all carriers it writes out the:
+ * - score of the selected plan
+ * - number of tours (= vehicles) of the selected plan
+ * - number of Services (input)
+ * - number of Services (handled)
+ * - number of shipments (input)
+ * - number of shipments (handled)
+ * - number of not handled jobs
+ * - number of planned demand size
+ * - number of handled demand size
+ * to a tsv-file.
+ *
+ * @author Kai Martins-Turner (kturner), Ricardo Ewert
+ */
+public class CarrierPlanAnalysis {
+
+ private static final Logger log = LogManager.getLogger(CarrierPlanAnalysis.class);
+ public final String delimiter;
+
+ Carriers carriers;
+
+ public CarrierPlanAnalysis(String delimiter, Carriers carriers) {
+ this.delimiter = delimiter;
+ this.carriers = carriers;
+ }
+
+ public void runAnalysisAndWriteStats(String analysisOutputDirectory) throws IOException {
+ log.info("Writing out carrier analysis ...");
+ //Load per vehicle
+ String fileName = Path.of(analysisOutputDirectory).resolve("Carrier_stats.tsv").toString();
+
+ try (BufferedWriter bw1 = new BufferedWriter(new FileWriter(fileName))) {
+
+ //Write headline:
+ bw1.write(String.join(delimiter,
+ "carrierId",
+ "MATSimScoreSelectedPlan",
+ "jSpritScoreSelectedPlan",
+ "nuOfTours",
+ "nuOfShipments(input)",
+ "nuOfShipments(handled)",
+ "nuOfServices(input)",
+ "nuOfServices(handled)",
+ "noOfNotHandledJobs",
+ "nuOfPlanedDemandSize",
+ "nuOfHandledDemandSize",
+ "jspritComputationTime[HH:mm:ss]"
+ ));
+ bw1.newLine();
+
+ final TreeMap, Carrier> sortedCarrierMap = new TreeMap<>(carriers.getCarriers());
+
+ for (Carrier carrier : sortedCarrierMap.values()) {
+
+ int numberOfPlanedShipments = carrier.getShipments().size();
+ int numberOfPlanedServices = carrier.getServices().size();
+ int numberOfHandledPickups = (int) carrier.getSelectedPlan().getScheduledTours().stream().mapToDouble(
+ t -> t.getTour().getTourElements().stream().filter(te -> te instanceof Tour.Pickup).count()).sum();
+ int numberOfHandledDeliveries = (int) carrier.getSelectedPlan().getScheduledTours().stream().mapToDouble(
+ t -> t.getTour().getTourElements().stream().filter(te -> te instanceof Tour.Delivery).count()).sum();
+ int nuOfServiceHandled = (int) carrier.getSelectedPlan().getScheduledTours().stream().mapToDouble(
+ t -> t.getTour().getTourElements().stream().filter(te -> te instanceof Tour.ServiceActivity).count()).sum();
+ int numberOfPlanedDemandSize;
+ int numberOfHandledDemandSize;
+ int notHandledJobs;
+ if (numberOfPlanedShipments > 0) {
+ numberOfPlanedDemandSize = carrier.getShipments().values().stream().mapToInt(CarrierShipment::getSize).sum();
+ numberOfHandledDemandSize = carrier.getSelectedPlan().getScheduledTours().stream().mapToInt(
+ t -> t.getTour().getTourElements().stream().filter(te -> te instanceof Tour.Pickup).mapToInt(
+ te -> (((Tour.Pickup) te).getShipment().getSize())).sum()).sum();
+ notHandledJobs = numberOfPlanedShipments - numberOfHandledPickups;
+ } else {
+ numberOfPlanedDemandSize = carrier.getServices().values().stream().mapToInt(CarrierService::getCapacityDemand).sum();
+ numberOfHandledDemandSize = carrier.getSelectedPlan().getScheduledTours().stream().mapToInt(
+ t -> t.getTour().getTourElements().stream().filter(te -> te instanceof Tour.ServiceActivity).mapToInt(
+ te -> ((Tour.ServiceActivity) te).getService().getCapacityDemand()).sum()).sum();
+ notHandledJobs = numberOfPlanedServices - nuOfServiceHandled;
+ }
+
+ if (numberOfPlanedServices != nuOfServiceHandled) {
+ log.warn("Number of services in input and handled are not equal for carrier {}. Jobs Input: {}, Jobs Handled: {}",
+ carrier.getId(), numberOfPlanedServices, nuOfServiceHandled);
+ }
+ if (numberOfPlanedShipments != numberOfHandledPickups) {
+ log.warn("Number of shipments in input and handled are not equal for carrier {}. Jobs Input: {}, Jobs Handled: {}",
+ carrier.getId(), numberOfPlanedShipments, numberOfHandledPickups);
+ }
+ if (numberOfHandledDeliveries != numberOfHandledPickups) {
+ log.warn(
+ "Number of handled pickups and deliveries are not equal for carrier {}. Pickups: {}, Deliveries: {}. This should not happen!!",
+ carrier.getId(), numberOfHandledPickups, numberOfHandledDeliveries);
+ }
+ bw1.write(carrier.getId().toString());
+ bw1.write(delimiter + carrier.getSelectedPlan().getScore());
+ bw1.write(delimiter + carrier.getSelectedPlan().getJspritScore());
+ bw1.write(delimiter + carrier.getSelectedPlan().getScheduledTours().size());
+ bw1.write(delimiter + numberOfPlanedShipments);
+ bw1.write(delimiter + numberOfHandledPickups);
+ bw1.write(delimiter + numberOfPlanedServices);
+ bw1.write(delimiter + nuOfServiceHandled);
+ bw1.write(delimiter + notHandledJobs);
+ bw1.write(delimiter + numberOfPlanedDemandSize);
+ bw1.write(delimiter + numberOfHandledDemandSize);
+ if (CarriersUtils.getJspritComputationTime(carrier) != Integer.MIN_VALUE)
+ bw1.write(delimiter + Time.writeTime(CarriersUtils.getJspritComputationTime(carrier), Time.TIMEFORMAT_HHMMSS));
+ else
+ bw1.write(delimiter + "null");
+
+ bw1.newLine();
+ }
+
+ bw1.close();
+ log.info("Output written to {}", fileName);
+ } catch (IOException e) {
+ log.error("Error writing output to file: {}", fileName);
+ throw e;
+ }
+ }
+}
diff --git a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/FreightTimeAndDistanceAnalysisEventsHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/FreightTimeAndDistanceAnalysisEventsHandler.java
similarity index 70%
rename from contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/FreightTimeAndDistanceAnalysisEventsHandler.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/FreightTimeAndDistanceAnalysisEventsHandler.java
index 3037716368c..4e53c559222 100644
--- a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/FreightTimeAndDistanceAnalysisEventsHandler.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/FreightTimeAndDistanceAnalysisEventsHandler.java
@@ -21,38 +21,43 @@
package org.matsim.freight.carriers.analysis;
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.TreeMap;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
-import org.matsim.api.core.v01.events.Event;
import org.matsim.api.core.v01.events.LinkEnterEvent;
import org.matsim.api.core.v01.events.LinkLeaveEvent;
import org.matsim.api.core.v01.events.VehicleEntersTrafficEvent;
import org.matsim.api.core.v01.events.VehicleLeavesTrafficEvent;
+import org.matsim.api.core.v01.events.handler.LinkEnterEventHandler;
+import org.matsim.api.core.v01.events.handler.LinkLeaveEventHandler;
+import org.matsim.api.core.v01.events.handler.VehicleEntersTrafficEventHandler;
+import org.matsim.api.core.v01.events.handler.VehicleLeavesTrafficEventHandler;
import org.matsim.freight.carriers.Carrier;
import org.matsim.freight.carriers.CarriersUtils;
import org.matsim.freight.carriers.Tour;
import org.matsim.freight.carriers.events.CarrierTourEndEvent;
import org.matsim.freight.carriers.events.CarrierTourStartEvent;
-import org.matsim.core.events.handler.BasicEventHandler;
+import org.matsim.freight.carriers.events.eventhandler.CarrierTourEndEventHandler;
+import org.matsim.freight.carriers.events.eventhandler.CarrierTourStartEventHandler;
import org.matsim.vehicles.Vehicle;
import org.matsim.vehicles.VehicleType;
import org.matsim.vehicles.VehicleUtils;
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.TreeMap;
-
/**
* @author Kai Martins-Turner (kturner)
*/
-public class FreightTimeAndDistanceAnalysisEventsHandler implements BasicEventHandler {
+public class FreightTimeAndDistanceAnalysisEventsHandler implements CarrierTourStartEventHandler, CarrierTourEndEventHandler, LinkEnterEventHandler, LinkLeaveEventHandler, VehicleEntersTrafficEventHandler, VehicleLeavesTrafficEventHandler {
private final static Logger log = LogManager.getLogger(FreightTimeAndDistanceAnalysisEventsHandler.class);
+ private final String delimiter;
private final Scenario scenario;
private final Map, Double> vehicleId2TourDuration = new LinkedHashMap<>();
@@ -74,21 +79,24 @@ public class FreightTimeAndDistanceAnalysisEventsHandler implements BasicEventHa
private final Map, Double> vehicleEnteredLinkTime = new LinkedHashMap<>();
- public FreightTimeAndDistanceAnalysisEventsHandler(Scenario scenario) {
+ public FreightTimeAndDistanceAnalysisEventsHandler(String delimiter, Scenario scenario) {
+ this.delimiter = delimiter;
this.scenario = scenario;
}
- private void handleEvent(CarrierTourStartEvent event) {
+ @Override
+ public void handleEvent(CarrierTourStartEvent event) {
// Save time of freight tour start
final String key = event.getCarrierId().toString() + "_" + event.getTourId().toString();
tourStartTime.put(key, event.getTime());
}
//Fix costs for vehicle usage
- private void handleEvent(CarrierTourEndEvent event) {
+ @Override
+ public void handleEvent(CarrierTourEndEvent event) {
final String key = event.getCarrierId().toString() + "_" + event.getTourId().toString();
double tourDuration = event.getTime() - tourStartTime.get(key);
- vehicleId2TourDuration.put(event.getVehicleId(), tourDuration);
+ vehicleId2TourDuration.put(event.getVehicleId(), tourDuration); //TODO, check if this may overwrite old data and if this is intended to do so
VehicleType vehType = VehicleUtils.findVehicle(event.getVehicleId(), scenario).getType();
vehicleTypeId2SumOfTourDuration.merge(vehType.getId(), tourDuration, Double::sum);
@@ -99,7 +107,13 @@ private void handleEvent(CarrierTourEndEvent event) {
vehicleId2VehicleType.putIfAbsent(event.getVehicleId(), vehType);
}
- private void handleEvent(LinkEnterEvent event) {
+ @Override
+ public void handleEvent(VehicleEntersTrafficEvent event){
+ vehicleEnteredLinkTime.put(event.getVehicleId(), event.getTime());
+ }
+
+ @Override
+ public void handleEvent(LinkEnterEvent event) {
final double distance = scenario.getNetwork().getLinks().get(event.getLinkId()).getLength();
vehicleId2TourLength.merge(event.getVehicleId(), distance, Double::sum);
vehicleEnteredLinkTime.put(event.getVehicleId(), event.getTime()); //Safe time when entering the link.
@@ -109,7 +123,8 @@ private void handleEvent(LinkEnterEvent event) {
}
//If the vehicle leaves a link at the end, the travelTime is calculated and stored.
- private void handleEvent(LinkLeaveEvent event){
+ @Override
+ public void handleEvent(LinkLeaveEvent event){
final Id vehicleId = event.getVehicleId();
if (vehicleEnteredLinkTime.containsKey(vehicleId)){
double tt = event.getTime() - vehicleEnteredLinkTime.get(vehicleId);
@@ -123,7 +138,8 @@ private void handleEvent(LinkLeaveEvent event){
}
//If the vehicle leaves a link because it reached its destination, the travelTime is calculated and stored.
- private void handleEvent(VehicleLeavesTrafficEvent event){
+ @Override
+ public void handleEvent(VehicleLeavesTrafficEvent event){
final Id vehicleId = event.getVehicleId();
if (vehicleEnteredLinkTime.containsKey(vehicleId)){
double tt = event.getTime() - vehicleEnteredLinkTime.get(vehicleId);
@@ -136,39 +152,31 @@ private void handleEvent(VehicleLeavesTrafficEvent event){
}
}
- private void handleEvent(VehicleEntersTrafficEvent event){
- vehicleEnteredLinkTime.put(event.getVehicleId(), event.getTime());
- }
-
- @Override public void handleEvent(Event event) {
- if (event instanceof CarrierTourStartEvent carrierTourStartEvent) {
- handleEvent(carrierTourStartEvent);
- } else if (event instanceof CarrierTourEndEvent carrierTourEndEvent) {
- handleEvent(carrierTourEndEvent);
- } else if (event instanceof LinkEnterEvent linkEnterEvent) {
- handleEvent(linkEnterEvent);
- } else if (event instanceof LinkLeaveEvent linkLeaveEvent) {
- handleEvent(linkLeaveEvent);
- } else if (event instanceof VehicleLeavesTrafficEvent vehicleLeavesTrafficEvent) {
- handleEvent(vehicleLeavesTrafficEvent);
- } else if (event instanceof VehicleEntersTrafficEvent vehicleEntersTrafficEvent) {
- handleEvent(vehicleEntersTrafficEvent);
- }
- }
-
void writeTravelTimeAndDistancePerVehicle(String analysisOutputDirectory, Scenario scenario) throws IOException {
log.info("Writing out Time & Distance & Costs ... perVehicle");
//Travel time and distance per vehicle
- String fileName = analysisOutputDirectory + "TimeDistance_perVehicle.tsv";
+ String fileName = Path.of(analysisOutputDirectory).resolve("TimeDistance_perVehicle.tsv").toString();
BufferedWriter bw1 = new BufferedWriter(new FileWriter(fileName));
//Write headline:
- bw1.write("vehicleId \t carrierId \t vehicleTypeId \t tourId \t "
- + "tourDuration[s] \t tourDuration[h] \t"
- + "travelDistance[m] \t travelDistance[km] \t " +
- "travelTime[s] \t travelTime[h] \t" +
- "costPerSecond[EUR/s] \t costPerMeter[EUR/m] \t fixedCosts[EUR] \t varCostsTime[EUR] \t varCostsDist[EUR] \t totalCosts[EUR]");
+ bw1.write(String.join(delimiter,
+ "vehicleId",
+ "carrierId",
+ "vehicleTypeId",
+ "tourId",
+ "tourDuration[s]",
+ "tourDuration[h]",
+ "travelDistance[m]",
+ "travelDistance[km]",
+ "travelTime[s]",
+ "travelTime[h]",
+ "costPerSecond[EUR/s]",
+ "costPerMeter[EUR/m]",
+ "fixedCosts[EUR]",
+ "varCostsTime[EUR]",
+ "varCostsDist[EUR]",
+ "totalCosts[EUR]"));
bw1.newLine();
for (Id vehicleId : vehicleId2VehicleType.keySet()) {
@@ -188,34 +196,33 @@ void writeTravelTimeAndDistancePerVehicle(String analysisOutputDirectory, Scenar
final double totalVehCosts = fixedCost + varCostsTime + varCostsDist;
bw1.write(vehicleId.toString());
- bw1.write("\t" + vehicleId2CarrierId.get(vehicleId));
- bw1.write("\t" + vehicleType.getId().toString());
- bw1.write("\t" + vehicleId2TourId.get(vehicleId));
+ bw1.write(delimiter + vehicleId2CarrierId.get(vehicleId));
+ bw1.write(delimiter + vehicleType.getId().toString());
+ bw1.write(delimiter + vehicleId2TourId.get(vehicleId));
- bw1.write("\t" + durationInSeconds);
- bw1.write("\t" + durationInSeconds /3600);
+ bw1.write(delimiter + durationInSeconds);
+ bw1.write(delimiter + durationInSeconds /3600);
- bw1.write("\t" + distanceInMeters);
- bw1.write("\t" + distanceInMeters/1000);
+ bw1.write(delimiter + distanceInMeters);
+ bw1.write(delimiter + distanceInMeters/1000);
- bw1.write("\t" + travelTimeInSeconds);
- bw1.write("\t" + travelTimeInSeconds /3600);
+ bw1.write(delimiter + travelTimeInSeconds);
+ bw1.write(delimiter + travelTimeInSeconds /3600);
- bw1.write("\t" + costsPerSecond);
- bw1.write("\t" + costsPerMeter);
- bw1.write("\t" + fixedCost);
- bw1.write("\t" + varCostsTime);
- bw1.write("\t" + varCostsDist);
- bw1.write("\t" + totalVehCosts);
+ bw1.write(delimiter + costsPerSecond);
+ bw1.write(delimiter + costsPerMeter);
+ bw1.write(delimiter + fixedCost);
+ bw1.write(delimiter + varCostsTime);
+ bw1.write(delimiter + varCostsDist);
+ bw1.write(delimiter + totalVehCosts);
bw1.newLine();
}
bw1.close();
- log.info("Output written to " + fileName);
+ log.info("Output written to {}", fileName);
}
-
void writeTravelTimeAndDistancePerVehicleType(String analysisOutputDirectory, Scenario scenario) throws IOException {
log.info("Writing out Time & Distance & Costs ... perVehicleType");
@@ -226,16 +233,26 @@ void writeTravelTimeAndDistancePerVehicleType(String analysisOutputDirectory, Sc
vehicleTypesMap.putIfAbsent(vehicleType.getId(), vehicleType);
}
- String fileName = analysisOutputDirectory + "TimeDistance_perVehicleType.tsv";
+ String fileName = Path.of(analysisOutputDirectory).resolve("TimeDistance_perVehicleType.tsv").toString();
BufferedWriter bw1 = new BufferedWriter(new FileWriter(fileName));
//Write headline:
- bw1.write("vehicleTypeId \t nuOfVehicles \t " +
- "SumOfTourDuration[s] \t SumOfTourDuration[h] \t" +
- "SumOfTravelDistances[m] \t SumOfTravelDistances[km] \t " +
- "SumOfTravelTime[s] \t SumOfTravelTime[h] \t" +
- "costPerSecond[EUR/s] \t costPerMeter[EUR/m] \t fixedCosts[EUR/veh] \t" +
- "varCostsTime[EUR] \t varCostsDist[EUR] \t fixedCosts[EUR] \t totalCosts[EUR]");
+ bw1.write(String.join(delimiter,
+ "vehicleTypeId",
+ "nuOfVehicles",
+ "SumOfTourDuration[s]",
+ "SumOfTourDuration[h]",
+ "SumOfTravelDistances[m]",
+ "SumOfTravelDistances[km]",
+ "SumOfTravelTime[s]",
+ "SumOfTravelTime[h]",
+ "costPerSecond[EUR/s]",
+ "costPerMeter[EUR/m]",
+ "fixedCosts[EUR/veh]",
+ "varCostsTime[EUR]",
+ "varCostsDist[EUR]",
+ "fixedCosts[EUR]",
+ "totalCosts[EUR]"));
bw1.newLine();
for (VehicleType vehicleType : vehicleTypesMap.values()) {
@@ -255,25 +272,25 @@ void writeTravelTimeAndDistancePerVehicleType(String analysisOutputDirectory, Sc
bw1.write(vehicleType.getId().toString());
- bw1.write("\t" + nuOfVehicles);
- bw1.write("\t" + sumOfTourDurationInSeconds);
- bw1.write("\t" + sumOfTourDurationInSeconds / 3600);
- bw1.write("\t" + sumOfDistanceInMeters);
- bw1.write("\t" + sumOfDistanceInMeters / 1000);
- bw1.write("\t" + sumOfTravelTimeInSeconds);
- bw1.write("\t" + sumOfTravelTimeInSeconds / 3600);
- bw1.write("\t" + costRatePerSecond);
- bw1.write("\t" + costRatePerMeter);
- bw1.write("\t" + fixedCostPerVeh);
- bw1.write("\t" + sumOfVarCostsTime);
- bw1.write("\t" + sumOfVarCostsDistance);
- bw1.write("\t" + sumOfFixCosts);
- bw1.write("\t" + (sumOfFixCosts + sumOfVarCostsTime + sumOfVarCostsDistance));
+ bw1.write(delimiter + nuOfVehicles);
+ bw1.write(delimiter + sumOfTourDurationInSeconds);
+ bw1.write(delimiter + sumOfTourDurationInSeconds / 3600);
+ bw1.write(delimiter + sumOfDistanceInMeters);
+ bw1.write(delimiter + sumOfDistanceInMeters / 1000);
+ bw1.write(delimiter + sumOfTravelTimeInSeconds);
+ bw1.write(delimiter + sumOfTravelTimeInSeconds / 3600);
+ bw1.write(delimiter + costRatePerSecond);
+ bw1.write(delimiter + costRatePerMeter);
+ bw1.write(delimiter + fixedCostPerVeh);
+ bw1.write(delimiter + sumOfVarCostsTime);
+ bw1.write(delimiter + sumOfVarCostsDistance);
+ bw1.write(delimiter + sumOfFixCosts);
+ bw1.write(delimiter + (sumOfFixCosts + sumOfVarCostsTime + sumOfVarCostsDistance));
bw1.newLine();
}
bw1.close();
- log.info("Output written to " + fileName);
+ log.info("Output written to {}", fileName);
}
}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/RunFreightAnalysisEventBased.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/RunFreightAnalysisEventBased.java
new file mode 100644
index 00000000000..d6a01e09409
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/RunFreightAnalysisEventBased.java
@@ -0,0 +1,191 @@
+/*
+ * *********************************************************************** *
+ * project: org.matsim.*
+ * *********************************************************************** *
+ * *
+ * copyright : (C) by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * ***********************************************************************
+ *
+ */
+
+package org.matsim.freight.carriers.analysis;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.matsim.api.core.v01.Scenario;
+import org.matsim.core.api.experimental.events.EventsManager;
+import org.matsim.core.config.Config;
+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.freight.carriers.Carrier;
+import org.matsim.freight.carriers.Carriers;
+import org.matsim.freight.carriers.CarriersUtils;
+import org.matsim.freight.carriers.FreightCarriersConfigGroup;
+import org.matsim.freight.carriers.events.CarrierEventsReaders;
+
+//import static org.matsim.application.ApplicationUtils.globFile;
+
+
+/**
+ * A first approach for some analysis based on the freight events introduced in 2022/23.
+ * This class comes from teaching SimGV in the winter term 2022/23.
+ *
+ * This class should get extended and prepared as a standardized analysis for freight output.
+ * This should also get aligned with the current development in Simwrapper.
+ * Todo: Add some tests.
+ *
+ * @author kturner (Kai Martins-Turner)
+ */
+public class RunFreightAnalysisEventBased {
+
+ private static final Logger log = LogManager.getLogger(RunFreightAnalysisEventBased.class);
+
+ //Where is your simulation output, that should be analysed?
+ private String EVENTS_PATH = null;
+ private final String ANALYSIS_OUTPUT_PATH;
+ private Scenario scenario = null;
+ private Carriers carriers = null;
+ private final String delimiter = "\t";
+
+ //TODO discuss renaming without EventBased. If this becomes the standard carrier output
+ /**
+ * This constructor automatically searches for the necessary output file in a simulation run output.
+ *
+ * @param simOutputPath The output directory of the simulation run
+ * @param analysisOutputPath The directory where the result of the analysis should go to
+ * @param globalCrs The CRS of the simulation
+ */
+ public RunFreightAnalysisEventBased(String simOutputPath, String analysisOutputPath, String globalCrs) {
+
+ this.ANALYSIS_OUTPUT_PATH = analysisOutputPath;
+// this.EVENTS_PATH = globFile(simOutputPath, "*output_events.*");
+// Path vehiclesPath = globFile(simOutputPath, "*output_allVehicles.*");
+// Path networkPath = globFile(simOutputPath, "*output_network.*");
+// Path carriersPath = globFile(simOutputPath, "*output_carriers.*");
+// Path carriersVehicleTypesPath = globFile(simOutputPath, "*output_carriersVehicleTypes.*");
+
+ // the better version with the globFile method is not available since there is a circular dependency between the modules application and freight
+
+ this.EVENTS_PATH = Path.of(simOutputPath).resolve("output_events.xml.gz").toString();
+ String vehiclesPath = Path.of(simOutputPath).resolve("output_allVehicles.xml.gz").toString();
+ String networkPath = Path.of(simOutputPath).resolve("output_network.xml.gz").toString();
+ String carriersPath = Path.of(simOutputPath).resolve("output_carriers.xml.gz").toString();
+ String carriersVehicleTypesPath = Path.of(simOutputPath).resolve("output_carriersVehicleTypes.xml.gz").toString();
+
+ createScenarioForFreightAnalysis(vehiclesPath, networkPath, carriersPath, carriersVehicleTypesPath, globalCrs);
+ }
+
+ /**
+ * Alternative if you want to set the paths to the necessary resources directly.
+ *
+ * @param networkPath Path to the network file
+ * @param vehiclesPath Path to the vehicle file
+ * @param carriersPath Path to the carriers file
+ * @param carriersVehicleTypesPath Path to the carriersVehicleTypes file
+ * @param eventsPath Path to the events file
+ * @param analysisOutputPath Path to the output directory
+ * @param globalCrs The CRS of the simulation
+ */
+ public RunFreightAnalysisEventBased(String networkPath, String vehiclesPath, String carriersPath, String carriersVehicleTypesPath, String eventsPath,
+ String analysisOutputPath, String globalCrs) {
+ this.EVENTS_PATH = eventsPath;
+ this.ANALYSIS_OUTPUT_PATH = analysisOutputPath;
+
+ createScenarioForFreightAnalysis(vehiclesPath, networkPath, carriersPath, carriersVehicleTypesPath, globalCrs);
+ }
+
+ /**
+ * Constructor, if you only want to have the carrier analysis.
+ *
+ * @param carriers The carriers to be analysed
+ * @param analysisOutputPath The directory where the result of the analysis should go to
+ */
+ public RunFreightAnalysisEventBased(Carriers carriers, String analysisOutputPath) {
+ this.carriers = carriers;
+ this.ANALYSIS_OUTPUT_PATH = analysisOutputPath;
+ }
+
+ private void createScenarioForFreightAnalysis(String vehiclesPath, String networkPath, String carriersPath, String carriersVehicleTypesPath,
+ String globalCrs) {
+ Config config = ConfigUtils.createConfig();
+ config.vehicles().setVehiclesFile(vehiclesPath);
+ config.network().setInputFile(networkPath);
+ config.plans().setInputFile(null);
+ config.eventsManager().setNumberOfThreads(null);
+ config.eventsManager().setEstimatedNumberOfEvents(null);
+ config.global().setNumberOfThreads(1);
+ config.global().setCoordinateSystem(globalCrs);
+
+ //freight settings
+ FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class);
+ freightCarriersConfigGroup.setCarriersFile(carriersPath);
+ freightCarriersConfigGroup.setCarriersVehicleTypesFile(carriersVehicleTypesPath.toString());
+
+ scenario = ScenarioUtils.loadScenario(config);
+
+ //load carriers according to freight config
+ CarriersUtils.loadCarriersAccordingToFreightConfig( scenario );
+ this.carriers = CarriersUtils.addOrGetCarriers(scenario);
+ }
+
+ public void runCarriersAnalysis() throws IOException {
+
+ //Where to store the analysis output?
+ File folder = new File(String.valueOf(ANALYSIS_OUTPUT_PATH));
+ folder.mkdirs();
+ if (allCarriersHavePlans(carriers)) {
+ CarrierPlanAnalysis carrierPlanAnalysis = new CarrierPlanAnalysis(delimiter, carriers);
+ carrierPlanAnalysis.runAnalysisAndWriteStats(ANALYSIS_OUTPUT_PATH);
+ }
+ else {
+ log.warn("########## Not all carriers have plans. Skipping CarrierPlanAnalysis."); //TODO perhaps skipp complete analysis
+ }
+ }
+ public void runCompleteAnalysis() throws IOException {
+ runCarriersAnalysis();
+
+ // Prepare eventsManager - start of event based Analysis;
+ EventsManager eventsManager = EventsUtils.createEventsManager();
+
+ FreightTimeAndDistanceAnalysisEventsHandler freightTimeAndDistanceAnalysisEventsHandler = new FreightTimeAndDistanceAnalysisEventsHandler(delimiter, scenario);
+ eventsManager.addHandler(freightTimeAndDistanceAnalysisEventsHandler);
+
+ CarrierLoadAnalysis carrierLoadAnalysis = new CarrierLoadAnalysis(delimiter, CarriersUtils.getCarriers(scenario));
+ eventsManager.addHandler(carrierLoadAnalysis);
+
+ eventsManager.initProcessing();
+ MatsimEventsReader matsimEventsReader = CarrierEventsReaders.createEventsReader(eventsManager);
+
+ matsimEventsReader.readFile(EVENTS_PATH);
+ eventsManager.finishProcessing();
+
+ log.info("Analysis completed.");
+ log.info("Writing output...");
+ freightTimeAndDistanceAnalysisEventsHandler.writeTravelTimeAndDistancePerVehicle(ANALYSIS_OUTPUT_PATH, scenario);
+ freightTimeAndDistanceAnalysisEventsHandler.writeTravelTimeAndDistancePerVehicleType(ANALYSIS_OUTPUT_PATH, scenario);
+ carrierLoadAnalysis.writeLoadPerVehicle(ANALYSIS_OUTPUT_PATH, scenario);
+ }
+
+ private boolean allCarriersHavePlans(Carriers carriers) {
+ for (Carrier carrier : carriers.getCarriers().values())
+ if (carrier.getSelectedPlan() == null) return false;
+
+ return true;
+ }
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierAgent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierAgent.java
similarity index 99%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierAgent.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierAgent.java
index da31ae5637d..1afe10da4d0 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierAgent.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierAgent.java
@@ -19,8 +19,9 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
+import java.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -38,8 +39,6 @@
import org.matsim.vehicles.Vehicle;
import org.matsim.vehicles.VehicleUtils;
-import java.util.*;
-
/**
* This keeps track of the carrier during simulation.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierAgentTracker.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierAgentTracker.java
similarity index 99%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierAgentTracker.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierAgentTracker.java
index 09c4036d92f..f2bd02a204e 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierAgentTracker.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierAgentTracker.java
@@ -19,9 +19,10 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
import com.google.inject.Inject;
+import java.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -35,8 +36,6 @@
import org.matsim.freight.carriers.events.CarrierEventCreator;
import org.matsim.freight.carriers.events.CarrierEventCreatorUtils;
-import java.util.*;
-
/**
* This keeps track of all carrierAgents during simulation.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierControlerListener.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierControllerListener.java
similarity index 92%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierControlerListener.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierControllerListener.java
index f8a103bcbe5..136fecf4725 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierControlerListener.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierControllerListener.java
@@ -19,9 +19,10 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
import jakarta.inject.Inject;
+import javax.annotation.Nullable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Scenario;
@@ -31,8 +32,6 @@
import org.matsim.core.controler.listener.ScoringListener;
import org.matsim.freight.carriers.CarriersUtils;
-import javax.annotation.Nullable;
-
/**
* Controls the workflow of the simulation.
*
@@ -46,13 +45,13 @@
* // not sure if this _should_ be public, but current LSP design makes this necessary. kai, sep'20
*/
-public class CarrierControlerListener implements ScoringListener, ReplanningListener {
+public class CarrierControllerListener implements ScoringListener, ReplanningListener {
// not sure if this _should_ be public, but current LSP design makes this necessary.
// It is done analogue to CarrierAgentTracker. kmt oct'22
@SuppressWarnings("unused")
- private static final Logger log = LogManager.getLogger( CarrierControlerListener.class ) ;
+ private static final Logger log = LogManager.getLogger( CarrierControllerListener.class ) ;
private final CarrierStrategyManager strategyManager;
private final CarrierAgentTracker carrierAgentTracker;
@@ -62,7 +61,8 @@ public class CarrierControlerListener implements ScoringListener, ReplanningList
/**
* Constructs a controller with a set of carriers, re-planning capabilities and scoring-functions.
*/
- @Inject CarrierControlerListener( @Nullable CarrierStrategyManager strategyManager, CarrierAgentTracker carrierAgentTracker ) {
+ @Inject
+ CarrierControllerListener(@Nullable CarrierStrategyManager strategyManager, CarrierAgentTracker carrierAgentTracker ) {
// The current default is bind( CarrierStrategyManager.class ).toProvider( () -> null );
this.strategyManager = strategyManager;
this.carrierAgentTracker = carrierAgentTracker;
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierControlerUtils.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierControllerUtils.java
similarity index 94%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierControlerUtils.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierControllerUtils.java
index fe19207bfcc..5d15a6821f0 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierControlerUtils.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierControllerUtils.java
@@ -19,7 +19,7 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
/**
* Utils class for (package-private) content of freight.carriers.controler - package;
@@ -27,7 +27,7 @@
* @author kturner
*
*/
-public class CarrierControlerUtils {
+public class CarrierControllerUtils {
public static CarrierStrategyManager createDefaultCarrierStrategyManager() {
return new CarrierStrategyManagerImpl();
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierDriverAgent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierDriverAgent.java
similarity index 99%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierDriverAgent.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierDriverAgent.java
index c7f030f3457..ba8e40e3d71 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierDriverAgent.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierDriverAgent.java
@@ -19,8 +19,13 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -41,12 +46,6 @@
import org.matsim.freight.carriers.events.CarrierEventCreator;
import org.matsim.vehicles.Vehicle;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
/**
* This keeps track of a scheduledTour during simulation and can thus be seen as the driver of the vehicle that runs the tour.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierModule.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierModule.java
similarity index 97%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierModule.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierModule.java
index e2b9e1d8354..d95e1e7ac18 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierModule.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierModule.java
@@ -19,11 +19,12 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
+import java.util.List;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.events.Event;
import org.matsim.api.core.v01.population.Activity;
@@ -38,8 +39,6 @@
import org.matsim.core.scoring.ScoringFunction;
import org.matsim.freight.carriers.*;
-import java.util.List;
-
public final class CarrierModule extends AbstractModule {
@@ -49,8 +48,8 @@ public final class CarrierModule extends AbstractModule {
bind(Carriers.class).toProvider( new CarrierProvider() ).asEagerSingleton(); // needs to be eager since it is still scenario construction. kai, oct'19
// this is probably ok
- bind(CarrierControlerListener.class).in( Singleton.class );
- addControlerListenerBinding().to(CarrierControlerListener.class);
+ bind(CarrierControllerListener.class).in( Singleton.class );
+ addControlerListenerBinding().to(CarrierControllerListener.class);
bind(CarrierAgentTracker.class).in( Singleton.class );
addEventHandlerBinding().to( CarrierAgentTracker.class );
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierReRouteVehicles.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierReRouteVehicles.java
similarity index 95%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierReRouteVehicles.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierReRouteVehicles.java
index f59ba81c930..a2e32470a88 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierReRouteVehicles.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierReRouteVehicles.java
@@ -19,7 +19,7 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -77,8 +77,8 @@ private CarrierReRouteVehicles( LeastCostPathCalculator router, Network network,
/**
* Routes the carrierPlan in time and space.
*
- * @param carrierPlan
- * @throws IllegalStateException if carrierPlan is null.
+ * @param carrierPlan the carrierPlan to be routed.
+ * @throws IllegalStateException if carrierPlan is null.
* @see CarrierTimeAndSpaceTourRouter
*/
@Override
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierScoringFunctionFactory.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierScoringFunctionFactory.java
similarity index 96%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierScoringFunctionFactory.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierScoringFunctionFactory.java
index c73a41b3008..79338a48884 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierScoringFunctionFactory.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierScoringFunctionFactory.java
@@ -19,7 +19,7 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
import org.matsim.core.scoring.ScoringFunction;
import org.matsim.freight.carriers.Carrier;
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierStrategyManager.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierStrategyManager.java
similarity index 98%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierStrategyManager.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierStrategyManager.java
index f1d6d06e84e..8a7a3cfa263 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierStrategyManager.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierStrategyManager.java
@@ -19,7 +19,7 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
import com.google.inject.Provider;
import org.matsim.core.replanning.GenericStrategyManager;
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierStrategyManagerImpl.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierStrategyManagerImpl.java
similarity index 98%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierStrategyManagerImpl.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierStrategyManagerImpl.java
index 5bcad45b183..8a673af527b 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierStrategyManagerImpl.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierStrategyManagerImpl.java
@@ -19,8 +19,9 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
+import java.util.List;
import org.matsim.api.core.v01.population.HasPlansAndId;
import org.matsim.core.replanning.GenericPlanStrategy;
import org.matsim.core.replanning.GenericStrategyManager;
@@ -30,8 +31,6 @@
import org.matsim.freight.carriers.Carrier;
import org.matsim.freight.carriers.CarrierPlan;
-import java.util.List;
-
class CarrierStrategyManagerImpl implements CarrierStrategyManager{
final GenericStrategyManager delegate = new GenericStrategyManagerImpl<>();
@Override public void addStrategy( GenericPlanStrategy strategy, String subpopulation, double weight ){
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierTimeAllocationMutator.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierTimeAllocationMutator.java
similarity index 98%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierTimeAllocationMutator.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierTimeAllocationMutator.java
index 3b7fc83af01..b38a96a8fd2 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierTimeAllocationMutator.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierTimeAllocationMutator.java
@@ -18,17 +18,16 @@
* ***********************************************************************
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
+import java.util.ArrayList;
+import java.util.Collection;
import org.matsim.core.gbl.MatsimRandom;
import org.matsim.core.replanning.ReplanningContext;
import org.matsim.core.replanning.modules.GenericPlanStrategyModule;
import org.matsim.freight.carriers.CarrierPlan;
import org.matsim.freight.carriers.ScheduledTour;
-import java.util.ArrayList;
-import java.util.Collection;
-
/**
* @author nagel
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierTimeAndSpaceTourRouter.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierTimeAndSpaceTourRouter.java
similarity index 96%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierTimeAndSpaceTourRouter.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierTimeAndSpaceTourRouter.java
index 0a6a7399c9f..b02c5938e42 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierTimeAndSpaceTourRouter.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierTimeAndSpaceTourRouter.java
@@ -19,8 +19,10 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
+import java.util.ArrayList;
+import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -41,9 +43,6 @@
import org.matsim.vehicles.Vehicle;
import org.matsim.vehicles.VehicleType;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Router routing scheduledTours.
*
@@ -94,9 +93,9 @@ public Attributes getAttributes() {
/**
* Constructs the timeAndSpaceRouter with a leastCostPathCalculator, network and travelTime.
- * @param router
- * @param network
- * @param travelTime
+ * @param router the leastCostPathCalculator
+ * @param network the network
+ * @param travelTime the travelTime
* @see LeastCostPathCalculator, Network, TravelTime
*/
public CarrierTimeAndSpaceTourRouter( LeastCostPathCalculator router, Network network, TravelTime travelTime ) {
@@ -111,7 +110,7 @@ public CarrierTimeAndSpaceTourRouter( LeastCostPathCalculator router, Network ne
*
*
Uses a leastCostPathCalculator to calculate a route/path from one activity to another. It starts at the departureTime of
* the scheduledTour and determines activity arrival and departure times considering activities time-windows.
- * @param tour
+ * @param tour the scheduledTour to be routed.
*/
public void route(ScheduledTour tour) {
MatsimVehicleAdapter matsimVehicle = new MatsimVehicleAdapter(tour.getVehicle());
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierVehicleReRouter.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierVehicleReRouter.java
similarity index 98%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierVehicleReRouter.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierVehicleReRouter.java
index cd03cb5fd94..1d9a02d74d0 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierVehicleReRouter.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/CarrierVehicleReRouter.java
@@ -19,7 +19,7 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
import com.graphhopper.jsprit.core.algorithm.VehicleRoutingAlgorithm;
import com.graphhopper.jsprit.core.algorithm.state.StateManager;
@@ -35,6 +35,7 @@
import com.graphhopper.jsprit.io.algorithm.AlgorithmConfig;
import com.graphhopper.jsprit.io.algorithm.AlgorithmConfigXmlReader;
import com.graphhopper.jsprit.io.algorithm.VehicleRoutingAlgorithms;
+import java.util.Collection;
import org.matsim.api.core.v01.network.Network;
import org.matsim.contrib.roadpricing.RoadPricingScheme;
import org.matsim.core.replanning.ReplanningContext;
@@ -45,9 +46,6 @@
import org.matsim.freight.carriers.CarrierVehicleTypes;
import org.matsim.freight.carriers.jsprit.MatsimJspritFactory;
import org.matsim.freight.carriers.jsprit.NetworkBasedTransportCosts;
-import org.matsim.freight.carriers.jsprit.VehicleTypeDependentRoadPricingCalculator;
-
-import java.util.Collection;
class CarrierVehicleReRouter implements GenericPlanStrategyModule{
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/FreightActivity.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/FreightActivity.java
similarity index 98%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/FreightActivity.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/FreightActivity.java
index 42cd58ae587..ee3f0e65afc 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/FreightActivity.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/FreightActivity.java
@@ -19,7 +19,7 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.Id;
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/FreightAgentSource.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/FreightAgentSource.java
similarity index 98%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/FreightAgentSource.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/FreightAgentSource.java
index f5613f1a961..c1550c49701 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/FreightAgentSource.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/FreightAgentSource.java
@@ -19,9 +19,11 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
import com.google.inject.Inject;
+import java.util.ArrayList;
+import java.util.Collection;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -35,8 +37,6 @@
import org.matsim.vehicles.Vehicle;
import org.matsim.vehicles.VehicleUtils;
-import java.util.ArrayList;
-import java.util.Collection;
/**
* Created by IntelliJ IDEA. User: zilske Date: 10/31/11 Time: 5:59 PM To change
* this template use File | Settings | File Templates.
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/WithinDayActivityReScheduling.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/WithinDayActivityReScheduling.java
similarity index 98%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/controler/WithinDayActivityReScheduling.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/controller/WithinDayActivityReScheduling.java
index 285939a7174..0e4cbebfa6d 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/WithinDayActivityReScheduling.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controller/WithinDayActivityReScheduling.java
@@ -19,9 +19,12 @@
*
*/
-package org.matsim.freight.carriers.controler;
+package org.matsim.freight.carriers.controller;
import com.google.inject.Inject;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -38,10 +41,6 @@
import org.matsim.freight.carriers.Tour.Start;
import org.matsim.freight.carriers.Tour.TourActivity;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
/*
* Physically enforces beginnings of time windows for freight activities, i.e. freight agents
* wait before closed doors until they can deliver / pick up their goods.
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/AbstractCarrierEvent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/AbstractCarrierEvent.java
index 1380144b9b4..497bc3dca7e 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/AbstractCarrierEvent.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/AbstractCarrierEvent.java
@@ -21,6 +21,7 @@
package org.matsim.freight.carriers.events;
+import java.util.Map;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.Event;
import org.matsim.api.core.v01.events.HasLinkId;
@@ -29,8 +30,6 @@
import org.matsim.freight.carriers.Carrier;
import org.matsim.vehicles.Vehicle;
-import java.util.Map;
-
/**
* A general freight event contains the information (= {@link Id}) of the
* - {@link Carrier}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierEventsReaders.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierEventsReaders.java
index 23c9176a0ff..ee06d87ba6d 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierEventsReaders.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierEventsReaders.java
@@ -21,11 +21,10 @@
package org.matsim.freight.carriers.events;
+import java.util.Map;
import org.matsim.core.api.experimental.events.EventsManager;
import org.matsim.core.events.MatsimEventsReader;
-import java.util.Map;
-
/**
* Creates an {@link MatsimEventsReader} that also handles the carrier specific events.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierServiceEndEvent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierServiceEndEvent.java
index bfd8ad7d68c..f806248471c 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierServiceEndEvent.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierServiceEndEvent.java
@@ -21,6 +21,7 @@
package org.matsim.freight.carriers.events;
+import java.util.Map;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.GenericEvent;
import org.matsim.api.core.v01.network.Link;
@@ -28,8 +29,6 @@
import org.matsim.freight.carriers.CarrierService;
import org.matsim.vehicles.Vehicle;
-import java.util.Map;
-
/**
* An event, that informs that a Freight {@link CarrierService} activity has ended.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierServiceStartEvent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierServiceStartEvent.java
index 1b866d5ce5b..d1b4d816ace 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierServiceStartEvent.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierServiceStartEvent.java
@@ -21,6 +21,7 @@
package org.matsim.freight.carriers.events;
+import java.util.Map;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.GenericEvent;
import org.matsim.api.core.v01.network.Link;
@@ -28,8 +29,6 @@
import org.matsim.freight.carriers.CarrierService;
import org.matsim.vehicles.Vehicle;
-import java.util.Map;
-
/**
* An event, that informs that a Freight {@link CarrierService} activity has started.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryEndEvent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryEndEvent.java
index c02717031fa..8f60260a067 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryEndEvent.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryEndEvent.java
@@ -21,6 +21,7 @@
package org.matsim.freight.carriers.events;
+import java.util.Map;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.GenericEvent;
import org.matsim.api.core.v01.network.Link;
@@ -28,8 +29,6 @@
import org.matsim.freight.carriers.CarrierShipment;
import org.matsim.vehicles.Vehicle;
-import java.util.Map;
-
/**
* An event, that informs that a Freight {@link CarrierShipment} delivery-activity has ended.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryStartEvent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryStartEvent.java
index 43cf21fc752..a30035968c0 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryStartEvent.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryStartEvent.java
@@ -21,6 +21,9 @@
package org.matsim.freight.carriers.events;
+import static org.matsim.freight.carriers.events.CarrierEventAttributes.*;
+
+import java.util.Map;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.GenericEvent;
import org.matsim.api.core.v01.network.Link;
@@ -28,10 +31,6 @@
import org.matsim.freight.carriers.CarrierShipment;
import org.matsim.vehicles.Vehicle;
-import java.util.Map;
-
-import static org.matsim.freight.carriers.events.CarrierEventAttributes.*;
-
/**
* An event, that informs that a Freight {@link CarrierShipment} delivery-activity has started.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentPickupEndEvent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentPickupEndEvent.java
index 90e1fd137b7..4316e6f4dfe 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentPickupEndEvent.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentPickupEndEvent.java
@@ -21,6 +21,9 @@
package org.matsim.freight.carriers.events;
+import static org.matsim.freight.carriers.events.CarrierEventAttributes.*;
+
+import java.util.Map;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.GenericEvent;
import org.matsim.api.core.v01.network.Link;
@@ -28,10 +31,6 @@
import org.matsim.freight.carriers.CarrierShipment;
import org.matsim.vehicles.Vehicle;
-import java.util.Map;
-
-import static org.matsim.freight.carriers.events.CarrierEventAttributes.*;
-
/**
* An event, that informs that a Freight {@link CarrierShipment} pickup-activity has ended.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentPickupStartEvent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentPickupStartEvent.java
index ab36e627190..fe851a10138 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentPickupStartEvent.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentPickupStartEvent.java
@@ -21,6 +21,7 @@
package org.matsim.freight.carriers.events;
+import java.util.Map;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.GenericEvent;
import org.matsim.api.core.v01.network.Link;
@@ -28,8 +29,6 @@
import org.matsim.freight.carriers.CarrierShipment;
import org.matsim.vehicles.Vehicle;
-import java.util.Map;
-
/**
* An event, that informs that a Freight {@link CarrierShipment} pickup-activity has started.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierTourEndEvent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierTourEndEvent.java
index 82e133f2166..1c0e3579312 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierTourEndEvent.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierTourEndEvent.java
@@ -21,6 +21,7 @@
package org.matsim.freight.carriers.events;
+import java.util.Map;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.GenericEvent;
import org.matsim.api.core.v01.network.Link;
@@ -28,8 +29,6 @@
import org.matsim.freight.carriers.Tour;
import org.matsim.vehicles.Vehicle;
-import java.util.Map;
-
/**
* An event, that informs when a Freight {@link Tour} has ended.
* There are NO specific information of the tour given, because the {@link Tour} is determined by the {@link Vehicle} and its {@link Carrier}.
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierTourStartEvent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierTourStartEvent.java
index 9c64e8213b2..aa4ff9f1084 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierTourStartEvent.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierTourStartEvent.java
@@ -21,6 +21,9 @@
package org.matsim.freight.carriers.events;
+import static org.matsim.freight.carriers.events.CarrierEventAttributes.ATTRIBUTE_TOUR_ID;
+
+import java.util.Map;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.GenericEvent;
import org.matsim.api.core.v01.network.Link;
@@ -28,10 +31,6 @@
import org.matsim.freight.carriers.Tour;
import org.matsim.vehicles.Vehicle;
-import java.util.Map;
-
-import static org.matsim.freight.carriers.events.CarrierEventAttributes.ATTRIBUTE_TOUR_ID;
-
/**
* An event, that informs when a Freight {@link Tour} has started.
* There are NO specific information of the tour given, because the {@link Tour} is determined by the {@link Vehicle} and its {@link Carrier}.
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierTourStartEventCreator.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierTourStartEventCreator.java
index aacf3e6ef12..fea34b4f577 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierTourStartEventCreator.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierTourStartEventCreator.java
@@ -21,6 +21,7 @@
package org.matsim.freight.carriers.events;
+import java.util.TreeMap;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.ActivityEndEvent;
import org.matsim.api.core.v01.events.Event;
@@ -32,8 +33,6 @@
import org.matsim.freight.carriers.ScheduledTour;
import org.matsim.vehicles.Vehicle;
-import java.util.TreeMap;
-
/*package-private*/ final class CarrierTourStartEventCreator implements CarrierEventCreator {
final TreeMap, ActivityEndEvent> endEventMap = new TreeMap<>();
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierServiceStartEventHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierServiceStartEventHandler.java
index a8ea55c13e8..362974eae3f 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierServiceStartEventHandler.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierServiceStartEventHandler.java
@@ -24,7 +24,6 @@
import org.matsim.core.events.handler.EventHandler;
import org.matsim.freight.carriers.events.CarrierServiceStartEvent;
-
public interface CarrierServiceStartEventHandler extends EventHandler {
void handleEvent( CarrierServiceStartEvent event );
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourEndEventHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourEndEventHandler.java
index 2d30ce4d70c..d14a5d285cf 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourEndEventHandler.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourEndEventHandler.java
@@ -24,7 +24,6 @@
import org.matsim.core.events.handler.EventHandler;
import org.matsim.freight.carriers.events.CarrierTourEndEvent;
-
public interface CarrierTourEndEventHandler extends EventHandler {
void handleEvent( CarrierTourEndEvent event );
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourStartEventHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourStartEventHandler.java
index 5f4b26ce4bb..3a7997cc9ef 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourStartEventHandler.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourStartEventHandler.java
@@ -24,7 +24,6 @@
import org.matsim.core.events.handler.EventHandler;
import org.matsim.freight.carriers.events.CarrierTourStartEvent;
-
public interface CarrierTourStartEventHandler extends EventHandler {
void handleEvent( CarrierTourStartEvent event );
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/Vehicle2CarrierEventHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/Vehicle2CarrierEventHandler.java
index bc9236decbf..0d5b9902f57 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/Vehicle2CarrierEventHandler.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/Vehicle2CarrierEventHandler.java
@@ -20,15 +20,14 @@
*/
package org.matsim.freight.carriers.events.eventhandler;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import org.matsim.api.core.v01.Id;
import org.matsim.freight.carriers.Carrier;
import org.matsim.freight.carriers.events.CarrierTourEndEvent;
import org.matsim.freight.carriers.events.CarrierTourStartEvent;
import org.matsim.vehicles.Vehicle;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
/**
* Basic event handler that collects the relation between vehicles and carrier.
* Necessary since link enter and leave events do not contain any information of the carrier.
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/DistanceConstraint.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/DistanceConstraint.java
index 068c70506cd..8615e0b3d75 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/DistanceConstraint.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/DistanceConstraint.java
@@ -94,7 +94,7 @@ public ConstraintsStatus fulfilled(JobInsertionContext context, TourActivity pre
consumptionPerMeter = VehicleUtils
.getEnergyConsumptionKWhPerMeter(vehicleTypeOfNewVehicle.getEngineInformation());
else
- consumptionPerMeter = VehicleUtils.getFuelConsumption(vehicleTypeOfNewVehicle);
+ consumptionPerMeter = VehicleUtils.getFuelConsumptionLitersPerMeter(vehicleTypeOfNewVehicle.getEngineInformation());
double routeDistance = calculateRouteDistance(context, newVehicle);
double routeConsumption = routeDistance * (consumptionPerMeter);
@@ -212,9 +212,9 @@ private double calculateRouteDistance(JobInsertionContext context, Vehicle newVe
* directly behind the new pickup. This method gives back the minimal distance
* of this three options.
*
- * @param context
- * @param newInvestigatedPickup
- * @param nextAct
+ * @param context the context of the job insertion
+ * @param newInvestigatedPickup the new pickup which should be added to the tour
+ * @param nextAct the next activity after the new pickup
* @return minimal distance of the associated delivery
*/
private double findMinimalAdditionalDistance(JobInsertionContext context, TourActivity newInvestigatedPickup,
@@ -283,8 +283,8 @@ private double findMinimalAdditionalDistance(JobInsertionContext context, TourAc
/**
* Checks if the find possible distance is the minimal one.
*
- * @param minimalAdditionalDistance
- * @param possibleAdditionalDistance
+ * @param minimalAdditionalDistance the minimal additional distance
+ * @param possibleAdditionalDistance the possible additional distance
* @return the minimal transport distance
*/
private double findMinimalDistance(double minimalAdditionalDistance, double possibleAdditionalDistance) {
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/MatsimJspritFactory.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/MatsimJspritFactory.java
index 8710e50c7ba..00cf9347716 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/MatsimJspritFactory.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/MatsimJspritFactory.java
@@ -45,6 +45,10 @@
import com.graphhopper.jsprit.io.algorithm.AlgorithmConfig;
import com.graphhopper.jsprit.io.algorithm.AlgorithmConfigXmlReader;
import com.graphhopper.jsprit.io.algorithm.VehicleRoutingAlgorithms;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Coord;
@@ -57,11 +61,6 @@
import org.matsim.vehicles.VehicleType;
import org.matsim.vehicles.VehicleUtils;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
/**
* A factory that creates matsim-object from jsprit
* (...) and vice versa.
@@ -686,9 +685,6 @@ public static Carrier createCarrier(String carrierId, VehicleRoutingProblem vrp)
capabilityBuilder.setFleetSize(CarrierCapabilities.FleetSize.FINITE);
} else
capabilityBuilder.setFleetSize(CarrierCapabilities.FleetSize.INFINITE);
- for (com.graphhopper.jsprit.core.problem.vehicle.VehicleType type : vrp.getTypes()) {
- capabilityBuilder.addType(createMatsimVehicleType(type));
- }
for (Vehicle vehicle : vrp.getVehicles()) {
capabilityBuilder.addVehicle(createCarrierVehicle(vehicle));
}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java
index e6d8e1a0e45..aa18f9d2487 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java
@@ -26,6 +26,8 @@
import com.graphhopper.jsprit.core.problem.driver.Driver;
import com.graphhopper.jsprit.core.problem.vehicle.Vehicle;
import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.network.Network;
@@ -45,9 +47,6 @@
import org.matsim.vehicles.VehicleType;
import org.matsim.vehicles.VehicleUtils;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-
/**
* This calculates transport-times, transport-costs and the distance to cover
* the distance from one location to another. It calculates these values based
@@ -658,12 +657,12 @@ private VehicleImpl getDefaultVehicle(Location fromId) {
private void informEndCalc() {
for (InternalLeastCostPathCalculatorListener l : listeners)
- l.endCalculation(Thread.currentThread().getId());
+ l.endCalculation(Thread.currentThread().threadId());
}
private void informStartCalc() {
for (InternalLeastCostPathCalculatorListener l : listeners)
- l.startCalculation(Thread.currentThread().getId());
+ l.startCalculation(Thread.currentThread().threadId());
}
/**
@@ -853,11 +852,11 @@ public LeastCostPathCalculator getRouter() {
}
private LeastCostPathCalculator createLeastCostPathCalculator() {
- LeastCostPathCalculator router = routerCache.get(Thread.currentThread().getId());
+ LeastCostPathCalculator router = routerCache.get(Thread.currentThread().threadId());
if (router == null) {
LeastCostPathCalculator newRouter = leastCostPathCalculatorFactory.createPathCalculator(network,
travelDisutility, travelTime);
- router = routerCache.putIfAbsent(Thread.currentThread().getId(), newRouter);
+ router = routerCache.putIfAbsent(Thread.currentThread().threadId(), newRouter);
if (router == null) {
router = newRouter;
}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsFactory.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsFactory.java
index 6a0be5414f0..558ec523a81 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsFactory.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsFactory.java
@@ -21,19 +21,18 @@
package org.matsim.freight.carriers.jsprit;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.router.util.TravelTime;
-import org.matsim.freight.carriers.FreightCarriersConfigGroup;
import org.matsim.freight.carriers.Carriers;
+import org.matsim.freight.carriers.FreightCarriersConfigGroup;
import org.matsim.vehicles.VehicleType;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
/**
* @author steffenaxer
*/
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkRouter.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkRouter.java
index 7dac94a1c8c..2388801503b 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkRouter.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkRouter.java
@@ -22,7 +22,7 @@
import org.matsim.freight.carriers.CarrierPlan;
import org.matsim.freight.carriers.ScheduledTour;
-import org.matsim.freight.carriers.controler.CarrierTimeAndSpaceTourRouter;
+import org.matsim.freight.carriers.controller.CarrierTimeAndSpaceTourRouter;
/**
* Router that routes {@link CarrierPlan}.
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/VehicleTypeDependentRoadPricingCalculator.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/VehicleTypeDependentRoadPricingCalculator.java
index 6175780ab9a..7c9541f5777 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/VehicleTypeDependentRoadPricingCalculator.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/VehicleTypeDependentRoadPricingCalculator.java
@@ -21,14 +21,12 @@
package org.matsim.freight.carriers.jsprit;
import com.graphhopper.jsprit.core.problem.vehicle.VehicleType;
+import java.util.*;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.contrib.roadpricing.RoadPricingScheme;
import org.matsim.contrib.roadpricing.RoadPricingSchemeImpl.Cost;
-import java.util.*;
-
-
/**
* Calculator that manages and calculates vehicle type dependent road pricing schemas.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/analysis/CarrierScoreStats.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/analysis/CarrierScoreStats.java
index 84556de1a14..ab4fa18632f 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/analysis/CarrierScoreStats.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/analysis/CarrierScoreStats.java
@@ -21,6 +21,10 @@
package org.matsim.freight.carriers.usecases.analysis;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.Locale;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.core.controler.events.IterationEndsEvent;
@@ -35,11 +39,6 @@
import org.matsim.freight.carriers.CarrierPlan;
import org.matsim.freight.carriers.Carriers;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.util.Locale;
-
/**
* As you can see, it is basically a copy of {@link org.matsim.analysis.ScoreStatsControlerListener}. However, it is modified to score {@link Carrier}s
* rather than Persons. (Oct'13, schroeder)
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/analysis/LegHistogram.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/analysis/LegHistogram.java
index fff393eee93..1954eff762e 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/analysis/LegHistogram.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/analysis/LegHistogram.java
@@ -22,6 +22,14 @@
package org.matsim.freight.carriers.usecases.analysis;
import jakarta.inject.Inject;
+import java.awt.*;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtils;
import org.jfree.chart.JFreeChart;
@@ -42,15 +50,6 @@
import org.matsim.api.core.v01.population.Population;
import org.matsim.core.utils.misc.Time;
-import java.awt.*;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
/**
* It is a copy of {@link org.matsim.analysis.LegHistogram}. It is modified to include or exclude persons.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/CarrierScoringFunctionFactoryImpl.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/CarrierScoringFunctionFactoryImpl.java
index 759b3da5890..ee2b54c9399 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/CarrierScoringFunctionFactoryImpl.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/CarrierScoringFunctionFactoryImpl.java
@@ -22,6 +22,8 @@
package org.matsim.freight.carriers.usecases.chessboard;
import com.google.inject.Inject;
+import java.util.HashSet;
+import java.util.Set;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
@@ -36,14 +38,11 @@
import org.matsim.core.scoring.ScoringFunction;
import org.matsim.core.scoring.SumScoringFunction;
import org.matsim.freight.carriers.*;
-import org.matsim.freight.carriers.controler.CarrierScoringFunctionFactory;
-import org.matsim.freight.carriers.controler.FreightActivity;
+import org.matsim.freight.carriers.controller.CarrierScoringFunctionFactory;
+import org.matsim.freight.carriers.controller.FreightActivity;
import org.matsim.freight.carriers.jsprit.VehicleTypeDependentRoadPricingCalculator;
import org.matsim.vehicles.Vehicle;
-import java.util.HashSet;
-import java.util.Set;
-
/**
* Defines example carrier scoring function (factory).
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/FreightScenarioCreator.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/FreightScenarioCreator.java
index c258d01e703..3d291829b77 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/FreightScenarioCreator.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/FreightScenarioCreator.java
@@ -21,6 +21,9 @@
package org.matsim.freight.carriers.usecases.chessboard;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.network.Link;
@@ -34,10 +37,6 @@
import org.matsim.vehicles.VehicleType;
import org.matsim.vehicles.VehicleUtils;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
/**
* Creates chessboard freight scenario.
*
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/InitialCarrierPlanCreator.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/InitialCarrierPlanCreator.java
index fb2979e4be1..72c6d90df96 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/InitialCarrierPlanCreator.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/InitialCarrierPlanCreator.java
@@ -34,6 +34,7 @@
import com.graphhopper.jsprit.io.algorithm.AlgorithmConfig;
import com.graphhopper.jsprit.io.algorithm.AlgorithmConfigXmlReader;
import com.graphhopper.jsprit.io.algorithm.VehicleRoutingAlgorithms;
+import java.util.Collection;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.network.Network;
import org.matsim.core.config.Config;
@@ -44,8 +45,6 @@
import org.matsim.freight.carriers.jsprit.NetworkBasedTransportCosts;
import org.matsim.freight.carriers.jsprit.NetworkRouter;
-import java.util.Collection;
-
final class InitialCarrierPlanCreator {
private final Network network;
@@ -166,8 +165,6 @@ public static void main(String[] args) {
Carriers carriers = new Carriers();
new CarrierPlanXmlReader(carriers, types ).readFile("input/usecases/chessboard/freight/carrierPlansWithoutRoutes_10minTW.xml" );
- new CarrierVehicleTypeLoader(carriers).loadVehicleTypes(types);
-
for(Carrier carrier : carriers.getCarriers().values()){
CarrierPlan plan = new InitialCarrierPlanCreator(scenario.getNetwork()).createPlan(carrier);
carrier.addPlan(plan);
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/InnerOuterCityScenarioCreator.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/InnerOuterCityScenarioCreator.java
index d5b48f1df69..789a5681a46 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/InnerOuterCityScenarioCreator.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/InnerOuterCityScenarioCreator.java
@@ -21,12 +21,11 @@
package org.matsim.freight.carriers.usecases.chessboard;
-import org.matsim.api.core.v01.Id;
-import org.matsim.api.core.v01.network.Link;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.network.Link;
final class InnerOuterCityScenarioCreator {
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/PassengerScenarioCreator.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/PassengerScenarioCreator.java
index 3a742ced5e6..1060931835e 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/PassengerScenarioCreator.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/PassengerScenarioCreator.java
@@ -21,6 +21,8 @@
package org.matsim.freight.carriers.usecases.chessboard;
+import java.util.ArrayList;
+import java.util.List;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.TransportMode;
@@ -36,9 +38,6 @@
import org.matsim.core.router.util.LeastCostPathCalculator.Path;
import org.matsim.core.scenario.ScenarioUtils;
-import java.util.ArrayList;
-import java.util.List;
-
final class PassengerScenarioCreator {
static int agentCounter = 1;
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/PlotPlans.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/PlotPlans.java
index 838ac5463ae..9e615dda9f4 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/PlotPlans.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/PlotPlans.java
@@ -47,8 +47,6 @@ public static void main(String[] args) {
// new CarrierPlanXmlReader(carriers).read("input/usecases/chessboard/freight/singleCarrierTwentyActivities.xml");
new CarrierPlanXmlReader(carriers, types ).readFile("output/ITERS/it.140/140.carrierPlans.xml" );
- new CarrierVehicleTypeLoader(carriers).loadVehicleTypes(types);
-
final Carrier carrier = carriers.getCarriers().get(Id.create("carrier1",Carrier.class));
VehicleRoutingProblem.Builder vrpBuilder = MatsimJspritFactory.createRoutingProblemBuilder(carrier, scenario.getNetwork());
VehicleRoutingProblem vrp = vrpBuilder.build();
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/RunChessboard.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/RunChessboard.java
index e8f7887cfea..ff62264a468 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/RunChessboard.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/RunChessboard.java
@@ -23,14 +23,13 @@
import com.google.inject.Provider;
import jakarta.inject.Inject;
+import java.util.Map;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.network.Network;
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 org.matsim.core.controler.OutputDirectoryHierarchy;
+import org.matsim.core.controler.*;
import org.matsim.core.controler.events.IterationEndsEvent;
import org.matsim.core.controler.listener.IterationEndsListener;
import org.matsim.core.replanning.GenericPlanStrategyImpl;
@@ -46,12 +45,10 @@
import org.matsim.core.utils.io.IOUtils;
import org.matsim.examples.ExamplesUtils;
import org.matsim.freight.carriers.*;
-import org.matsim.freight.carriers.controler.*;
+import org.matsim.freight.carriers.controller.*;
import org.matsim.freight.carriers.usecases.analysis.CarrierScoreStats;
import org.matsim.freight.carriers.usecases.analysis.LegHistogram;
-import java.util.Map;
-
public final class RunChessboard {
public static void main(String[] args){
@@ -74,11 +71,11 @@ public static void main(String[] args){
Carriers carriers = CarriersUtils.addOrGetCarriers( scenario );
CarrierVehicleTypes types = CarriersUtils.getCarrierVehicleTypes( scenario );
- Controler controler = new Controler( scenario);
+ Controller controller = ControllerUtils.createController( scenario );
- controler.addOverridingModule(new CarrierModule() );
+ controller.addOverridingModule(new CarrierModule() );
- controler.addOverridingModule(new AbstractModule() {
+ controller.addOverridingModule(new AbstractModule() {
@Override
public void install() {
@@ -113,7 +110,7 @@ public void install() {
}
});
- controler.run();
+ controller.run();
}
@@ -139,7 +136,7 @@ private static class MyCarrierPlanStrategyManagerProvider implements Provider strategy = new GenericPlanStrategyImpl<>( new ExpBetaPlanChanger.Factory().build() );
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/RunPassengerAlongWithCarriers.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/RunPassengerAlongWithCarriers.java
index 9d54c7299e1..2561968e1f2 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/RunPassengerAlongWithCarriers.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/RunPassengerAlongWithCarriers.java
@@ -23,16 +23,15 @@
import com.google.inject.Provider;
import jakarta.inject.Inject;
+import java.net.URL;
+import java.util.Map;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.network.Network;
import org.matsim.core.api.experimental.events.EventsManager;
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 org.matsim.core.controler.MatsimServices;
-import org.matsim.core.controler.OutputDirectoryHierarchy;
+import org.matsim.core.controler.*;
import org.matsim.core.controler.listener.IterationEndsListener;
import org.matsim.core.gbl.Gbl;
import org.matsim.core.replanning.GenericPlanStrategyImpl;
@@ -47,13 +46,10 @@
import org.matsim.core.utils.io.IOUtils;
import org.matsim.examples.ExamplesUtils;
import org.matsim.freight.carriers.*;
-import org.matsim.freight.carriers.controler.*;
+import org.matsim.freight.carriers.controller.*;
import org.matsim.freight.carriers.usecases.analysis.CarrierScoreStats;
import org.matsim.freight.carriers.usecases.analysis.LegHistogram;
-import java.net.URL;
-import java.util.Map;
-
final class RunPassengerAlongWithCarriers {
final static URL url = ExamplesUtils.getTestScenarioURL("freight-chessboard-9x9");
@@ -67,7 +63,7 @@ public void run() {
Scenario scenario = prepareScenario(config);
- Controler controler = new Controler(scenario);
+ Controller controller = ControllerUtils.createController(scenario);
CarrierVehicleTypes types = new CarrierVehicleTypes();
new CarrierVehicleTypeReader(types).readURL( IOUtils.extendUrl(url, "vehicleTypes.xml" ) );
@@ -75,9 +71,9 @@ public void run() {
final Carriers carriers = new Carriers();
new CarrierPlanXmlReader(carriers, types ).readURL( IOUtils.extendUrl(url, "carrierPlans.xml" ) );
- controler.addOverridingModule( new CarrierModule() );
+ controller.addOverridingModule( new CarrierModule() );
- controler.addOverridingModule( new AbstractModule(){
+ controller.addOverridingModule( new AbstractModule(){
@Override public void install(){
this.bind( CarrierStrategyManager.class ).toProvider( new MyCarrierPlanStrategyManagerFactory(types) );
this.bind( CarrierScoringFunctionFactory.class ).toInstance(carrier -> {
@@ -91,15 +87,16 @@ public void run() {
} );
- prepareFreightOutputDataAndStats(scenario, controler.getEvents(), controler, carriers);
+ prepareFreightOutputDataAndStats(scenario, controller.getEvents(), controller, carriers);
- controler.run();
+ controller.run();
}
public Config prepareConfig() {
Config config = ConfigUtils.loadConfig(IOUtils.extendUrl(url, "config.xml"));
config.controller().setOverwriteFileSetting( OutputDirectoryHierarchy.OverwriteFileSetting.overwriteExistingFiles );
+ config.controller().setLastIteration(5);
config.global().setRandomSeed(4177);
config.controller().setOutputDirectory("./output/");
return config;
@@ -153,7 +150,7 @@ public MyCarrierPlanStrategyManagerFactory(CarrierVehicleTypes types) {
final TravelDisutility travelDisutility = CarrierTravelDisutilities.createBaseDisutility(types, modeTravelTimes.get(TransportMode.car ) );
final LeastCostPathCalculator router = leastCostPathCalculatorFactory.createPathCalculator(network, travelDisutility, modeTravelTimes.get(TransportMode.car));
- final CarrierStrategyManager carrierStrategyManager = CarrierControlerUtils.createDefaultCarrierStrategyManager();
+ final CarrierStrategyManager carrierStrategyManager = CarrierControllerUtils.createDefaultCarrierStrategyManager();
carrierStrategyManager.setMaxPlansPerAgent(5);
carrierStrategyManager.addStrategy(new GenericPlanStrategyImpl<>(new BestPlanSelector<>()), null, 0.95);
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/SelectBestPlanAndOptimizeItsVehicleRouteFactory.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/SelectBestPlanAndOptimizeItsVehicleRouteFactory.java
index 0051af3de81..a043c85d958 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/SelectBestPlanAndOptimizeItsVehicleRouteFactory.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/SelectBestPlanAndOptimizeItsVehicleRouteFactory.java
@@ -30,6 +30,8 @@
import com.graphhopper.jsprit.core.problem.vehicle.Vehicle;
import com.graphhopper.jsprit.core.util.Solutions;
import com.graphhopper.jsprit.io.algorithm.VehicleRoutingAlgorithms;
+import java.net.URL;
+import java.util.Collection;
import org.matsim.api.core.v01.network.Network;
import org.matsim.core.replanning.GenericPlanStrategy;
import org.matsim.core.replanning.GenericPlanStrategyImpl;
@@ -46,9 +48,6 @@
import org.matsim.freight.carriers.jsprit.NetworkBasedTransportCosts;
import org.matsim.freight.carriers.jsprit.NetworkRouter;
-import java.net.URL;
-import java.util.Collection;
-
final class SelectBestPlanAndOptimizeItsVehicleRouteFactory {
final URL url = ExamplesUtils.getTestScenarioURL("freight-chessboard-9x9");
diff --git a/contribs/freight/src/main/java/org/matsim/freight/logistics/ForwardLogisticChainSchedulerImpl.java b/contribs/freight/src/main/java/org/matsim/freight/logistics/ForwardLogisticChainSchedulerImpl.java
new file mode 100644
index 00000000000..71d76c307ce
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/logistics/ForwardLogisticChainSchedulerImpl.java
@@ -0,0 +1,189 @@
+/*
+ * *********************************************************************** *
+ * * project: org.matsim.*
+ * * *********************************************************************** *
+ * * *
+ * * copyright : (C) 2022 by the members listed in the COPYING, *
+ * * LICENSE and WARRANTY file. *
+ * * email : info at matsim dot org *
+ * * *
+ * * *********************************************************************** *
+ * * *
+ * * This program is free software; you can redistribute it and/or modify *
+ * * it under the terms of the GNU General Public License as published by *
+ * * the Free Software Foundation; either version 2 of the License, or *
+ * * (at your option) any later version. *
+ * * See also COPYING, LICENSE and WARRANTY file *
+ * * *
+ * * ***********************************************************************
+ */
+
+package org.matsim.freight.logistics;
+
+import java.util.ArrayList;
+import org.matsim.api.core.v01.Id;
+import org.matsim.freight.logistics.shipment.LspShipment;
+
+/**
+ * .... Macht 3 Schritte: 1.) the LSPShipments are handed over to the first {@link
+ * LogisticChainElement} of their {@link LogisticChain} 2.) the neighbors, i.e. the predecessors and
+ * successors of all {@link LSPResource}s are determined 3.) the Resources are brought into the
+ * right sequence according to the algorithm.
+ *
+ *
When traversing this list of {@link LSPResource}s, the operations in each {@link LSPResource}
+ * are scheduled individually by calling their {@link LSPResourceScheduler}.
+ */
+/* package-private */ class ForwardLogisticChainSchedulerImpl implements LogisticChainScheduler {
+
+ /**
+ * The Resources are brought into the right sequence according to the algorithm. The result of
+ * this algorithm is a list of Resources that is later traversed from the front to the back, i.e.
+ * starting with the entry at index 0. In the algorithm, this list is called sortedResourceList.
+ */
+ private final ArrayList sortedResourceList;
+
+ /**
+ * The determination of the neighborhood structure among the Resources resulted in the
+ * neighborList.
+ */
+ private final ArrayList neighbourList;
+
+ private LSP lsp;
+ private int bufferTime;
+
+ ForwardLogisticChainSchedulerImpl() {
+ this.sortedResourceList = new ArrayList<>();
+ this.neighbourList = new ArrayList<>();
+ }
+
+ @Override
+ public void scheduleLogisticChain() {
+ insertShipmentsAtBeginning();
+ setResourceNeighbours();
+ sortResources();
+ for (LSPResource resource : sortedResourceList) {
+ resource.schedule(bufferTime, lsp.getSelectedPlan());
+ }
+ }
+
+ @Override
+ public void setEmbeddingContainer(LSP lsp) {
+ this.lsp = lsp;
+ }
+
+ private void setResourceNeighbours() {
+ // internal data structure, try to ignore when looking from outside. kai/kai, jan'22
+ neighbourList.clear();
+ for (LSPResource resource : lsp.getResources()) {
+ ResourceNeighbours neighbours = new ResourceNeighbours(resource);
+ for (LogisticChainElement element : resource.getClientElements()) {
+ LogisticChainElement predecessor = element.getPreviousElement();
+ LSPResource previousResource = predecessor.getResource();
+ neighbours.addPredecessor(previousResource);
+ LogisticChainElement successor = element.getNextElement();
+ LSPResource nextResource = successor.getResource();
+ neighbours.addSuccessor(nextResource);
+ }
+ neighbourList.add(neighbours);
+ }
+ }
+
+ private void sortResources() {
+ sortedResourceList.clear();
+ while (!neighbourList.isEmpty()) {
+ for (ResourceNeighbours neighbours : neighbourList) {
+ if (allPredecessorsAlreadyScheduled(neighbours)
+ && noSuccessorAlreadyScheduled(neighbours)) {
+ sortedResourceList.add(neighbours.resource);
+ neighbourList.remove(neighbours);
+ }
+ }
+ }
+ }
+
+ private boolean allPredecessorsAlreadyScheduled(ResourceNeighbours neighbours) {
+ if (neighbours.predecessors.isEmpty()) {
+ return true;
+ }
+
+ for (LSPResource predecessor : neighbours.predecessors) {
+ if (!sortedResourceList.contains(predecessor)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean noSuccessorAlreadyScheduled(ResourceNeighbours neighbours) {
+ if (neighbours.successors.isEmpty()) {
+ return true;
+ }
+
+ for (LSPResource successor : neighbours.successors) {
+ if (!sortedResourceList.contains(successor)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void insertShipmentsAtBeginning() {
+ for (LogisticChain solution : lsp.getSelectedPlan().getLogisticChains()) {
+ LogisticChainElement firstElement = getFirstElement(solution);
+ assert firstElement != null;
+ for (Id lspShipmentId : solution.getLspShipmentIds()) {
+ var shipment = LSPUtils.findLspShipment(lsp, lspShipmentId);
+ assert shipment != null;
+ firstElement
+ .getIncomingShipments()
+ .addShipment(shipment.getPickupTimeWindow().getStart(), shipment);
+ }
+ }
+ }
+
+ private LogisticChainElement getFirstElement(LogisticChain solution) {
+ for (LogisticChainElement element : solution.getLogisticChainElements()) {
+ if (element.getPreviousElement() == null) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void setBufferTime(int bufferTime) {
+ this.bufferTime = bufferTime;
+ }
+
+ /**
+ * The relationship between different {@link LSPResource}s allows to handle various supply
+ * structures that the {@link LSP} might decide to maintain. Thus, a {@link LSPResource} can have
+ * several successors or predecessors or can be used by several different {@link LogisticChain}s.
+ * The neighborhood structure among the {@link LSPResource}s is stored in instances of the class
+ * {@link ResourceNeighbours} which contain references on the considered {@link LSPResource} and
+ * on the set of immediate successors respective predecessors. As the result of this step, a
+ * collection of {@link ResourceNeighbours} called neighborList is created that contains the
+ * neighbors of all {@link LSPResource}s in the plan of the considered {@link LSP}.
+ */
+ private static class ResourceNeighbours {
+ // internal data structure, try to ignore when looking from outside. kai/kai, jan'22
+
+ private final ArrayList predecessors;
+ private final ArrayList successors;
+ private final LSPResource resource;
+
+ private ResourceNeighbours(LSPResource resource) {
+ this.resource = resource;
+ this.predecessors = new ArrayList<>();
+ this.successors = new ArrayList<>();
+ }
+
+ private void addPredecessor(LSPResource resource) {
+ this.predecessors.add(resource);
+ }
+
+ private void addSuccessor(LSPResource resource) {
+ this.successors.add(resource);
+ }
+ }
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/logistics/FreightLogisticsConfigGroup.java b/contribs/freight/src/main/java/org/matsim/freight/logistics/FreightLogisticsConfigGroup.java
new file mode 100644
index 00000000000..bab230379ba
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/logistics/FreightLogisticsConfigGroup.java
@@ -0,0 +1,142 @@
+/*
+ *********************************************************************** *
+ * project: org.matsim.*
+ * *
+ * *********************************************************************** *
+ * *
+ * copyright : (C) 2024 by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * ***********************************************************************
+ */
+
+package org.matsim.freight.logistics;
+
+import java.net.URL;
+import java.util.Map;
+import org.matsim.core.config.ConfigGroup;
+import org.matsim.core.config.ReflectiveConfigGroup;
+
+public class FreightLogisticsConfigGroup extends ReflectiveConfigGroup {
+
+ public static final String GROUPNAME="freightLogistics" ;
+
+ private String lspsFile;
+ static final String LSPS_FILE = "lspsFile";
+ private static final String LSPS_FILE_DESC = "Freight LogisticsServiceProviders (LSP)s File, according to MATSim logistics extension as part of MATSim's freight contrib.";
+
+ public FreightLogisticsConfigGroup() {
+ super(GROUPNAME);
+ }
+
+ //### CarriersFile ###
+ /**
+ * @return -- {@value #LSPS_FILE_DESC}
+ */
+ @StringGetter(LSPS_FILE)
+ public String getLspsFile() {
+ return lspsFile;
+ }
+
+ URL getLspsFileUrl(URL context) {
+ return ConfigGroup.getInputFileURL(context, this.lspsFile);
+ }
+
+ /**
+ * @param -- {@value #LSPS_FILE_DESC}
+ */
+ @StringSetter(LSPS_FILE)
+ public void setLspsFile(String lspsFile) {
+ this.lspsFile = lspsFile;
+ }
+
+
+
+ //---
+ // Commenting this out, because in a frist step I think it is better/ more streight forward to have the VRP logic in the carriers as an attribute.
+ // please see {@link CarrierSchedulerUtils#setVrpLogic(carrier, VRPLogic)} and {@link CarrierSchedulerUtils#getVrpLogic(carrier)}
+ //---
+
+// static final String VRP_LOGIC_OF_DISTRIBUTION_CARRIER = "vrpLogicOfDistributionCarrier";
+// private LSPUtils.LogicOfVrp vrpLogicOfDistributionCarrier = LSPUtils.LogicOfVrp.serviceBased;
+// private static final String VRP_LOGIC_OF_DISTRIBUTION_CARRIER_DESC = "Define, on which type of jobs the VRP of the **distribution** carrier will base on:" + Arrays.toString(LSPUtils.LogicOfVrp.values());
+//
+// static final String VRP_LOGIC_OF_MAINRUN_CARRIER = "vrpLogicOfMainRunCarrier";
+// private LSPUtils.LogicOfVrp vrpLogicOfMainRunCarrier = LSPUtils.LogicOfVrp.serviceBased;
+// private static final String VRP_LOGIC_OF_MAINRUN_CARRIER_DESC = "Define, on which type of jobs the VRP of the **MainRun** carrier will base on:" + Arrays.toString(LSPUtils.LogicOfVrp.values());
+//
+// static final String VRP_LOGIC_OF_COLLECTION_CARRIER = "vrpLogicOfCollectionCarrier";
+// private LSPUtils.LogicOfVrp vrpLogicOfCollectionCarrier = LSPUtils.LogicOfVrp.serviceBased;
+// private static final String VRP_LOGIC_OF_COLLECTION_CARRIER_DESC = "Define, on which type of jobs the VRP of the **Collection** carrier will base on:" + Arrays.toString(LSPUtils.LogicOfVrp.values());
+//
+// /**
+// *
+// * @return The internal type of jobs, on which the VRPs of the distribution carrier bases on.
+// */
+// @StringGetter(VRP_LOGIC_OF_DISTRIBUTION_CARRIER)
+// public LSPUtils.LogicOfVrp getVrpLogicOfDistributionCarrier() {
+// return vrpLogicOfDistributionCarrier;
+// }
+//
+// /**
+// * @param vrpLogicOfDistributionCarrier {@value #VRP_LOGIC_OF_DISTRIBUTION_CARRIER}
+// */
+// @StringSetter(VRP_LOGIC_OF_DISTRIBUTION_CARRIER)
+// public void setVrpLogicOfDistributionCarrier(LSPUtils.LogicOfVrp vrpLogicOfDistributionCarrier) {
+// this.vrpLogicOfDistributionCarrier = vrpLogicOfDistributionCarrier;
+// }
+//
+// /**
+// * @return The internal type of jobs, on which the VRPs of the main run carrier bases on.
+// */
+// @StringGetter(FreightLogisticsConfigGroup.VRP_LOGIC_OF_MAINRUN_CARRIER)
+// public LSPUtils.LogicOfVrp getVrpLogicOfMainRunCarrier() {
+// return vrpLogicOfMainRunCarrier;
+// }
+//
+// /**
+// * @param vrpLogicOfMainRunCarrier {@value #VRP_LOGIC_OF_MAINRUN_CARRIER}
+// */
+// @StringSetter(FreightLogisticsConfigGroup.VRP_LOGIC_OF_MAINRUN_CARRIER)
+// public void setVrpLogicOfMainRunCarrier(LSPUtils.LogicOfVrp vrpLogicOfMainRunCarrier) {
+// this.vrpLogicOfMainRunCarrier = vrpLogicOfMainRunCarrier;
+// }
+//
+// /**
+// * @return The internal type of jobs, on which the VRPs of the collection carrier bases on.
+// */
+// @StringGetter(FreightLogisticsConfigGroup.VRP_LOGIC_OF_COLLECTION_CARRIER)
+// public LSPUtils.LogicOfVrp getVrpLogicOfCollectionCarrier() {
+// return vrpLogicOfCollectionCarrier;
+// }
+//
+// /**
+// * @param vrpLogicOfCollectionCarrier {@value #VRP_LOGIC_OF_COLLECTION_CARRIER}
+// */
+// @StringSetter(FreightLogisticsConfigGroup.VRP_LOGIC_OF_COLLECTION_CARRIER)
+// public void setVrpLogicOfCollectionCarrier(LSPUtils.LogicOfVrp vrpLogicOfCollectionCarrier) {
+// this.vrpLogicOfCollectionCarrier = vrpLogicOfCollectionCarrier;
+// }
+
+ //---
+ //---
+ @Override
+ public Map getComments() {
+ Map map = super.getComments();
+ map.put(LSPS_FILE, LSPS_FILE_DESC);
+// map.put(VRP_LOGIC_OF_DISTRIBUTION_CARRIER, VRP_LOGIC_OF_DISTRIBUTION_CARRIER_DESC);
+// map.put(VRP_LOGIC_OF_MAINRUN_CARRIER, VRP_LOGIC_OF_MAINRUN_CARRIER_DESC);
+// map.put(VRP_LOGIC_OF_COLLECTION_CARRIER, VRP_LOGIC_OF_COLLECTION_CARRIER_DESC);
+ return map;
+ }
+
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/logistics/HasBackpointer.java b/contribs/freight/src/main/java/org/matsim/freight/logistics/HasBackpointer.java
new file mode 100644
index 00000000000..73f97386951
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/logistics/HasBackpointer.java
@@ -0,0 +1,12 @@
+package org.matsim.freight.logistics;
+
+@SuppressWarnings("InterfaceMayBeAnnotatedFunctional")
+public interface HasBackpointer {
+ // In general, we set backpointers when we add to the container.
+
+ // yy maybe also have interface HasSettableBackpointer?
+ void setEmbeddingContainer(T pointer);
+
+ // T getEmbeddingContainer();
+
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/logistics/HasLspShipmentId.java b/contribs/freight/src/main/java/org/matsim/freight/logistics/HasLspShipmentId.java
new file mode 100644
index 00000000000..e3ddd1fc2f5
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/logistics/HasLspShipmentId.java
@@ -0,0 +1,32 @@
+/* *********************************************************************** *
+ * project: org.matsim.* *
+ * *
+ * *********************************************************************** *
+ * *
+ * copyright : (C) 2008 by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * *********************************************************************** */
+package org.matsim.freight.logistics;
+
+import org.matsim.api.core.v01.Id;
+import org.matsim.freight.logistics.shipment.LspShipment;
+
+/**
+ * @author Kai Martins-Turner (kturner)
+ */
+public interface HasLspShipmentId {
+
+ String ATTRIBUTE_LSP_SHIPMENT_ID = "lspShipmentId";
+
+ Id getLspShipmentId();
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/logistics/HasSimulationTrackers.java b/contribs/freight/src/main/java/org/matsim/freight/logistics/HasSimulationTrackers.java
new file mode 100644
index 00000000000..33ba50074ed
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/logistics/HasSimulationTrackers.java
@@ -0,0 +1,14 @@
+package org.matsim.freight.logistics;
+
+import java.util.Collection;
+
+// One could say that the simulation trackers are the decorators that convert the data objects into
+// behavioral objects. In core matsim, we instead
+// create behavioral objects, which contain the data objects. E.g. MobsimAgent, DriverAgent,
+// CarrierAgent, etc. kai, may'22
+public interface HasSimulationTrackers {
+
+ void addSimulationTracker(LSPSimulationTracker tracker);
+
+ Collection> getSimulationTrackers();
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/logistics/InitialShipmentAssigner.java b/contribs/freight/src/main/java/org/matsim/freight/logistics/InitialShipmentAssigner.java
new file mode 100644
index 00000000000..eb6ff6287e7
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/logistics/InitialShipmentAssigner.java
@@ -0,0 +1,43 @@
+/*
+ * *********************************************************************** *
+ * * project: org.matsim.*
+ * * *********************************************************************** *
+ * * *
+ * * copyright : (C) 2022 by the members listed in the COPYING, *
+ * * LICENSE and WARRANTY file. *
+ * * email : info at matsim dot org *
+ * * *
+ * * *********************************************************************** *
+ * * *
+ * * This program is free software; you can redistribute it and/or modify *
+ * * it under the terms of the GNU General Public License as published by *
+ * * the Free Software Foundation; either version 2 of the License, or *
+ * * (at your option) any later version. *
+ * * See also COPYING, LICENSE and WARRANTY file *
+ * * *
+ * * ***********************************************************************
+ */
+
+package org.matsim.freight.logistics;
+
+import org.matsim.freight.logistics.shipment.LspShipment;
+
+/**
+ * Takes an {@link LspShipment} and normally assigns it to something that belongs to an {@link LSP}.
+ *
+ * After changes in fall 2023 (see master thesis of nrichter), the assingment is
+ * there to be done one time initially.
+ *
+ * If there are several {@link LogisticChain}s in a {@link LSPPlan}, the {@link LSP} has to assign each {@link
+ * LspShipment} to the suitable {@link LogisticChain}. For this purpose, each {@link LSPPlan}
+ * (or only the LSP? - kmt'jan'24), contains a pluggable strategy
+ * that is contained in classes implementing the interface {@link InitialShipmentAssigner}.
+ *
+ * During iterations, it can happen that the {@link LspShipment} should be moved to another
+ * {@link LogisticChain} of the same {@link LSPPlan}. This is now (since fall 2023; see master
+ * thesis of nrichter) part of the (innovative) **Replanning** strategies.
+ */
+public interface InitialShipmentAssigner {
+
+ void assignToPlan(LSPPlan lspPlan, LspShipment lspShipment);
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/logistics/KnowsLSP.java b/contribs/freight/src/main/java/org/matsim/freight/logistics/KnowsLSP.java
new file mode 100644
index 00000000000..60a9c8ea190
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/logistics/KnowsLSP.java
@@ -0,0 +1,7 @@
+package org.matsim.freight.logistics;
+
+interface KnowsLSP {
+ LSP getLSP();
+
+ void setLSP(LSP lsp);
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/logistics/LSP.java b/contribs/freight/src/main/java/org/matsim/freight/logistics/LSP.java
new file mode 100644
index 00000000000..0486cd0f958
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/logistics/LSP.java
@@ -0,0 +1,53 @@
+/*
+ * *********************************************************************** *
+ * * project: org.matsim.*
+ * * *********************************************************************** *
+ * * *
+ * * copyright : (C) 2022 by the members listed in the COPYING, *
+ * * LICENSE and WARRANTY file. *
+ * * email : info at matsim dot org *
+ * * *
+ * * *********************************************************************** *
+ * * *
+ * * This program is free software; you can redistribute it and/or modify *
+ * * it under the terms of the GNU General Public License as published by *
+ * * the Free Software Foundation; either version 2 of the License, or *
+ * * (at your option) any later version. *
+ * * See also COPYING, LICENSE and WARRANTY file *
+ * * *
+ * * ***********************************************************************
+ */
+
+package org.matsim.freight.logistics;
+
+import java.util.Collection;
+import org.matsim.api.core.v01.population.HasPlansAndId;
+import org.matsim.freight.logistics.shipment.LspShipment;
+
+/**
+ * In the class library, the interface LSP has the following tasks: 1. Maintain one or several
+ * transport chains through which {@link LspShipment}s are routed. 2. Assign {@link LspShipment}s to
+ * the suitable transport chain. --> {@link InitialShipmentAssigner}. 3. Interact with the agents that
+ * embody the demand side of the freight transport market, if they are specified in the setting. 4.
+ * Coordinate carriers that are in charge of the physical transport.
+ */
+public interface LSP extends HasPlansAndId, HasSimulationTrackers {
+
+ /** yyyy does this have to be exposed? */
+ Collection getLspShipments();
+
+ /** ok (behavioral method) */
+ void scheduleLogisticChains();
+
+ /** yyyy does this have to be exposed? */
+ Collection getResources();
+
+ /** ok (behavioral method) */
+ void scoreSelectedPlan();
+
+ /**
+ * @param lspShipment ok (LSP needs to be told that it is responsible for lspShipment)
+ */
+ void assignShipmentToLSP(LspShipment lspShipment);
+
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPCarrierResource.java b/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPCarrierResource.java
new file mode 100644
index 00000000000..1a26be79a61
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPCarrierResource.java
@@ -0,0 +1,28 @@
+/*
+ * *********************************************************************** *
+ * * project: org.matsim.*
+ * * *********************************************************************** *
+ * * *
+ * * copyright : (C) 2022 by the members listed in the COPYING, *
+ * * LICENSE and WARRANTY file. *
+ * * email : info at matsim dot org *
+ * * *
+ * * *********************************************************************** *
+ * * *
+ * * This program is free software; you can redistribute it and/or modify *
+ * * it under the terms of the GNU General Public License as published by *
+ * * the Free Software Foundation; either version 2 of the License, or *
+ * * (at your option) any later version. *
+ * * See also COPYING, LICENSE and WARRANTY file *
+ * * *
+ * * ***********************************************************************
+ */
+
+package org.matsim.freight.logistics;
+
+import org.matsim.freight.carriers.Carrier;
+
+public interface LSPCarrierResource extends LSPResource {
+
+ Carrier getCarrier();
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPConstants.java b/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPConstants.java
new file mode 100644
index 00000000000..44df1603232
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPConstants.java
@@ -0,0 +1,29 @@
+package org.matsim.freight.logistics;
+
+import org.matsim.freight.carriers.CarrierConstants;
+
+public abstract class LSPConstants extends CarrierConstants {
+
+ public static final String CAPACITY_NEED_FIXED = "capacityNeedFixed";
+ public static final String CAPACITY_NEED_LINEAR = "capacityNeedLinear";
+ public static final String CHAIN_ID = "chainId";
+ public static final String ELEMENT = "element";
+ public static final String END_TIME = "endTime";
+ public static final String FIXED_COST = "fixedCost";
+ public static final String HUB = "hub";
+ public static final String LOCATION = "location";
+ public static final String LOGISTIC_CHAIN = "logisticChain";
+ public static final String LOGISTIC_CHAINS = "logisticChains";
+ public static final String LOGISTIC_CHAIN_ELEMENT = "logisticChainElement";
+ public static final String LSP = "lsp";
+ public static final String LSPS = "lsps";
+ public static final String LSP_PLAN = "LspPlan";
+ public static final String LSP_PLANS = "LspPlans";
+ public static final String RESOURCES = "resources";
+ public static final String RESOURCE_ID = "resourceId";
+ public static final String SCHEDULER = "scheduler";
+ public static final String SHIPMENT_PLAN = "shipmentPlan";
+ public static final String SHIPMENT_PLANS = "shipmentPlans";
+ public static final String START_TIME = "startTime";
+ public static final String TYPE = "type";
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPControllerListener.java b/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPControllerListener.java
new file mode 100644
index 00000000000..0da2e144cbc
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPControllerListener.java
@@ -0,0 +1,253 @@
+/*
+ * *********************************************************************** *
+ * * project: org.matsim.*
+ * * *********************************************************************** *
+ * * *
+ * * copyright : (C) 2022 by the members listed in the COPYING, *
+ * * LICENSE and WARRANTY file. *
+ * * email : info at matsim dot org *
+ * * *
+ * * *********************************************************************** *
+ * * *
+ * * This program is free software; you can redistribute it and/or modify *
+ * * it under the terms of the GNU General Public License as published by *
+ * * the Free Software Foundation; either version 2 of the License, or *
+ * * (at your option) any later version. *
+ * * See also COPYING, LICENSE and WARRANTY file *
+ * * *
+ * * ***********************************************************************
+ */
+
+package org.matsim.freight.logistics;
+
+import jakarta.inject.Inject;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.Nullable;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.matsim.api.core.v01.Scenario;
+import org.matsim.core.api.experimental.events.EventsManager;
+import org.matsim.core.controler.MatsimServices;
+import org.matsim.core.controler.OutputDirectoryHierarchy;
+import org.matsim.core.controler.events.*;
+import org.matsim.core.controler.listener.*;
+import org.matsim.core.events.handler.EventHandler;
+import org.matsim.core.gbl.Gbl;
+import org.matsim.freight.carriers.Carrier;
+import org.matsim.freight.carriers.CarrierPlanWriter;
+import org.matsim.freight.carriers.Carriers;
+import org.matsim.freight.carriers.CarriersUtils;
+import org.matsim.freight.carriers.controller.CarrierAgentTracker;
+import org.matsim.freight.logistics.io.LSPPlanXmlWriter;
+import org.matsim.freight.logistics.shipment.LspShipment;
+
+class LSPControllerListener
+ implements StartupListener,
+ BeforeMobsimListener,
+ AfterMobsimListener,
+ ScoringListener,
+ ReplanningListener,
+ IterationStartsListener,
+ IterationEndsListener,
+ ShutdownListener {
+ private static final Logger log = LogManager.getLogger(LSPControllerListener.class);
+ private final Scenario scenario;
+ private final List registeredHandlers = new ArrayList<>();
+
+ private static int addListenerCnt = 0;
+ private static final int maxAddListenerCnt = 1;
+
+ @Inject private EventsManager eventsManager;
+ @Inject private MatsimServices matsimServices;
+ @Inject private LSPScorerFactory lspScoringFunctionFactory;
+ @Inject @Nullable private LSPStrategyManager strategyManager;
+ @Inject private OutputDirectoryHierarchy controlerIO;
+ @Inject private CarrierAgentTracker carrierAgentTracker;
+
+
+ @Inject
+ LSPControllerListener(Scenario scenario) {
+ this.scenario = scenario;
+ }
+
+ @Override
+ public void notifyStartup(StartupEvent event) {
+ //Ensure that all ressource Ids are only there once.
+
+ checkForUniqueResourceIds();
+
+ }
+
+/**
+* For later steps, e.g. scoring the Ids of the {@link LSPResource} ids must be unique.
+ * Otherwise, there are scored several times.
+ *
+ * For the future we may reduce it to unique {@link LSPResource} ids PER {@link LSP}.
+ * This means, that the events (also from the carriers) need to have an information obout the LSP it belongs to and that
+ * in scoring and analysis this must be taken into account. What itself is another source for errors...
+ * KMT jul'24
+*/
+ private void checkForUniqueResourceIds() {
+ List duplicates = new ArrayList<>();
+ Set set = new HashSet<>();
+
+ LSPs lsps = LSPUtils.getLSPs(scenario);
+ for (LSP lsp : lsps.getLSPs().values()) {
+ for (LSPResource lspResource : lsp.getResources()) {
+ String idString = lspResource.getId().toString();
+ if (set.contains(idString)) {
+ duplicates.add(idString);
+ } else {
+ set.add(idString);
+ }
+ }
+ }
+
+ if (!duplicates.isEmpty()) {
+ log.error("There are non-unique ressource Ids. This must not be! The duplicate ids are: {}.", duplicates.toString());
+ log.error("You may also use output_lsp.xml to check were the duplicates are located");
+ log.error("Aborting now ...");
+ throw new RuntimeException();
+ }
+ }
+
+ @Override
+ public void notifyBeforeMobsim(BeforeMobsimEvent event) {
+ LSPs lsps = LSPUtils.getLSPs(scenario);
+
+ // TODO: Why do we add all simTrackers in every iteration beforeMobsim starts?
+ // Doing so results in a lot of "not adding eventsHandler since already added" warnings.
+ // @KN: Would it be possible to do it in (simulation) startup and therefor only oce?
+ for (LSP lsp : lsps.getLSPs().values()) {
+ ((LSPImpl) lsp).setScorer(lspScoringFunctionFactory.createScoringFunction());
+
+ // simulation trackers of lsp:
+ registerSimulationTrackers(lsp);
+
+ // simulation trackers of resources:
+ for (LSPResource resource : lsp.getResources()) {
+ registerSimulationTrackers(resource);
+ }
+
+ // simulation trackers of shipments:
+ for (LspShipment lspShipment : lsp.getLspShipments()) {
+ registerSimulationTrackers(lspShipment);
+ }
+
+ // simulation trackers of solutions:
+ for (LogisticChain solution : lsp.getSelectedPlan().getLogisticChains()) {
+ registerSimulationTrackers(solution);
+
+ // simulation trackers of solution elements:
+ for (LogisticChainElement element : solution.getLogisticChainElements()) {
+ registerSimulationTrackers(element);
+
+ // simulation trackers of resources:
+ registerSimulationTrackers(element.getResource());
+ }
+ }
+ }
+ }
+
+ private void registerSimulationTrackers(HasSimulationTrackers> hasSimulationTrackers) {
+ // get all simulation trackers ...
+ for (LSPSimulationTracker> simulationTracker :
+ hasSimulationTrackers.getSimulationTrackers()) {
+ // ... register them ...
+ if (!registeredHandlers.contains(simulationTracker)) {
+ log.info("adding eventsHandler: {}", simulationTracker);
+ eventsManager.addHandler(simulationTracker);
+ registeredHandlers.add(simulationTracker);
+ matsimServices.addControlerListener(simulationTracker);
+ simulationTracker.setEventsManager(eventsManager);
+ } else if ( addListenerCnt < maxAddListenerCnt ){
+ log.warn("not adding eventsHandler since already added: {}", simulationTracker);
+ addListenerCnt++;
+ if (addListenerCnt == maxAddListenerCnt) {
+ log.warn(Gbl.FUTURE_SUPPRESSED);
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public void notifyReplanning(ReplanningEvent event) {
+ if (strategyManager == null) {
+ throw new RuntimeException(
+ "You need to set LSPStrategyManager to something meaningful to run iterations.");
+ }
+
+ LSPs lsps = LSPUtils.getLSPs(scenario);
+ strategyManager.run(
+ lsps.getLSPs().values(), event.getIteration(), event.getReplanningContext());
+
+ for (LSP lsp : lsps.getLSPs().values()) {
+ lsp.getSelectedPlan()
+ .getShipmentPlans()
+ .clear(); // clear ShipmentPlans to start with clear(n) state. Otherwise, some of the times were
+ // accumulating over the time. :(
+ lsp.scheduleLogisticChains();
+ }
+
+ // Update carriers in scenario and CarrierAgentTracker
+ carrierAgentTracker.getCarriers().getCarriers().clear();
+ for (Carrier carrier : getCarriersFromLSP().getCarriers().values()) {
+ CarriersUtils.getCarriers(scenario).addCarrier(carrier);
+ carrierAgentTracker.getCarriers().addCarrier(carrier);
+ }
+ }
+
+ @Override
+ public void notifyScoring(ScoringEvent scoringEvent) {
+ for (LSP lsp : LSPUtils.getLSPs(scenario).getLSPs().values()) {
+ lsp.scoreSelectedPlan();
+ }
+ // yyyyyy might make more sense to register the lsps directly as scoring controler listener (??)
+ }
+
+ @Override
+ public void notifyAfterMobsim(AfterMobsimEvent event) {}
+
+ Carriers getCarriersFromLSP() {
+ LSPs lsps = LSPUtils.getLSPs(scenario);
+ assert !lsps.getLSPs().isEmpty();
+
+ Carriers carriers = new Carriers();
+ for (LSP lsp : lsps.getLSPs().values()) {
+ LSPPlan selectedPlan = lsp.getSelectedPlan();
+ for (LogisticChain solution : selectedPlan.getLogisticChains()) {
+ for (LogisticChainElement element : solution.getLogisticChainElements()) {
+ if (element.getResource() instanceof LSPCarrierResource carrierResource) {
+ Carrier carrier = carrierResource.getCarrier();
+ if (!carriers.getCarriers().containsKey(carrier.getId())) {
+ carriers.addCarrier(carrier);
+ }
+ }
+ }
+ }
+ }
+ return carriers;
+ }
+
+ @Override
+ public void notifyIterationStarts(IterationStartsEvent event) {}
+
+ @Override
+ public void notifyIterationEnds(IterationEndsEvent event) {
+ new LSPPlanXmlWriter(LSPUtils.getLSPs(scenario))
+ .write(controlerIO.getIterationFilename(event.getIteration(), "lsps.xml"));
+ }
+
+ @Override
+ public void notifyShutdown(ShutdownEvent event) {
+ new LSPPlanXmlWriter(LSPUtils.getLSPs(scenario))
+ .write(controlerIO.getOutputPath() + "/output_lsps.xml.gz");
+ new CarrierPlanWriter(CarriersUtils.getCarriers(scenario))
+ .write(controlerIO.getOutputPath() + "/output_carriers.xml.gz");
+ }
+
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPDataObject.java b/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPDataObject.java
new file mode 100644
index 00000000000..ff150a79d88
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPDataObject.java
@@ -0,0 +1,45 @@
+package org.matsim.freight.logistics;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.Identifiable;
+import org.matsim.utils.objectattributes.attributable.Attributable;
+import org.matsim.utils.objectattributes.attributable.Attributes;
+import org.matsim.utils.objectattributes.attributable.AttributesImpl;
+
+public class LSPDataObject implements HasSimulationTrackers, Attributable, Identifiable {
+
+ private final Collection> trackers = new LinkedList<>();
+ private final Attributes attributes = new AttributesImpl();
+ private final Id id;
+
+ public LSPDataObject(Id id) {
+ this.id = id;
+ }
+
+ @Override
+ public final void addSimulationTracker(LSPSimulationTracker tracker) {
+ this.trackers.add(tracker);
+ tracker.setEmbeddingContainer((T) this);
+ // It may not be possible to do this without this cast. Since "this" only knows that it is at
+ // least an LSPDataObject, and only we
+ // know that it is truly of type T. kai, jun'22
+ }
+
+ @Override
+ public final Collection> getSimulationTrackers() {
+ return Collections.unmodifiableCollection(this.trackers);
+ }
+
+ @Override
+ public final Attributes getAttributes() {
+ return attributes;
+ }
+
+ @Override
+ public final Id getId() {
+ return id;
+ }
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPImpl.java b/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPImpl.java
new file mode 100644
index 00000000000..d25cbfb043a
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/logistics/LSPImpl.java
@@ -0,0 +1,163 @@
+/*
+ * *********************************************************************** *
+ * * project: org.matsim.*
+ * * *********************************************************************** *
+ * * *
+ * * copyright : (C) 2022 by the members listed in the COPYING, *
+ * * LICENSE and WARRANTY file. *
+ * * email : info at matsim dot org *
+ * * *
+ * * *********************************************************************** *
+ * * *
+ * * This program is free software; you can redistribute it and/or modify *
+ * * it under the terms of the GNU General Public License as published by *
+ * * the Free Software Foundation; either version 2 of the License, or *
+ * * (at your option) any later version. *
+ * * See also COPYING, LICENSE and WARRANTY file *
+ * * *
+ * * ***********************************************************************
+ */
+
+package org.matsim.freight.logistics;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.matsim.freight.logistics.shipment.LspShipment;
+
+/* package-private */ class LSPImpl extends LSPDataObject implements LSP {
+ private static final Logger log = LogManager.getLogger(LSPImpl.class);
+
+ private final Collection lspShipments;
+ private final ArrayList