Skip to content

Commit 73477b0

Browse files
authored
Merge pull request #136 from moia-oss/master
Update MATSim CW 10
2 parents 6085443 + a43b3cb commit 73477b0

File tree

185 files changed

+5783
-20847
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

185 files changed

+5783
-20847
lines changed

contribs/application/src/main/java/org/matsim/application/analysis/traffic/traveltime/SampleValidationRoutes.java

+43-16
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,20 @@ public class SampleValidationRoutes implements MATSimAppCommand {
8888
@CommandLine.Option(names = "--input-od", description = "Use input fromNode,toNode instead of sampling", required = false)
8989
private String inputOD;
9090

91+
@CommandLine.Option(names = "--offline", description = "Only write the aggregated result without fetching any new data.")
92+
private boolean offline;
93+
9194
public static void main(String[] args) {
9295
new SampleValidationRoutes().execute(args);
9396
}
9497

9598
/**
9699
* Read the produced API files and collect the speeds by hour.
97100
*/
98-
public static Map<FromToNodes, Int2ObjectMap<DoubleList>> readValidation(List<String> validationFiles) throws IOException {
101+
public static Map<FromToNodes, Int2ObjectMap<Data>> readValidation(List<String> validationFiles) throws IOException {
99102

100103
// entry to hour and list of speeds
101-
Map<FromToNodes, Int2ObjectMap<DoubleList>> entries = new LinkedHashMap<>();
104+
Map<FromToNodes, Int2ObjectMap<Data>> entries = new LinkedHashMap<>();
102105

103106
for (String file : validationFiles) {
104107

@@ -109,15 +112,21 @@ public static Map<FromToNodes, Int2ObjectMap<DoubleList>> readValidation(List<St
109112

110113
for (CSVRecord r : parser) {
111114
FromToNodes e = new FromToNodes(Id.createNodeId(r.get("from_node")), Id.createNodeId(r.get("to_node")));
112-
double speed = Double.parseDouble(r.get("dist")) / Double.parseDouble(r.get("travel_time"));
115+
double travelTime = Double.parseDouble(r.get("travel_time"));
116+
double dist = Double.parseDouble(r.get("dist"));
117+
double speed = dist / travelTime;
113118

114119
if (!Double.isFinite(speed)) {
115120
log.warn("Invalid entry {}", r);
116121
continue;
117122
}
118123

119-
Int2ObjectMap<DoubleList> perHour = entries.computeIfAbsent(e, (k) -> new Int2ObjectLinkedOpenHashMap<>());
120-
perHour.computeIfAbsent(Integer.parseInt(r.get("hour")), k -> new DoubleArrayList()).add(speed);
124+
Int2ObjectMap<Data> perHour = entries.computeIfAbsent(e, (k) -> new Int2ObjectLinkedOpenHashMap<>());
125+
Data d = perHour.computeIfAbsent(Integer.parseInt(r.get("hour")), k -> new Data());
126+
127+
d.speeds.add(speed);
128+
d.travelTimes.add(travelTime);
129+
d.dists.add(dist);
121130
}
122131
}
123132
}
@@ -174,9 +183,10 @@ public Integer call() throws Exception {
174183
for (Map.Entry<RouteAPI, String> e : apis.entrySet()) {
175184

176185
Path out = Path.of(output.getPath().toString().replace(".csv", "-api-" + e.getKey() + ".csv"));
177-
futures.add(
178-
CompletableFuture.runAsync(new FetchRoutesTask(e.getKey(), e.getValue(), routes, hours, out), executor)
179-
);
186+
if (!offline)
187+
futures.add(
188+
CompletableFuture.runAsync(new FetchRoutesTask(e.getKey(), e.getValue(), routes, hours, out), executor)
189+
);
180190

181191
files.add(out.toString());
182192
}
@@ -185,31 +195,38 @@ public Integer call() throws Exception {
185195
all.join();
186196
executor.shutdown();
187197

188-
Map<FromToNodes, Int2ObjectMap<DoubleList>> res = readValidation(files);
198+
Map<FromToNodes, Int2ObjectMap<Data>> res = readValidation(files);
189199

190200
Path ref = Path.of(output.getPath().toString().replace(".csv", "-ref.csv"));
191201

192202
// Write the reference file
193203
try (CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(ref), CSVFormat.DEFAULT)) {
194-
printer.printRecord("from_node", "to_node", "hour", "min", "max", "mean", "std");
204+
printer.printRecord("from_node", "to_node", "hour", "min", "max", "mean", "std",
205+
"min_tt", "max_tt", "mean_tt", "mean_dist");
195206

196207
// Target values
197-
for (Map.Entry<FromToNodes, Int2ObjectMap<DoubleList>> e : res.entrySet()) {
208+
for (Map.Entry<FromToNodes, Int2ObjectMap<Data>> e : res.entrySet()) {
198209

199-
Int2ObjectMap<DoubleList> perHour = e.getValue();
200-
for (Int2ObjectMap.Entry<DoubleList> e2 : perHour.int2ObjectEntrySet()) {
210+
Int2ObjectMap<Data> perHour = e.getValue();
211+
for (Int2ObjectMap.Entry<Data> e2 : perHour.int2ObjectEntrySet()) {
201212

202213
SummaryStatistics stats = new SummaryStatistics();
214+
SummaryStatistics ttStats = new SummaryStatistics();
215+
SummaryStatistics distStats = new SummaryStatistics();
216+
203217
// This is as kmh
204-
e2.getValue().forEach(v -> stats.addValue(v * 3.6));
218+
e2.getValue().speeds.forEach(v -> stats.addValue(v * 3.6));
219+
e2.getValue().travelTimes.forEach(ttStats::addValue);
220+
e2.getValue().dists.forEach(distStats::addValue);
205221

206222
printer.printRecord(e.getKey().fromNode, e.getKey().toNode, e2.getIntKey(),
207-
stats.getMin(), stats.getMax(), stats.getMean(), stats.getStandardDeviation());
223+
stats.getMin(), stats.getMax(), stats.getMean(), stats.getStandardDeviation(),
224+
ttStats.getMin(), ttStats.getMax(), ttStats.getMean(), distStats.getMean());
208225
}
209226
}
210227
}
211228

212-
log.info("All done.");
229+
log.info("Written reference file to {}", ref);
213230

214231
return 0;
215232
}
@@ -349,6 +366,16 @@ private List<Route> queryRoutes(Network network, LeastCostPathCalculator router)
349366
public record FromToNodes(Id<Node> fromNode, Id<Node> toNode) {
350367
}
351368

369+
/**
370+
* Results obtained from multiple APIs.
371+
*/
372+
public record Data(DoubleList speeds, DoubleList travelTimes, DoubleList dists) {
373+
374+
public Data() {
375+
this(new DoubleArrayList(), new DoubleArrayList(), new DoubleArrayList());
376+
}
377+
}
378+
352379
record Route(Id<Node> fromNode, Id<Node> toNode, Coord from, Coord to, double travelTime, double dist) {
353380
}
354381

contribs/application/src/main/java/org/matsim/application/analysis/traffic/traveltime/TravelTimeComparison.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ public Integer call() throws Exception {
8989

9090
data.addColumns(
9191
DoubleColumn.create("simulated", data.rowCount()),
92-
DoubleColumn.create("free_flow", data.rowCount())
92+
DoubleColumn.create("simulated_tt", data.rowCount()),
93+
DoubleColumn.create("free_flow", data.rowCount()),
94+
DoubleColumn.create("free_flow_tt", data.rowCount())
9395
);
9496

9597
for (Row row : data) {
@@ -105,12 +107,14 @@ public Integer call() throws Exception {
105107
double speed = 3.6 * dist / congested.travelTime;
106108

107109
row.setDouble("simulated", speed);
110+
row.setDouble("simulated_tt", congested.travelTime);
108111

109112
LeastCostPathCalculator.Path freeflow = computePath(network, freeflowRouter, row);
110113
dist = freeflow.links.stream().mapToDouble(Link::getLength).sum();
111114
speed = 3.6 * dist / freeflow.travelTime;
112115

113116
row.setDouble("free_flow", speed);
117+
row.setDouble("free_flow_tt", freeflow.travelTime);
114118
}
115119

116120
data = data.dropWhere(data.doubleColumn("simulated").isMissing());

contribs/application/src/main/java/org/matsim/application/prepare/freight/tripExtraction/ExtractRelevantFreightTrips.java

+28-18
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.matsim.core.trafficmonitoring.FreeSpeedTravelTime;
2727
import org.matsim.core.utils.geometry.CoordinateTransformation;
2828
import org.matsim.core.utils.geometry.geotools.MGC;
29+
import org.matsim.utils.objectattributes.attributable.Attributes;
2930
import picocli.CommandLine;
3031

3132
import java.io.FileWriter;
@@ -40,6 +41,7 @@ public class ExtractRelevantFreightTrips implements MATSimAppCommand {
4041
// This script will extract the relevant freight trips within the given shape
4142
// file from the German wide freight traffic.
4243
private static final Logger log = LogManager.getLogger(ExtractRelevantFreightTrips.class);
44+
public static final String GEOGRAPHICAL_TRIP_TYPE = "geographical_Trip_Type";
4345

4446
/**
4547
* Enum for the type of trips to be extracted. The following types are available:
@@ -74,9 +76,12 @@ private enum TripType {
7476
@CommandLine.Option(names = "--tripType", description = "Set the tripType: OUTGOING, INCOMING, TRANSIT, INTERNAL, ALL", defaultValue = "ALL")
7577
private TripType tripType;
7678

77-
@CommandLine.Option(names = "--LegMode", description = "Set leg mode for long distance freight legs.", defaultValue = "freight")
79+
@CommandLine.Option(names = "--legMode", description = "Set leg mode for long distance freight legs.", defaultValue = "freight")
7880
private String legMode;
7981

82+
@CommandLine.Option(names = "--subpopulation", description = "Set subpopulation for the extracted freight trips", defaultValue = "freight")
83+
private String subpopulation;
84+
8085
private final SplittableRandom rnd = new SplittableRandom(4711);
8186

8287
private final List<Coord> fromCoords = new ArrayList<>();
@@ -139,17 +144,17 @@ public Integer call() throws Exception {
139144
int generated = 0;
140145
int processed = 0;
141146
log.info("Start creating the modified plans: there are in total {} persons to be processed",
142-
originalPlans.getPersons().keySet().size());
147+
originalPlans.getPersons().size());
143148

144149
for (Person person : originalPlans.getPersons().values()) {
145150

146151
processed += 1;
147152
if (processed % 10000 == 0) {
148-
log.info("Processing: {} persons of {} persons have been processed", processed, originalPlans.getPersons().keySet().size());
153+
log.info("Processing: {} persons of {} persons have been processed", processed, originalPlans.getPersons().size());
149154
}
150155

151156
Plan plan = person.getSelectedPlan();
152-
// String goodType = (String) person.getAttributes().getAttribute("type_of_good"); // TODO keep all the attribute from original population
157+
Attributes attributes = person.getAttributes();
153158
// By default, the plan of each freight person consist of only 3 elements:
154159
// startAct, leg, endAct
155160
Activity startActivity = (Activity) plan.getPlanElements().get(0);
@@ -169,33 +174,35 @@ public Integer call() throws Exception {
169174

170175
switch (tripType) {
171176
case ALL -> {
172-
createActivitiesForInternalTrips(originIsInside, destinationIsInside, act0, ct, startCoord, departureTime, act1, endCoord);
177+
createActivitiesForInternalTrips(originIsInside, destinationIsInside, act0, ct, startCoord, departureTime, act1, endCoord, attributes);
173178
createActivitiesForOutgoingTrip(originIsInside, destinationIsInside, act0, ct, startCoord, departureTime, router, network,
174179
startLink, endLink,
175-
linksOnTheBoundary, act1, endCoord);
180+
linksOnTheBoundary, act1, endCoord, attributes);
176181
createActivitiesForIncomingTrips(originIsInside, destinationIsInside, act0, ct, startCoord, departureTime, router, network,
177-
startLink, endLink, linksOnTheBoundary, act1, endCoord);
182+
startLink, endLink, linksOnTheBoundary, act1, endCoord, attributes);
178183
createActivitiesForTransitTrip(originIsInside, destinationIsInside, act0, ct, startCoord, departureTime, router, network,
179-
startLink, endLink, linksOnTheBoundary, act1, endCoord);
184+
startLink, endLink, linksOnTheBoundary, act1, endCoord, attributes);
180185
}
181186
case INTERNAL ->
182-
createActivitiesForInternalTrips(originIsInside, destinationIsInside, act0, ct, startCoord, departureTime, act1, endCoord);
187+
createActivitiesForInternalTrips(originIsInside, destinationIsInside, act0, ct, startCoord, departureTime, act1, endCoord,
188+
attributes);
183189
case OUTGOING ->
184190
createActivitiesForOutgoingTrip(originIsInside, destinationIsInside, act0, ct, startCoord, departureTime, router, network,
185-
startLink, endLink, linksOnTheBoundary, act1, endCoord);
191+
startLink, endLink, linksOnTheBoundary, act1, endCoord, attributes);
186192
case INCOMING ->
187193
createActivitiesForIncomingTrips(originIsInside, destinationIsInside, act0, ct, startCoord, departureTime, router, network,
188-
startLink, endLink, linksOnTheBoundary, act1, endCoord);
194+
startLink, endLink, linksOnTheBoundary, act1, endCoord, attributes);
189195
case TRANSIT ->
190196
createActivitiesForTransitTrip(originIsInside, destinationIsInside, act0, ct, startCoord, departureTime, router, network,
191-
startLink, endLink, linksOnTheBoundary, act1, endCoord);
197+
startLink, endLink, linksOnTheBoundary, act1, endCoord, attributes);
192198
default -> throw new IllegalStateException("Unexpected value: " + tripType);
193199
}
194200

195201
// Add new freight person to the output plans if trips is relevant
196202
if (act0.getEndTime().orElse(86400) < 86400) {
197203
Person freightPerson = populationFactory.createPerson(Id.create("freight_" + generated, Person.class));
198-
freightPerson.getAttributes().putAttribute("subpopulation", "freight");
204+
attributes.getAsMap().forEach(freightPerson.getAttributes()::putAttribute);
205+
freightPerson.getAttributes().putAttribute("subpopulation", subpopulation);
199206
Plan freightPersonPlan = populationFactory.createPlan();
200207
freightPersonPlan.addActivity(act0);
201208
freightPersonPlan.addLeg(leg);
@@ -246,7 +253,7 @@ public Integer call() throws Exception {
246253
*/
247254
private void createActivitiesForTransitTrip(boolean originIsInside, boolean destinationIsInside, Activity act0, CoordinateTransformation ct, Coord startCoord,
248255
double departureTime, LeastCostPathCalculator router, Network network, Id<Link> startLink, Id<Link> endLink,
249-
List<Id<Link>> linksOnTheBoundary, Activity act1, Coord endCoord) {
256+
List<Id<Link>> linksOnTheBoundary, Activity act1, Coord endCoord, Attributes attributes) {
250257
if (!originIsInside && !destinationIsInside) {
251258
double timeSpent = 0;
252259
boolean vehicleIsInside = false;
@@ -283,6 +290,7 @@ private void createActivitiesForTransitTrip(boolean originIsInside, boolean dest
283290
}
284291
}
285292
}
293+
attributes.putAttribute(GEOGRAPHICAL_TRIP_TYPE, "transit");
286294
}
287295
}
288296

@@ -291,7 +299,7 @@ private void createActivitiesForTransitTrip(boolean originIsInside, boolean dest
291299
*/
292300
private void createActivitiesForIncomingTrips(boolean originIsInside, boolean destinationIsInside, Activity act0, CoordinateTransformation ct, Coord startCoord,
293301
double departureTime, LeastCostPathCalculator router, Network network, Id<Link> startLink, Id<Link> endLink,
294-
List<Id<Link>> linksOnTheBoundary, Activity act1, Coord endCoord) {
302+
List<Id<Link>> linksOnTheBoundary, Activity act1, Coord endCoord, Attributes attributes) {
295303
if (!originIsInside && destinationIsInside) {
296304
if (cutOnBoundary) {
297305
boolean isCoordSet = false;
@@ -324,6 +332,7 @@ private void createActivitiesForIncomingTrips(boolean originIsInside, boolean de
324332
act0.setEndTime(departureTime);
325333
}
326334
act1.setCoord(ct.transform(endCoord));
335+
attributes.putAttribute(GEOGRAPHICAL_TRIP_TYPE, "incoming");
327336
}
328337
}
329338

@@ -332,7 +341,7 @@ private void createActivitiesForIncomingTrips(boolean originIsInside, boolean de
332341
*/
333342
private void createActivitiesForOutgoingTrip(boolean originIsInside, boolean destinationIsInside, Activity act0, CoordinateTransformation ct, Coord startCoord,
334343
double departureTime, LeastCostPathCalculator router, Network network, Id<Link> startLink, Id<Link> endLink,
335-
List<Id<Link>> linksOnTheBoundary, Activity act1, Coord endCoord) {
344+
List<Id<Link>> linksOnTheBoundary, Activity act1, Coord endCoord, Attributes attributes) {
336345
if (originIsInside && !destinationIsInside) {
337346
act0.setCoord(ct.transform(startCoord));
338347
act0.setEndTime(departureTime);
@@ -359,19 +368,20 @@ private void createActivitiesForOutgoingTrip(boolean originIsInside, boolean des
359368
} else {
360369
act1.setCoord(ct.transform(endCoord));
361370
}
362-
371+
attributes.putAttribute(GEOGRAPHICAL_TRIP_TYPE, "outgoing");
363372
}
364373
}
365374

366375
/**
367376
* Create activities if the trip is an internal trip
368377
*/
369378
private static void createActivitiesForInternalTrips(boolean originIsInside, boolean destinationIsInside, Activity act0, CoordinateTransformation ct, Coord startCoord,
370-
double departureTime, Activity act1, Coord endCoord) {
379+
double departureTime, Activity act1, Coord endCoord, Attributes attributes) {
371380
if (originIsInside && destinationIsInside) {
372381
act0.setCoord(ct.transform(startCoord));
373382
act0.setEndTime(departureTime);
374383
act1.setCoord(ct.transform(endCoord));
384+
attributes.putAttribute(GEOGRAPHICAL_TRIP_TYPE, "internal");
375385
}
376386
}
377387
}

contribs/application/src/main/java/org/matsim/application/prepare/network/params/NetworkParamsOpt.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,16 @@ private static Feature createDefaultFeature(Link link) {
141141
static Object2DoubleMap<SampleValidationRoutes.FromToNodes> readValidation(List<String> validationFiles, List<Integer> refHours) throws IOException {
142142

143143
// entry to hour and list of speeds
144-
Map<SampleValidationRoutes.FromToNodes, Int2ObjectMap<DoubleList>> entries = SampleValidationRoutes.readValidation(validationFiles);
144+
Map<SampleValidationRoutes.FromToNodes, Int2ObjectMap<SampleValidationRoutes.Data>> entries = SampleValidationRoutes.readValidation(validationFiles);
145145

146146
Object2DoubleMap<SampleValidationRoutes.FromToNodes> result = new Object2DoubleOpenHashMap<>();
147147

148148
// Target values
149-
for (Map.Entry<SampleValidationRoutes.FromToNodes, Int2ObjectMap<DoubleList>> e : entries.entrySet()) {
149+
for (Map.Entry<SampleValidationRoutes.FromToNodes, Int2ObjectMap<SampleValidationRoutes.Data>> e : entries.entrySet()) {
150150

151-
Int2ObjectMap<DoubleList> perHour = e.getValue();
151+
Int2ObjectMap<SampleValidationRoutes.Data> perHour = e.getValue();
152152

153-
double avg = refHours.stream().map(h -> perHour.get((int) h).doubleStream())
153+
double avg = refHours.stream().map(h -> perHour.get((int) h).speeds().doubleStream())
154154
.flatMapToDouble(Function.identity()).average().orElseThrow();
155155

156156

0 commit comments

Comments
 (0)