diff --git a/contribs/application/pom.xml b/contribs/application/pom.xml index 83422007fee..e8ec00d4800 100644 --- a/contribs/application/pom.xml +++ b/contribs/application/pom.xml @@ -87,7 +87,7 @@ com.github.matsim-org gtfs2matsim - 0bd5850fd6 + 47b0802a29 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 a3f321c7f38..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 @@ -66,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; @@ -86,19 +86,20 @@ public Integer call() throws Exception { boolean overrideParameters = ! ConfigUtils.hasModule(config, NoiseConfigGroup.class); NoiseConfigGroup noiseParameters = ConfigUtils.addOrGetModule(config, NoiseConfigGroup.class); - if(overrideParameters){ + 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(considerActivities.toArray(String[]::new)); - noiseParameters.setConsideredActivitiesForDamageCalculationArray(considerActivities.toArray(String[]::new)); + noiseParameters.setConsideredActivitiesForReceiverPointGridArray(consideredActivities.toArray(String[]::new)); + noiseParameters.setConsideredActivitiesForDamageCalculationArray(consideredActivities.toArray(String[]::new)); { - Set set = CollectionUtils.stringArrayToSet( new String[]{TransportMode.bike, TransportMode.walk, TransportMode.transit_walk, TransportMode.non_network_walk} ); - noiseParameters.setNetworkModesToIgnoreSet( set ); - } - { - String[] set = new String[]{"freight"}; - noiseParameters.setHgvIdPrefixesArray( set ); + //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); //use the valid speed range (recommended by IK) 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 893c05cf9fd..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; @@ -27,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; @@ -37,6 +35,7 @@ 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; @@ -46,8 +45,9 @@ 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_shift.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" } @@ -283,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)) { @@ -305,17 +310,24 @@ public Integer call() throws Exception { writePopulationStats(persons, joined); - writeTripStats(joined); - - writeTripPurposes(joined); - - writeTripDistribution(joined); - - writeModeShift(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"); @@ -502,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"); @@ -610,6 +617,89 @@ private void writeModeShift(Table trips) throws IOException { 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. */ @@ -619,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/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..120f9711ba6 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 @@ -257,7 +257,10 @@ private boolean applyFreeSpeed(Link link, Feature ft) { 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/scenario/CreateScenarioCutOut.java b/contribs/application/src/main/java/org/matsim/application/prepare/scenario/CreateScenarioCutOut.java index 6559a9c5c97..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; @@ -453,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; } /** @@ -501,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 @@ -564,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..ac3c44cb5a6 100644 --- a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java +++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java @@ -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/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/square/SquareGridZoneSystem.java b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/square/SquareGridZoneSystem.java index b1319fed1a9..f47ed5669c9 100644 --- a/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/square/SquareGridZoneSystem.java +++ b/contribs/common/src/main/java/org/matsim/contrib/common/zones/systems/grid/square/SquareGridZoneSystem.java @@ -36,6 +36,7 @@ import java.util.*; import java.util.function.Predicate; +import java.util.stream.Collectors; public class SquareGridZoneSystem implements GridZoneSystem { @@ -55,6 +56,7 @@ public class SquareGridZoneSystem implements GridZoneSystem { private final IdMap zones = new IdMap<>(Zone.class); private final IdMap> zoneToLinksMap = new IdMap<>(Zone.class); + private final Map> index2Links; private final Network network; @@ -76,6 +78,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())); @@ -126,12 +129,11 @@ 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); - } + List linkList = zoneToLinksMap.computeIfAbsent(zone.getId(), zoneId -> new ArrayList<>()); + List links = index2Links.get(index); + if(links!=null) + { + linkList.addAll(links); } } else { return Optional.empty(); @@ -140,6 +142,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.contrib otfvis - ${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; i { 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/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/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/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/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 chargerSpecifications; + private Map, AttributeConverter> attributeConverters = new HashMap<>(); + private final AttributesXmlWriterDelegate attributesWriter = new AttributesXmlWriterDelegate(); + public ChargerWriter(Stream 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/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeReaderV1.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierVehicleTypeReaderV1.java index 61718d49850..92e2bacc590 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 @@ -24,6 +24,7 @@ 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; @@ -54,6 +55,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"); 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 index 751e96a2f45..7269a70ac7f 100644 --- 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 @@ -38,6 +38,7 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Path; //import static org.matsim.application.ApplicationUtils.globFile; @@ -80,13 +81,15 @@ public RunFreightAnalysisEventBased(String simOutputPath, String analysisOutputP // Path carriersPath = globFile(simOutputPath, "*output_carriers.*"); // Path carriersVehicleTypesPath = globFile(simOutputPath, "*output_carriersVehicleTypes.*"); -// this.EVENTS_PATH = simOutputPath.resolve("*output_events.xml.gz"); -// Path vehiclesPath = simOutputPath.resolve("*output_allVehicles.xml.gz"); -// Path networkPath = simOutputPath.resolve("*output_network.xml.gz"); -// Path carriersPath = simOutputPath.resolve("*output_carriers.xml.gz"); -// Path carriersVehicleTypesPath = simOutputPath.resolve("*output_carriersVehicleTypes.xml.gz"); -// -// createScenarioForFreightAnalysis(vehiclesPath, networkPath, carriersPath, carriersVehicleTypesPath, globalCrs); + // 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); } /** diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/CarrierVehicleTypeTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/CarrierVehicleTypeTest.java index 24328872de2..a95fac8d1ec 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/CarrierVehicleTypeTest.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/CarrierVehicleTypeTest.java @@ -26,6 +26,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.TransportMode; import org.matsim.freight.carriers.CarrierVehicleTypes; import org.matsim.testcases.MatsimTestUtils; import org.matsim.vehicles.*; @@ -53,6 +54,7 @@ public void setUp() { VehicleCapacity vehicleCapacity = mediumType.getCapacity(); vehicleCapacity.setWeightInTons( 30 ); mediumType.setDescription( "Medium Vehicle" ).setMaximumVelocity( 13.89 ); + mediumType.setNetworkMode(TransportMode.truck); types = new CarrierVehicleTypes(); types.getVehicleTypes().put( mediumType.getId(), mediumType ); } @@ -77,6 +79,7 @@ public void setUp() { capacity.setWeightInTons( 16 ) ; // VehicleType smallType = CarriersUtils.CarrierVehicleTypeBuilder.newInstance( smallTypeId, mediumType ) smallType.setDescription( "Small Vehicle" ).setMaximumVelocity( 10.0 ) ; + smallType.setNetworkMode(TransportMode.car); types.getVehicleTypes().put( smallType.getId(), smallType); } } diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/Order.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/Order.java similarity index 99% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/Order.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/Order.java index 6060e7ba4ee..d2cd76201eb 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/Order.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/Order.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ProductType.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ProductType.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ProductType.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ProductType.java index 4589cd7b3b9..6c7b6f84f97 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ProductType.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ProductType.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Identifiable; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/Receiver.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/Receiver.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/Receiver.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/Receiver.java index 631130ba87a..3faee4fc53b 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/Receiver.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/Receiver.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverAgent.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverAgent.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverAgent.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverAgent.java index df29bc43a71..df4c6d6f948 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverAgent.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverAgent.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverConfigGroup.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverConfigGroup.java similarity index 99% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverConfigGroup.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverConfigGroup.java index dfbc6cbe4a5..e42150f9b8f 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverConfigGroup.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverConfigGroup.java @@ -15,7 +15,7 @@ * See also COPYING, LICENSE and WARRANTY file * * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverControlerListener.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverControlerListener.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverControlerListener.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverControlerListener.java index 10fe1be6bdd..852452663a6 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverControlerListener.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverControlerListener.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import com.google.inject.Inject; import org.apache.logging.log4j.LogManager; @@ -29,8 +29,8 @@ import org.matsim.freight.carriers.CarriersUtils; import org.matsim.freight.carriers.ScheduledTour; import org.matsim.freight.carriers.Tour; -import org.matsim.contrib.freightreceiver.collaboration.CollaborationUtils; -import org.matsim.contrib.freightreceiver.replanning.ReceiverStrategyManager; +import org.matsim.freight.receiver.collaboration.CollaborationUtils; +import org.matsim.freight.receiver.replanning.ReceiverStrategyManager; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.events.*; import org.matsim.core.controler.listener.*; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocation.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverCostAllocation.java similarity index 96% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocation.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverCostAllocation.java index 72ccdeb68fa..c01f7425f9b 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocation.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverCostAllocation.java @@ -18,7 +18,7 @@ * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.matsim.freight.carriers.Carrier; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocationEqualProportion.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverCostAllocationEqualProportion.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocationEqualProportion.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverCostAllocationEqualProportion.java index 6f85efcd2f1..ae79d2db6c5 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocationEqualProportion.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverCostAllocationEqualProportion.java @@ -18,7 +18,7 @@ * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import com.google.inject.Inject; import org.matsim.api.core.v01.Id; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocationFixed.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverCostAllocationFixed.java similarity index 97% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocationFixed.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverCostAllocationFixed.java index 5f3a6a2dea2..fed9d76f609 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocationFixed.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverCostAllocationFixed.java @@ -17,7 +17,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.apache.logging.log4j.LogManager; import org.matsim.freight.carriers.Carrier; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocationType.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverCostAllocationType.java similarity index 96% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocationType.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverCostAllocationType.java index 9ad1862b9c9..c4b110f8266 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocationType.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverCostAllocationType.java @@ -18,7 +18,7 @@ * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; /** * The supported ways in which the carrier's cost is spread among the receivers. diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverImpl.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverImpl.java similarity index 99% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverImpl.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverImpl.java index 1f29889a0a6..59b70767176 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverImpl.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverImpl.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverModule.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverModule.java similarity index 96% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverModule.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverModule.java index aac11b5e7b2..a108dbf87f4 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverModule.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverModule.java @@ -16,14 +16,15 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; import org.matsim.freight.carriers.Carrier; -import org.matsim.contrib.freightreceiver.replanning.*; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.AbstractModule; +import org.matsim.freight.receiver.replanning.ReceiverReplanningUtils; +import org.matsim.freight.receiver.replanning.ReceiverStrategyManager; public final class ReceiverModule extends AbstractModule { final private static Logger LOG = LogManager.getLogger(ReceiverModule.class); diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverOrder.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverOrder.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverOrder.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverOrder.java index 081004dcb71..cad5c103842 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverOrder.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverOrder.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverPlan.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverPlan.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverPlan.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverPlan.java index 0497d364b3d..88a8fe76268 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverPlan.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverPlan.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -25,7 +25,7 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.TimeWindow; -import org.matsim.contrib.freightreceiver.collaboration.CollaborationUtils; +import org.matsim.freight.receiver.collaboration.CollaborationUtils; import org.matsim.utils.objectattributes.attributable.Attributable; import org.matsim.utils.objectattributes.attributable.Attributes; import org.matsim.utils.objectattributes.attributable.AttributesImpl; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverProduct.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverProduct.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverProduct.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverProduct.java index 40489f44c23..5e734d77247 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverProduct.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverProduct.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; /** * Returns a new instance of a receiver product with associated information, diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverReplanningType.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverReplanningType.java similarity index 96% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverReplanningType.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverReplanningType.java index d8bd5df43dc..f1845f3d2cb 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverReplanningType.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverReplanningType.java @@ -15,7 +15,7 @@ * See also COPYING, LICENSE and WARRANTY file * * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; public enum ReceiverReplanningType { serviceTime, timeWindow, orderFrequency, afterHoursTimeWindow diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverScoreStats.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverScoreStats.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverScoreStats.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverScoreStats.java index a9a63491a07..a6b260fc449 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverScoreStats.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverScoreStats.java @@ -1,11 +1,11 @@ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import com.google.inject.Inject; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Scenario; import org.matsim.freight.carriers.CarriersUtils; -import org.matsim.contrib.freightreceiver.collaboration.CollaborationUtils; +import org.matsim.freight.receiver.collaboration.CollaborationUtils; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.events.IterationEndsEvent; import org.matsim.core.controler.events.ShutdownEvent; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverScoringFunctionFactory.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverScoringFunctionFactory.java similarity index 97% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverScoringFunctionFactory.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverScoringFunctionFactory.java index 81e60676e02..ade37d5354e 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverScoringFunctionFactory.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverScoringFunctionFactory.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.matsim.core.scoring.ScoringFunction; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverScoringFunctionFactoryMoneyOnly.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverScoringFunctionFactoryMoneyOnly.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverScoringFunctionFactoryMoneyOnly.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverScoringFunctionFactoryMoneyOnly.java index 57357050ebb..e937074d616 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverScoringFunctionFactoryMoneyOnly.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverScoringFunctionFactoryMoneyOnly.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.apache.logging.log4j.LogManager; import org.matsim.core.scoring.ScoringFunction; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverTracker.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverTracker.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverTracker.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverTracker.java index a03dc19cf06..e1fd6bc7ef5 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverTracker.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverTracker.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverTriggersCarrierReplanningListener.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverTriggersCarrierReplanningListener.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverTriggersCarrierReplanningListener.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverTriggersCarrierReplanningListener.java index 62a2a507aa2..2b8c4a6dfb9 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverTriggersCarrierReplanningListener.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverTriggersCarrierReplanningListener.java @@ -15,7 +15,7 @@ * See also COPYING, LICENSE and WARRANTY file * * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import com.graphhopper.jsprit.core.algorithm.VehicleRoutingAlgorithm; import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; @@ -29,7 +29,7 @@ import org.matsim.freight.carriers.jsprit.MatsimJspritFactory; import org.matsim.freight.carriers.jsprit.NetworkBasedTransportCosts; import org.matsim.freight.carriers.jsprit.NetworkRouter; -import org.matsim.contrib.freightreceiver.collaboration.CollaborationUtils; +import org.matsim.freight.receiver.collaboration.CollaborationUtils; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.events.IterationStartsEvent; import org.matsim.core.controler.listener.IterationStartsListener; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverUtils.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverUtils.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverUtils.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverUtils.java index dcd2861daed..e9b1b293368 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverUtils.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiverUtils.java @@ -1,4 +1,4 @@ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/Receivers.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/Receivers.java similarity index 99% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/Receivers.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/Receivers.java index 3d042480928..640aa31d6b8 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/Receivers.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/Receivers.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversReader.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversReader.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversReader.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversReader.java index 63afdf1c4cd..1c68dd3dbfe 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversReader.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversReader.java @@ -18,7 +18,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.matsim.core.utils.io.MatsimXmlParser; import org.xml.sax.Attributes; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversReaderV2.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversReaderV2.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversReaderV2.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversReaderV2.java index 2036326c078..b886be795f8 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversReaderV2.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversReaderV2.java @@ -18,13 +18,13 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.TimeWindow; -import org.matsim.contrib.freightreceiver.collaboration.CollaborationUtils; +import org.matsim.freight.receiver.collaboration.CollaborationUtils; import org.matsim.core.api.internal.MatsimReader; import org.matsim.core.utils.io.MatsimXmlParser; import org.matsim.core.utils.misc.Counter; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversWriter.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversWriter.java similarity index 99% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversWriter.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversWriter.java index cd9e2f33a06..68b37813398 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversWriter.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversWriter.java @@ -18,7 +18,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversWriterHandler.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversWriterHandler.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversWriterHandler.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversWriterHandler.java index 09172159e06..1ceacde5d4b 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversWriterHandler.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversWriterHandler.java @@ -18,7 +18,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.matsim.freight.carriers.TimeWindow; import java.io.BufferedWriter; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversWriterHandlerImplV1.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversWriterHandlerImplV1.java similarity index 99% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversWriterHandlerImplV1.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversWriterHandlerImplV1.java index ecc7b58f43e..4e5a4b2e262 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversWriterHandlerImplV1.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversWriterHandlerImplV1.java @@ -18,7 +18,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.matsim.freight.carriers.TimeWindow; import org.matsim.core.utils.misc.Time; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversWriterHandlerImplV2.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversWriterHandlerImplV2.java similarity index 99% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversWriterHandlerImplV2.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversWriterHandlerImplV2.java index c2b8fe50f1b..b9091c62111 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiversWriterHandlerImplV2.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReceiversWriterHandlerImplV2.java @@ -18,7 +18,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.matsim.freight.carriers.TimeWindow; import org.matsim.core.utils.misc.Time; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReorderPolicy.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReorderPolicy.java similarity index 97% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReorderPolicy.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReorderPolicy.java index e04152e5e30..9447bb3b8bc 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReorderPolicy.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/ReorderPolicy.java @@ -18,7 +18,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.matsim.utils.objectattributes.attributable.Attributable; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/SSReorderPolicy.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/SSReorderPolicy.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/SSReorderPolicy.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/SSReorderPolicy.java index 9928bbc6191..f9620ef58b2 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/SSReorderPolicy.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/SSReorderPolicy.java @@ -18,7 +18,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.matsim.utils.objectattributes.attributable.Attributes; import org.matsim.utils.objectattributes.attributable.AttributesImpl; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/UsecasesCarrierScoringFunctionFactory.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/UsecasesCarrierScoringFunctionFactory.java similarity index 99% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/UsecasesCarrierScoringFunctionFactory.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/UsecasesCarrierScoringFunctionFactory.java index 5cc872f2b50..f1287ff4de3 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/UsecasesCarrierScoringFunctionFactory.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/UsecasesCarrierScoringFunctionFactory.java @@ -1,4 +1,4 @@ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/Coalition.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/Coalition.java similarity index 86% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/Coalition.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/Coalition.java index 9afea8cdc9e..77e28d853e6 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/Coalition.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/Coalition.java @@ -1,7 +1,7 @@ -package org.matsim.contrib.freightreceiver.collaboration; +package org.matsim.freight.receiver.collaboration; import org.matsim.freight.carriers.Carrier; -import org.matsim.contrib.freightreceiver.Receiver; +import org.matsim.freight.receiver.Receiver; import org.matsim.utils.objectattributes.attributable.Attributable; import java.util.Collection; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/CollaborationUtils.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/CollaborationUtils.java similarity index 97% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/CollaborationUtils.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/CollaborationUtils.java index 25e73445613..3775eec413b 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/CollaborationUtils.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/CollaborationUtils.java @@ -1,4 +1,4 @@ -package org.matsim.contrib.freightreceiver.collaboration; +package org.matsim.freight.receiver.collaboration; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -7,7 +7,7 @@ import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.CarriersUtils; import org.matsim.freight.carriers.Carriers; -import org.matsim.contrib.freightreceiver.*; +import org.matsim.freight.receiver.*; public class CollaborationUtils{ private CollaborationUtils(){} // do not instantiate diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/CollaborationUtilsNew.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/CollaborationUtilsNew.java similarity index 70% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/CollaborationUtilsNew.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/CollaborationUtilsNew.java index c3c3d3d544e..68576dc0ea3 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/CollaborationUtilsNew.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/CollaborationUtilsNew.java @@ -1,7 +1,7 @@ -package org.matsim.contrib.freightreceiver.collaboration; +package org.matsim.freight.receiver.collaboration; import org.matsim.freight.carriers.Carriers; -import org.matsim.contrib.freightreceiver.*; +import org.matsim.freight.receiver.Receivers; /** * Class with utilities to handle the collaboration between {@link Carriers} diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/MutableCoalition.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/MutableCoalition.java similarity index 93% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/MutableCoalition.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/MutableCoalition.java index 4799f493912..c6597ff695d 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/MutableCoalition.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/MutableCoalition.java @@ -1,8 +1,8 @@ -package org.matsim.contrib.freightreceiver.collaboration; +package org.matsim.freight.receiver.collaboration; import org.matsim.freight.carriers.Carrier; -import org.matsim.contrib.freightreceiver.Receiver; +import org.matsim.freight.receiver.Receiver; import org.matsim.utils.objectattributes.attributable.Attributes; import org.matsim.utils.objectattributes.attributable.AttributesImpl; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/OrderSizeMutator.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/OrderSizeMutator.java similarity index 93% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/OrderSizeMutator.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/OrderSizeMutator.java index 99b91c04395..118f6ed3b84 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/OrderSizeMutator.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/OrderSizeMutator.java @@ -16,11 +16,11 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver.collaboration; +package org.matsim.freight.receiver.collaboration; -import org.matsim.contrib.freightreceiver.Order; -import org.matsim.contrib.freightreceiver.ReceiverOrder; -import org.matsim.contrib.freightreceiver.ReceiverPlan; +import org.matsim.freight.receiver.Order; +import org.matsim.freight.receiver.ReceiverOrder; +import org.matsim.freight.receiver.ReceiverPlan; import org.matsim.core.gbl.MatsimRandom; import org.matsim.core.replanning.ReplanningContext; import org.matsim.core.replanning.modules.GenericPlanStrategyModule; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/TimeWindowMutator.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/TimeWindowMutator.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/TimeWindowMutator.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/TimeWindowMutator.java index bf972b057fe..abd734db026 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/collaboration/TimeWindowMutator.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/collaboration/TimeWindowMutator.java @@ -19,10 +19,10 @@ /** * */ -package org.matsim.contrib.freightreceiver.collaboration; +package org.matsim.freight.receiver.collaboration; import org.matsim.freight.carriers.TimeWindow; -import org.matsim.contrib.freightreceiver.ReceiverPlan; +import org.matsim.freight.receiver.ReceiverPlan; import org.matsim.core.gbl.MatsimRandom; import org.matsim.core.replanning.ReplanningContext; import org.matsim.core.replanning.modules.GenericPlanStrategyModule; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/multiday/MultidayUtils.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/multiday/MultidayUtils.java similarity index 89% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/multiday/MultidayUtils.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/multiday/MultidayUtils.java index 46fad091944..b5aad6ea53a 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/multiday/MultidayUtils.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/multiday/MultidayUtils.java @@ -1,4 +1,4 @@ -package org.matsim.contrib.freightreceiver.multiday; +package org.matsim.freight.receiver.multiday; import org.matsim.core.utils.misc.OptionalTime; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/CollaborationStatusMutator.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/CollaborationStatusMutator.java similarity index 88% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/CollaborationStatusMutator.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/CollaborationStatusMutator.java index 018a8f64c87..caa840d48c1 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/CollaborationStatusMutator.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/CollaborationStatusMutator.java @@ -1,9 +1,9 @@ -package org.matsim.contrib.freightreceiver.replanning; +package org.matsim.freight.receiver.replanning; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; -import org.matsim.contrib.freightreceiver.ReceiverPlan; -import org.matsim.contrib.freightreceiver.collaboration.CollaborationUtils; +import org.matsim.freight.receiver.ReceiverPlan; +import org.matsim.freight.receiver.collaboration.CollaborationUtils; import org.matsim.core.replanning.ReplanningContext; import org.matsim.core.replanning.modules.GenericPlanStrategyModule; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/OrderFrequencyStrategyManager.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/OrderFrequencyStrategyManager.java similarity index 91% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/OrderFrequencyStrategyManager.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/OrderFrequencyStrategyManager.java index f74750d9924..eb14b8eeb22 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/OrderFrequencyStrategyManager.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/OrderFrequencyStrategyManager.java @@ -1,11 +1,11 @@ -package org.matsim.contrib.freightreceiver.replanning; +package org.matsim.freight.receiver.replanning; import com.google.inject.Inject; import com.google.inject.Provider; import org.matsim.api.core.v01.Scenario; -import org.matsim.contrib.freightreceiver.Receiver; -import org.matsim.contrib.freightreceiver.ReceiverPlan; -import org.matsim.contrib.freightreceiver.collaboration.OrderSizeMutator; +import org.matsim.freight.receiver.Receiver; +import org.matsim.freight.receiver.ReceiverPlan; +import org.matsim.freight.receiver.collaboration.OrderSizeMutator; import org.matsim.core.replanning.GenericPlanStrategyImpl; import org.matsim.core.replanning.selectors.ExpBetaPlanChanger; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ReceiverReplanningUtils.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ReceiverReplanningUtils.java similarity index 81% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ReceiverReplanningUtils.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ReceiverReplanningUtils.java index 2bdc4eadbb7..71309261c26 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ReceiverReplanningUtils.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ReceiverReplanningUtils.java @@ -1,7 +1,7 @@ -package org.matsim.contrib.freightreceiver.replanning; +package org.matsim.freight.receiver.replanning; import com.google.inject.Provider; -import org.matsim.contrib.freightreceiver.ReceiverReplanningType; +import org.matsim.freight.receiver.ReceiverReplanningType; /** * A single entry point for receiver replanning. diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ReceiverStrategyManager.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ReceiverStrategyManager.java similarity index 88% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ReceiverStrategyManager.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ReceiverStrategyManager.java index 0ef128e441a..f10d7d98145 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ReceiverStrategyManager.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ReceiverStrategyManager.java @@ -18,11 +18,11 @@ * *********************************************************************** */ -package org.matsim.contrib.freightreceiver.replanning; +package org.matsim.freight.receiver.replanning; import org.matsim.freight.carriers.controler.CarrierStrategyManager; -import org.matsim.contrib.freightreceiver.Receiver; -import org.matsim.contrib.freightreceiver.ReceiverPlan; +import org.matsim.freight.receiver.Receiver; +import org.matsim.freight.receiver.ReceiverPlan; import org.matsim.core.replanning.GenericStrategyManager; /** diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ReceiverStrategyManagerImpl.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ReceiverStrategyManagerImpl.java similarity index 94% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ReceiverStrategyManagerImpl.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ReceiverStrategyManagerImpl.java index 4b56bee4470..c164c64a039 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ReceiverStrategyManagerImpl.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ReceiverStrategyManagerImpl.java @@ -18,11 +18,11 @@ * *********************************************************************** */ -package org.matsim.contrib.freightreceiver.replanning; +package org.matsim.freight.receiver.replanning; import org.matsim.api.core.v01.population.HasPlansAndId; -import org.matsim.contrib.freightreceiver.Receiver; -import org.matsim.contrib.freightreceiver.ReceiverPlan; +import org.matsim.freight.receiver.Receiver; +import org.matsim.freight.receiver.ReceiverPlan; import org.matsim.core.replanning.GenericPlanStrategy; import org.matsim.core.replanning.GenericStrategyManager; import org.matsim.core.replanning.GenericStrategyManagerImpl; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ServiceTimeMutator.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ServiceTimeMutator.java similarity index 93% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ServiceTimeMutator.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ServiceTimeMutator.java index 842ad6c5584..7488cc3e748 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ServiceTimeMutator.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ServiceTimeMutator.java @@ -16,13 +16,13 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver.replanning; +package org.matsim.freight.receiver.replanning; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; -import org.matsim.contrib.freightreceiver.Order; -import org.matsim.contrib.freightreceiver.ReceiverOrder; -import org.matsim.contrib.freightreceiver.ReceiverPlan; +import org.matsim.freight.receiver.Order; +import org.matsim.freight.receiver.ReceiverOrder; +import org.matsim.freight.receiver.ReceiverPlan; import org.matsim.core.replanning.ReplanningContext; import org.matsim.core.replanning.modules.GenericPlanStrategyModule; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ServiceTimeStrategyManagerProvider.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ServiceTimeStrategyManagerProvider.java similarity index 95% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ServiceTimeStrategyManagerProvider.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ServiceTimeStrategyManagerProvider.java index 6271e402b57..c88b09a261d 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/ServiceTimeStrategyManagerProvider.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/ServiceTimeStrategyManagerProvider.java @@ -1,10 +1,10 @@ -package org.matsim.contrib.freightreceiver.replanning; +package org.matsim.freight.receiver.replanning; import com.google.inject.Inject; import com.google.inject.Provider; import org.matsim.api.core.v01.Scenario; -import org.matsim.contrib.freightreceiver.Receiver; -import org.matsim.contrib.freightreceiver.ReceiverPlan; +import org.matsim.freight.receiver.Receiver; +import org.matsim.freight.receiver.ReceiverPlan; import org.matsim.core.replanning.GenericPlanStrategy; import org.matsim.core.replanning.GenericPlanStrategyImpl; import org.matsim.core.replanning.selectors.ExpBetaPlanChanger; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/TimeWindowStrategyManagerFactory.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/TimeWindowStrategyManagerFactory.java similarity index 92% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/TimeWindowStrategyManagerFactory.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/TimeWindowStrategyManagerFactory.java index e19d1437dc0..87926d796a2 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/TimeWindowStrategyManagerFactory.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/TimeWindowStrategyManagerFactory.java @@ -1,13 +1,13 @@ /** * */ -package org.matsim.contrib.freightreceiver.replanning; +package org.matsim.freight.receiver.replanning; import com.google.inject.Inject; import com.google.inject.Provider; import org.matsim.api.core.v01.Scenario; -import org.matsim.contrib.freightreceiver.Receiver; -import org.matsim.contrib.freightreceiver.ReceiverPlan; +import org.matsim.freight.receiver.Receiver; +import org.matsim.freight.receiver.ReceiverPlan; import org.matsim.core.replanning.GenericPlanStrategyImpl; import org.matsim.core.replanning.selectors.ExpBetaPlanChanger; import org.matsim.core.utils.misc.Time; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/TimeWindowUpperBoundMutator.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/TimeWindowUpperBoundMutator.java similarity index 97% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/TimeWindowUpperBoundMutator.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/TimeWindowUpperBoundMutator.java index 97ea20b2e20..553504a7862 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/replanning/TimeWindowUpperBoundMutator.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/replanning/TimeWindowUpperBoundMutator.java @@ -16,10 +16,10 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver.replanning; +package org.matsim.freight.receiver.replanning; import org.matsim.freight.carriers.TimeWindow; -import org.matsim.contrib.freightreceiver.ReceiverPlan; +import org.matsim.freight.receiver.ReceiverPlan; import org.matsim.core.gbl.MatsimRandom; import org.matsim.core.replanning.ReplanningContext; import org.matsim.core.replanning.modules.GenericPlanStrategyModule; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/run/chessboard/ReceiverChessboardParameters.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/run/chessboard/ReceiverChessboardParameters.java similarity index 94% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/run/chessboard/ReceiverChessboardParameters.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/run/chessboard/ReceiverChessboardParameters.java index b5b946942b0..327c65716d6 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/run/chessboard/ReceiverChessboardParameters.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/run/chessboard/ReceiverChessboardParameters.java @@ -16,9 +16,9 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver.run.chessboard; +package org.matsim.freight.receiver.run.chessboard; -import org.matsim.contrib.freightreceiver.ReceiverReplanningType; +import org.matsim.freight.receiver.ReceiverReplanningType; /** * Class to help with setting experimental parameters. These parameters are diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/run/chessboard/ReceiverChessboardScenario.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/run/chessboard/ReceiverChessboardScenario.java similarity index 98% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/run/chessboard/ReceiverChessboardScenario.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/run/chessboard/ReceiverChessboardScenario.java index b5b2f535b45..fd036695370 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/run/chessboard/ReceiverChessboardScenario.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/run/chessboard/ReceiverChessboardScenario.java @@ -18,7 +18,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver.run.chessboard; +package org.matsim.freight.receiver.run.chessboard; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -29,8 +29,8 @@ import org.matsim.api.core.v01.network.NetworkWriter; import org.matsim.freight.carriers.*; import org.matsim.freight.carriers.CarrierCapabilities.FleetSize; -import org.matsim.contrib.freightreceiver.*; -import org.matsim.contrib.freightreceiver.collaboration.CollaborationUtils; +import org.matsim.freight.receiver.*; +import org.matsim.freight.receiver.collaboration.CollaborationUtils; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.config.ConfigWriter; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/run/chessboard/RunReceiverChessboardWithEqualProportionCost.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/run/chessboard/RunReceiverChessboardWithEqualProportionCost.java similarity index 93% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/run/chessboard/RunReceiverChessboardWithEqualProportionCost.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/run/chessboard/RunReceiverChessboardWithEqualProportionCost.java index 469f45574ee..4e7b9b2607a 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/run/chessboard/RunReceiverChessboardWithEqualProportionCost.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/run/chessboard/RunReceiverChessboardWithEqualProportionCost.java @@ -18,7 +18,7 @@ * *********************************************************************** */ -package org.matsim.contrib.freightreceiver.run.chessboard; +package org.matsim.freight.receiver.run.chessboard; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -26,9 +26,9 @@ import org.matsim.freight.carriers.CarriersUtils; import org.matsim.freight.carriers.Carriers; import org.matsim.freight.carriers.usecases.analysis.CarrierScoreStats; -import org.matsim.contrib.freightreceiver.ReceiverModule; -import org.matsim.contrib.freightreceiver.ReceiverReplanningType; -import org.matsim.contrib.freightreceiver.ReceiverUtils; +import org.matsim.freight.receiver.ReceiverModule; +import org.matsim.freight.receiver.ReceiverReplanningType; +import org.matsim.freight.receiver.ReceiverUtils; import org.matsim.core.controler.Controler; import org.matsim.core.controler.MatsimServices; diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/run/chessboard/RunReceiverChessboardWithFixedCarrierCost.java b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/run/chessboard/RunReceiverChessboardWithFixedCarrierCost.java similarity index 93% rename from contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/run/chessboard/RunReceiverChessboardWithFixedCarrierCost.java rename to contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/run/chessboard/RunReceiverChessboardWithFixedCarrierCost.java index 112785c45b8..2570eb80c16 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/run/chessboard/RunReceiverChessboardWithFixedCarrierCost.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/freight/receiver/run/chessboard/RunReceiverChessboardWithFixedCarrierCost.java @@ -18,7 +18,7 @@ * *********************************************************************** */ -package org.matsim.contrib.freightreceiver.run.chessboard; +package org.matsim.freight.receiver.run.chessboard; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -26,9 +26,9 @@ import org.matsim.freight.carriers.CarriersUtils; import org.matsim.freight.carriers.Carriers; import org.matsim.freight.carriers.usecases.analysis.CarrierScoreStats; -import org.matsim.contrib.freightreceiver.ReceiverModule; -import org.matsim.contrib.freightreceiver.ReceiverReplanningType; -import org.matsim.contrib.freightreceiver.ReceiverUtils; +import org.matsim.freight.receiver.ReceiverModule; +import org.matsim.freight.receiver.ReceiverReplanningType; +import org.matsim.freight.receiver.ReceiverUtils; import org.matsim.core.controler.Controler; import org.matsim.core.controler.MatsimServices; diff --git a/contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocationFixedTest.java b/contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiverCostAllocationFixedTest.java similarity index 88% rename from contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocationFixedTest.java rename to contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiverCostAllocationFixedTest.java index 8faf02fd1c0..4189a6e9779 100644 --- a/contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiverCostAllocationFixedTest.java +++ b/contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiverCostAllocationFixedTest.java @@ -1,4 +1,4 @@ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiverPlanTest.java b/contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiverPlanTest.java similarity index 97% rename from contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiverPlanTest.java rename to contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiverPlanTest.java index 9933bda39d7..ea784499f81 100644 --- a/contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiverPlanTest.java +++ b/contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiverPlanTest.java @@ -16,7 +16,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; diff --git a/contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiversReaderTest.java b/contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiversReaderTest.java similarity index 98% rename from contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiversReaderTest.java rename to contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiversReaderTest.java index 970641df24e..6a893a9409f 100644 --- a/contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiversReaderTest.java +++ b/contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiversReaderTest.java @@ -18,7 +18,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -26,7 +26,7 @@ import org.matsim.api.core.v01.Id; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.TimeWindow; -import org.matsim.contrib.freightreceiver.collaboration.CollaborationUtils; +import org.matsim.freight.receiver.collaboration.CollaborationUtils; import org.matsim.core.utils.misc.Time; import org.matsim.testcases.MatsimTestUtils; diff --git a/contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiversTest.java b/contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiversTest.java similarity index 97% rename from contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiversTest.java rename to contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiversTest.java index 35dbed33c31..8ca84ad87f8 100644 --- a/contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiversTest.java +++ b/contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiversTest.java @@ -1,11 +1,11 @@ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; -import org.matsim.contrib.freightreceiver.run.chessboard.ReceiverChessboardScenario; +import org.matsim.freight.receiver.run.chessboard.ReceiverChessboardScenario; import org.matsim.testcases.MatsimTestUtils; import java.util.Collection; diff --git a/contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiversWriterTest.java b/contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiversWriterTest.java similarity index 96% rename from contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiversWriterTest.java rename to contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiversWriterTest.java index 34a66898d68..1f9a453ce08 100644 --- a/contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/ReceiversWriterTest.java +++ b/contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/ReceiversWriterTest.java @@ -18,13 +18,13 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Scenario; -import org.matsim.contrib.freightreceiver.run.chessboard.ReceiverChessboardScenario; +import org.matsim.freight.receiver.run.chessboard.ReceiverChessboardScenario; import org.matsim.testcases.MatsimTestUtils; import java.io.File; diff --git a/contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/SSReorderPolicyTest.java b/contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/SSReorderPolicyTest.java similarity index 97% rename from contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/SSReorderPolicyTest.java rename to contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/SSReorderPolicyTest.java index 1841ae963fc..c22aea6a54b 100644 --- a/contribs/freightreceiver/src/test/java/org/matsim/contrib/freightreceiver/SSReorderPolicyTest.java +++ b/contribs/freightreceiver/src/test/java/org/matsim/freight/receiver/SSReorderPolicyTest.java @@ -18,7 +18,7 @@ * * * *********************************************************************** */ -package org.matsim.contrib.freightreceiver; +package org.matsim.freight.receiver; import org.junit.jupiter.api.Assertions; diff --git a/contribs/freightreceiver/test/input/org/matsim/contrib/freightreceiver/ReceiversReaderTest/receivers_v2_basic.xml b/contribs/freightreceiver/test/input/org/matsim/freight/receiver/ReceiversReaderTest/receivers_v2_basic.xml similarity index 100% rename from contribs/freightreceiver/test/input/org/matsim/contrib/freightreceiver/ReceiversReaderTest/receivers_v2_basic.xml rename to contribs/freightreceiver/test/input/org/matsim/freight/receiver/ReceiversReaderTest/receivers_v2_basic.xml diff --git a/contribs/freightreceiver/test/input/org/matsim/contrib/freightreceiver/ReceiversReaderTest/receivers_v2_full.xml b/contribs/freightreceiver/test/input/org/matsim/freight/receiver/ReceiversReaderTest/receivers_v2_full.xml similarity index 100% rename from contribs/freightreceiver/test/input/org/matsim/contrib/freightreceiver/ReceiversReaderTest/receivers_v2_full.xml rename to contribs/freightreceiver/test/input/org/matsim/freight/receiver/ReceiversReaderTest/receivers_v2_full.xml diff --git a/contribs/freightreceiver/test/input/org/matsim/contrib/freightreceiver/ReceiversTest/receivers_v2.xml b/contribs/freightreceiver/test/input/org/matsim/freight/receiver/ReceiversTest/receivers_v2.xml similarity index 100% rename from contribs/freightreceiver/test/input/org/matsim/contrib/freightreceiver/ReceiversTest/receivers_v2.xml rename to contribs/freightreceiver/test/input/org/matsim/freight/receiver/ReceiversTest/receivers_v2.xml diff --git a/contribs/hybridsim/pom.xml b/contribs/hybridsim/pom.xml index d8f69b28046..7bb94a4feff 100644 --- a/contribs/hybridsim/pom.xml +++ b/contribs/hybridsim/pom.xml @@ -11,7 +11,7 @@ 4.28.3 - 1.66.0 + 1.68.1 diff --git a/contribs/minibus/src/main/java/org/matsim/contrib/minibus/hook/PVehiclesFactory.java b/contribs/minibus/src/main/java/org/matsim/contrib/minibus/hook/PVehiclesFactory.java index cca689ac56c..7069b4c3b0a 100644 --- a/contribs/minibus/src/main/java/org/matsim/contrib/minibus/hook/PVehiclesFactory.java +++ b/contribs/minibus/src/main/java/org/matsim/contrib/minibus/hook/PVehiclesFactory.java @@ -22,6 +22,7 @@ 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.contrib.minibus.PConfigGroup; import org.matsim.pt.transitSchedule.api.Departure; import org.matsim.pt.transitSchedule.api.TransitLine; @@ -31,15 +32,15 @@ /** * Generates vehicles for a whole transit schedule - * + * * @author aneumann * */ class PVehiclesFactory { - + @SuppressWarnings("unused") private final static Logger log = LogManager.getLogger(PVehiclesFactory.class); - + private final PConfigGroup pConfig; public PVehiclesFactory(PConfigGroup pConfig) { @@ -48,11 +49,11 @@ public PVehiclesFactory(PConfigGroup pConfig) { /** * Create vehicles for each departure of the given transit schedule. - * + * * @return Vehicles used by paratranit lines */ - public Vehicles createVehicles(TransitSchedule pTransitSchedule){ - Vehicles vehicles = VehicleUtils.createVehiclesContainer(); + public Vehicles createVehicles(TransitSchedule pTransitSchedule){ + Vehicles vehicles = VehicleUtils.createVehiclesContainer(); VehiclesFactory vehFactory = vehicles.getFactory(); VehicleType vehType = vehFactory.createVehicleType(Id.create(this.pConfig.getPIdentifier(), VehicleType.class)); // VehicleCapacity capacity = new VehicleCapacity(); @@ -61,11 +62,12 @@ public Vehicles createVehicles(TransitSchedule pTransitSchedule){ // vehType.setCapacity(capacity); vehType.setPcuEquivalents(this.pConfig.getPassengerCarEquivalents()); vehType.setMaximumVelocity(this.pConfig.getVehicleMaximumVelocity()); + vehType.setNetworkMode(TransportMode.car); VehicleUtils.setAccessTime(vehType, this.pConfig.getDelayPerBoardingPassenger()); VehicleUtils.setEgressTime(vehType, this.pConfig.getDelayPerAlightingPassenger()); VehicleUtils.setDoorOperationMode(vehType, this.pConfig.getDoorOperationMode()) ; vehicles.addVehicleType( vehType); - + for (TransitLine line : pTransitSchedule.getTransitLines().values()) { for (TransitRoute route : line.getRoutes().values()) { for (Departure departure : route.getDepartures().values()) { @@ -76,7 +78,7 @@ public Vehicles createVehicles(TransitSchedule pTransitSchedule){ } } } - + return vehicles; } } diff --git a/contribs/noise/src/main/java/org/matsim/contrib/noise/Grid.java b/contribs/noise/src/main/java/org/matsim/contrib/noise/Grid.java index 6815899be8a..48eb2951430 100644 --- a/contribs/noise/src/main/java/org/matsim/contrib/noise/Grid.java +++ b/contribs/noise/src/main/java/org/matsim/contrib/noise/Grid.java @@ -268,19 +268,32 @@ private void setActivityCoord2NearestReceiverPointId () { counter.printCounter(); counter = new Counter("compute nearest receiver-points #"); + Counter otherCounter = new Counter("activities outside grid #"); for (Coord coord : consideredActivityCoordsForSpatialFunctionality) { // TODO maybe add a check here so we consider only the rp in the 9 surrounding cells? - ReceiverPoint rp = qTree.getClosest(coord.getX(), coord.getY()); - if(rp != null) { - if(activityCoord2receiverPointId.put(coord, rp.getId()) != null){ - log.warn("this must not happen"); + // ts, nov' 24: ---> might be done by the following filtering (by grid) ?? + + // Filter activity coords that are within the quadTree. + // I do not know, why whe put a buffer around the grid when instantiating the QuadTree, above, but I'll keep it for now + // tschlenther, nov '24 + if (coord.getX() >= xCoordMin && coord.getX() <= xCoordMax && + coord.getY() >= yCoordMin && coord.getY() <= yCoordMax){ + + ReceiverPoint rp = qTree.getClosest(coord.getX(), coord.getY()); + if(rp != null) { + if(activityCoord2receiverPointId.put(coord, rp.getId()) != null){ + log.warn("this must not happen"); + } } - } - counter.incCounter(); + counter.incCounter(); + } else { + otherCounter.incCounter(); + } } counter.printCounter(); + otherCounter.printCounter(); } private void readReceiverPoints(String file, CoordinateTransformation ct) throws IOException { diff --git a/contribs/noise/src/main/java/org/matsim/contrib/noise/NoiseConfigGroup.java b/contribs/noise/src/main/java/org/matsim/contrib/noise/NoiseConfigGroup.java index 06e793c85d9..c2c9bc8d039 100644 --- a/contribs/noise/src/main/java/org/matsim/contrib/noise/NoiseConfigGroup.java +++ b/contribs/noise/src/main/java/org/matsim/contrib/noise/NoiseConfigGroup.java @@ -26,6 +26,7 @@ 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.api.core.v01.network.Link; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigGroup; @@ -134,9 +135,9 @@ public enum NoiseAllocationApproach { private NoiseAllocationApproach noiseAllocationApproach = NoiseAllocationApproach.AverageCost; private String[] hgvIdPrefixes = {"lkw", "truck", "freight"}; + private Set networkModesToIgnore = CollectionUtils.stringArrayToSet( new String[]{TransportMode.bike, TransportMode.walk, TransportMode.transit_walk, TransportMode.non_network_walk} ); private Set busIdIdentifier = new HashSet<>(); private Set> tunnelLinkIDs = new HashSet<>(); - private Set networkModesToIgnore = new HashSet<>(); private double noiseTollFactor = 1.0; @@ -209,7 +210,7 @@ public Map getComments() { comments.put(USE_DEM, "Set to 'true' if a DEM (digital elevation model) should be used for road gradients. Otherwise set to 'false'."); comments.put(DEM_FILE, "Path to the geoTiff file of the DEM."); - comments.put(NETWORK_MODES_TO_IGNORE, "Specifies the network modes to be excluded from the noise computation, e.g. 'bike'."); + comments.put(NETWORK_MODES_TO_IGNORE, "Specifies the network modes to be excluded from the noise computation. By default, the following modes are excluded: [bike, walk, transit_walk, non_network_walk]."); comments.put(NOISE_COMPUTATION_METHOD, "Specifies the computation method of different guidelines: " + Arrays.toString(NoiseComputationMethod.values())); @@ -313,6 +314,37 @@ private void checkNoiseParametersForConsistency(Config config) { this.considerNoiseBarriers = false; } } + + List walkAndBikeModes = List.of(TransportMode.bike, TransportMode.walk, TransportMode.transit_walk, TransportMode.non_network_walk); + String exclude = "["; + for (String mode : walkAndBikeModes){ + exclude += mode + ","; + } + exclude = exclude.substring(0, exclude.lastIndexOf(',')) + "]"; + String warning = "You should set networkModesToIgnore such that all of the standard walk and bike modes are included!" + + " These are " + exclude + "."; + if (this.networkModesToIgnore.isEmpty() || + ! this.networkModesToIgnore.containsAll(walkAndBikeModes)){ + boolean bikeOrWalkIsNetworkMode = config.routing().getNetworkModes().stream() + .filter(networkMode -> networkModesToIgnore.contains(networkMode)) + .findAny() + .isPresent(); + if (bikeOrWalkIsNetworkMode){ + //TODO: use enum for consistencyCheckLevel and replace all RunTimeExceptions thrown within this class. + throw new RuntimeException(warning + " You configured one of these modes as networkMode in config().routing.getNetworkModes()! This will lead to wrong results!" + + "Make sure ignore all network modes that do not model a car, a heavy-goods-vehicle (HGV) or a transit vehicle to be considered by the noise analysis!!! Will abort now..."); + } else { + log.warn( warning + + " Otherwise, your results will turn wrong as soon as you are routing these modes on the network (which luckily appears not to be the case in your current setup)."); + } + } + + Set defaultHGVIdPrefixes = Set.of("lkw", "truck", "freight"); + + if (! defaultHGVIdPrefixes.stream().allMatch(defaultPrefix -> + Arrays.stream(this.hgvIdPrefixes).anyMatch(prefix -> defaultPrefix.equals(prefix)))){ + log.warn("You are not considering all of [lkw, truck, freight] as HGV prefixes, which you should! Especially when you use scenarios created by VSP!!"); + } } // ######################################################################################################## diff --git a/contribs/noise/src/main/java/org/matsim/contrib/noise/NoiseContextImpl.java b/contribs/noise/src/main/java/org/matsim/contrib/noise/NoiseContextImpl.java index d941615320a..bad61d3696c 100644 --- a/contribs/noise/src/main/java/org/matsim/contrib/noise/NoiseContextImpl.java +++ b/contribs/noise/src/main/java/org/matsim/contrib/noise/NoiseContextImpl.java @@ -201,9 +201,9 @@ private void checkConsistency() { || this.grid.getGridParams().getReceiverPointsGridMinX() != 0. || this.grid.getGridParams().getReceiverPointsGridMaxY() != 0. || this.grid.getGridParams().getReceiverPointsGridMinY() != 0.) { - log.warn("In order to keep track of the agent activities, the grid of receiver points should not be limited to a set of predefined coordinates." + log.warn("In order to keep track of ALL the agent activities, the grid of receiver points should not be limited to a set of predefined coordinates." + "For a grid covering all activity locations, set the minimum and maximum x/y parameters to 0.0. " - + "There will be more agents mapped to the receiver points at the edges. Only the inner receiver points should be used for analysis."); + + "Damages will be computed only for activities that are performed within the receiver point grid."); } if (this.grid.getGridParams().getReceiverPointsGridMinX() == 0. && this.grid.getGridParams().getReceiverPointsGridMinY() == 0. && this.grid.getGridParams().getReceiverPointsGridMaxX() == 0. && this.grid.getGridParams().getReceiverPointsGridMaxY() == 0.) { diff --git a/contribs/osm/src/main/java/org/matsim/contrib/osm/networkReader/LinkProperties.java b/contribs/osm/src/main/java/org/matsim/contrib/osm/networkReader/LinkProperties.java index 41d2b302d37..6d8ddbac9c8 100644 --- a/contribs/osm/src/main/java/org/matsim/contrib/osm/networkReader/LinkProperties.java +++ b/contribs/osm/src/main/java/org/matsim/contrib/osm/networkReader/LinkProperties.java @@ -18,6 +18,7 @@ public class LinkProperties { public static final int LEVEL_UNCLASSIFIED = 6; public static final int LEVEL_RESIDENTIAL = 7; public static final int LEVEL_LIVING_STREET = 8; + public static final int LEVEL_PATH = 9; /** * Assume for links with max speed lower than 51km/h to be in urban areas. diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DefaultDashboardProvider.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DefaultDashboardProvider.java index a01674f4856..5cb80fec839 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DefaultDashboardProvider.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DefaultDashboardProvider.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; /** * Default dashboards suited for every run. @@ -19,7 +20,7 @@ public List getDashboards(Config config, SimWrapper simWrapper) { List result = new ArrayList<>(List.of( new OverviewDashboard(), new TripDashboard(), - new TrafficDashboard() + new TrafficDashboard(Set.copyOf(config.qsim().getMainModes())) )); if (config.transit().isUseTransit()) { diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/PublicTransitDashboard.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/PublicTransitDashboard.java index fc902474591..50960fbaffe 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/PublicTransitDashboard.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/PublicTransitDashboard.java @@ -1,5 +1,7 @@ package org.matsim.simwrapper.dashboard; +import org.matsim.application.analysis.pt.PublicTransitAnalysis; +import org.matsim.application.prepare.network.CreateAvroNetwork; import org.matsim.simwrapper.Dashboard; import org.matsim.simwrapper.Header; import org.matsim.simwrapper.Layout; @@ -34,8 +36,13 @@ public void configure(Header header, Layout layout) { viz.title = "Transit Viewer"; viz.height = 12d; viz.description = "Visualize the transit schedule."; - viz.network = "(*.)?output_network.xml.gz"; + + // Include a network that has not been filtered + viz.network = data.withContext("all").compute(CreateAvroNetwork.class, "network.avro", + "--mode-filter", "", "--shp", "none"); + viz.transitSchedule = data.output("(*.)?output_transitSchedule.xml.gz"); + viz.ptStop2stopFile = data.compute(PublicTransitAnalysis.class, "pt_pax_volumes.csv.gz"); if (!customRouteTypes.isEmpty()) viz.customRouteTypes = customRouteTypes; diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/viz/TransitViewer.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/viz/TransitViewer.java index 4f6622d2b11..bf32176b9ab 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/viz/TransitViewer.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/viz/TransitViewer.java @@ -15,19 +15,17 @@ public class TransitViewer extends Viz { @JsonProperty(required = true) public String transitSchedule; + @JsonProperty + public String ptStop2stopFile; + public List customRouteTypes; public TransitViewer() { super("transit"); } - public CustomRouteType addCustomRouteType(String label, String color, boolean hide) { - CustomRouteType crt = new CustomRouteType(); - crt.label = label; - crt.color = color; - crt.hide = hide; - customRouteTypes.add(crt); - return crt; + public static CustomRouteType customRouteType(String label, String color) { + return new CustomRouteType(label, color); } public static class CustomRouteType { @@ -36,6 +34,11 @@ public static class CustomRouteType { public Boolean hide; Match match; + private CustomRouteType(String label, String color) { + this.label = label; + this.color = color; + } + public CustomRouteType addMatchTransportMode(String... transportMode) { if (match == null) match = new Match(); diff --git a/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/DashboardTests.java b/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/DashboardTests.java index dca4a209df1..e3e92fa87a7 100644 --- a/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/DashboardTests.java +++ b/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/DashboardTests.java @@ -29,7 +29,7 @@ public class DashboardTests { private void run(Dashboard... dashboards) { Config config = TestScenario.loadConfig(utils); - config.controller().setLastIteration(2); + config.controller().setLastIteration(1); SimWrapperConfigGroup group = ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class); group.sampleSize = 0.001; @@ -43,40 +43,29 @@ private void run(Dashboard... dashboards) { controler.run(); } + @Test void defaults() { - Path out = Path.of(utils.getOutputDirectory(), "analysis", "population"); + Path out = Path.of(utils.getOutputDirectory(), "analysis"); run(); // Ensure default dashboards have been added Assertions.assertThat(out) - .isDirectoryContaining("glob:**stuck_agents.csv"); - } - - @Test - void stuckAgents() { - - Path out = Path.of(utils.getOutputDirectory(), "analysis", "population"); - - run(new StuckAgentDashboard()); - - Assertions.assertThat(out) - .isDirectoryContaining("glob:**stuck_agents.csv"); - - } - - @Test - void trip() { - - Path out = Path.of(utils.getOutputDirectory(), "analysis", "population"); - - run(new TripDashboard()); - Assertions.assertThat(out) - .isDirectoryContaining("glob:**trip_stats.csv") - .isDirectoryContaining("glob:**mode_share.csv") - .isDirectoryContaining("glob:**mode_shift.csv"); + // Stuck agents + .isDirectoryRecursivelyContaining("glob:**stuck_agents.csv") + // Trip stats + .isDirectoryRecursivelyContaining("glob:**trip_stats.csv") + .isDirectoryRecursivelyContaining("glob:**mode_share.csv") + .isDirectoryRecursivelyContaining("glob:**mode_share_per_purpose.csv") + .isDirectoryRecursivelyContaining("glob:**mode_shift.csv") + // Traffic stats + .isDirectoryRecursivelyContaining("glob:**traffic_stats_by_link_daily.csv") + .isDirectoryRecursivelyContaining("glob:**traffic_stats_by_road_type_and_hour.csv") + .isDirectoryRecursivelyContaining("glob:**traffic_stats_by_road_type_daily.csv") + // PT + .isDirectoryRecursivelyContaining("glob:**pt_pax_volumes.csv.gz"); } @Test @@ -128,21 +117,6 @@ void populationAttribute() { .isDirectoryContaining("glob:**total_agents.csv"); - } - - @Test - void traffic() { - - Path out = Path.of(utils.getOutputDirectory(), "analysis", "traffic"); - - run(new TrafficDashboard()); - - Assertions.assertThat(out) - .isDirectoryContaining("glob:**traffic_stats_by_link_daily.csv") - .isDirectoryContaining("glob:**traffic_stats_by_road_type_and_hour.csv") - .isDirectoryContaining("glob:**traffic_stats_by_road_type_daily.csv"); - - } @Test @@ -163,19 +137,20 @@ void ptCustom() { PublicTransitDashboard pt = new PublicTransitDashboard(); // bus - TransitViewer.CustomRouteType crt = new TransitViewer.CustomRouteType(); - crt.label = "Bus"; - crt.color = "#109192"; + TransitViewer.CustomRouteType crt = TransitViewer.customRouteType("Bus", "#109192"); crt.addMatchGtfsRouteType(3); // rail - TransitViewer.CustomRouteType crtRail = new TransitViewer.CustomRouteType(); - crtRail.label = "Rail"; - crtRail.color = "#EC0016"; + TransitViewer.CustomRouteType crtRail = TransitViewer.customRouteType("Rail", "#EC0016"); crtRail.addMatchGtfsRouteType(2); pt.withCustomRouteTypes(crt, crtRail); run(pt); + + Path out = Path.of(utils.getOutputDirectory(), "analysis", "pt"); + + Assertions.assertThat(out) + .isDirectoryContaining("glob:**pt_pax_volumes.csv.gz"); } } diff --git a/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/NoiseDashboardTests.java b/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/NoiseDashboardTests.java index a4ce705e001..178bfa9109f 100644 --- a/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/NoiseDashboardTests.java +++ b/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/NoiseDashboardTests.java @@ -1,5 +1,6 @@ package org.matsim.simwrapper.dashboard; +import com.opencsv.CSVReader; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -15,6 +16,7 @@ import org.matsim.testcases.MatsimTestUtils; +import java.io.FileReader; import java.net.URL; import java.nio.file.Path; @@ -51,6 +53,19 @@ void generate() { .isDirectoryContaining("glob:**damages_receiverPoint_per_day.avro") .isDirectoryContaining("glob:**noise_stats.csv"); - //TODO check content / values of the files + double totalDamages; + double totalImmissions; + try { + CSVReader reader = new CSVReader(new FileReader(utils.getOutputDirectory() + "analysis/noise/noise_stats.csv")); + reader.skip(1); + totalDamages = Double.parseDouble(reader.readNext()[1]); + totalImmissions = Double.parseDouble(reader.readNext()[1]); + } catch (Exception e) { + throw new RuntimeException(e); + } + + Assertions.assertThat(totalDamages == 3573114.25); + Assertions.assertThat( totalImmissions == 2.688); + } } diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultUnhandledServicesSolution.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultUnhandledServicesSolution.java index 4928ce2a401..735a2d8f44a 100644 --- a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultUnhandledServicesSolution.java +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultUnhandledServicesSolution.java @@ -34,61 +34,12 @@ public List createListOfCarrierWithUnhandledJobs(Scenario scenario){ return carriersWithUnhandledJobs; } - public int getServiceTimePerStop(Carrier carrier, GenerateSmallScaleCommercialTrafficDemand.CarrierAttributes carrierAttributes, int additionalTravelBufferPerIterationInMinutes) { - GenerateSmallScaleCommercialTrafficDemand.ServiceDurationPerCategoryKey key = null; - if (carrierAttributes.smallScaleCommercialTrafficType().equals( - GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.commercialPersonTraffic.toString())) - key = GenerateSmallScaleCommercialTrafficDemand.makeServiceDurationPerCategoryKey(carrierAttributes.selectedStartCategory(), null, carrierAttributes.smallScaleCommercialTrafficType()); - else if (carrierAttributes.smallScaleCommercialTrafficType().equals( - GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString())) { - key = GenerateSmallScaleCommercialTrafficDemand.makeServiceDurationPerCategoryKey(carrierAttributes.selectedStartCategory(), carrierAttributes.modeORvehType(), carrierAttributes.smallScaleCommercialTrafficType()); - } - - //possible new Version by Ricardo - double maxVehicleAvailability = carrier.getCarrierCapabilities().getCarrierVehicles().values().stream().mapToDouble(vehicle -> vehicle.getLatestEndTime() - vehicle.getEarliestStartTime()).max().orElse(0); - int usedTravelTimeBuffer = additionalTravelBufferPerIterationInMinutes * 60; // buffer for the driving time; for unsolved carriers the buffer will be increased over time - for (int j = 0; j < 200; j++) { - GenerateSmallScaleCommercialTrafficDemand.DurationsBounds serviceDurationBounds = generator.getServiceDurationTimeSelector().get(key).sample(); - - for (int i = 0; i < 10; i++) { - int serviceDurationLowerBound = serviceDurationBounds.minDuration(); - int serviceDurationUpperBound = serviceDurationBounds.maxDuration(); - int possibleValue = rnd.nextInt(serviceDurationLowerBound * 60, serviceDurationUpperBound * 60); - // checks if the service duration will not exceed the vehicle availability including the buffer - if (possibleValue + usedTravelTimeBuffer <= maxVehicleAvailability) - return possibleValue; - } - if (j > 100){ - CarrierVehicle carrierVehicleToChange = carrier.getCarrierCapabilities().getCarrierVehicles().values().stream().sorted(Comparator.comparingDouble(vehicle -> vehicle.getLatestEndTime() - vehicle.getEarliestStartTime())).toList().getFirst(); - log.info("Changing vehicle availability for carrier {}. Old maxVehicleAvailability: {}", carrier.getId(), maxVehicleAvailability); - int tourDuration = 0; - int vehicleStartTime = 0; - int vehicleEndTime = 0; - while (tourDuration < maxVehicleAvailability) { - GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration t = generator.getTourDistribution().get(carrierAttributes.smallScaleCommercialTrafficType()).sample(); - vehicleStartTime = t.getVehicleStartTime(); - tourDuration = t.getVehicleTourDuration(); - vehicleEndTime = vehicleStartTime + tourDuration; - } - CarrierVehicle newCarrierVehicle = CarrierVehicle.Builder.newInstance(carrierVehicleToChange.getId(), carrierVehicleToChange.getLinkId(), - carrierVehicleToChange.getType()).setEarliestStart(vehicleStartTime).setLatestEnd(vehicleEndTime).build(); - carrier.getCarrierCapabilities().getCarrierVehicles().remove(carrierVehicleToChange.getId()); - carrier.getCarrierCapabilities().getCarrierVehicles().put(newCarrierVehicle.getId(), newCarrierVehicle); - maxVehicleAvailability = carrier.getCarrierCapabilities().getCarrierVehicles().values().stream().mapToDouble(vehicle -> vehicle.getLatestEndTime() - vehicle.getEarliestStartTime()).max().orElse(0); - log.info("New maxVehicleAvailability: {}", maxVehicleAvailability); - } - } - - throw new RuntimeException("No possible service duration found for employee category '" + carrierAttributes.selectedStartCategory() + "' and mode '" - + carrierAttributes.modeORvehType() + "' in traffic type '" + carrierAttributes.smallScaleCommercialTrafficType() + "'"); - } - /** * Redraws the service-durations of all {@link CarrierService}s of the given {@link Carrier}. */ private void redrawAllServiceDurations(Carrier carrier, GenerateSmallScaleCommercialTrafficDemand.CarrierAttributes carrierAttributes, int additionalTravelBufferPerIterationInMinutes) { for (CarrierService service : carrier.getServices().values()) { - double newServiceDuration = getServiceTimePerStop(carrier, carrierAttributes, additionalTravelBufferPerIterationInMinutes); + double newServiceDuration = generator.getServiceTimePerStop(carrier, carrierAttributes, additionalTravelBufferPerIterationInMinutes); CarrierService redrawnService = CarrierService.Builder.newInstance(service.getId(), service.getLocationLinkId()) .setServiceDuration(newServiceDuration).setServiceStartTimeWindow(service.getServiceStartTimeWindow()).build(); carrier.getServices().put(redrawnService.getId(), redrawnService); @@ -105,7 +56,6 @@ public void tryToSolveAllCarriersCompletely(Scenario scenario, List non for (Carrier nonCompleteSolvedCarrier : nonCompleteSolvedCarriers) { //Delete old plan of carrier nonCompleteSolvedCarrier.clearPlans(); - nonCompleteSolvedCarrier.setSelectedPlan(null); GenerateSmallScaleCommercialTrafficDemand.CarrierAttributes carrierAttributes = generator.getCarrierId2carrierAttributes().get(nonCompleteSolvedCarrier.getId()); // Generate new services. The new service batch should have a smaller sum of serviceDurations than before (or otherwise it will not change anything) @@ -133,4 +83,61 @@ public void tryToSolveAllCarriersCompletely(Scenario scenario, List non } } + /** + * Change the service duration for a given carrier, because the service could not be handled in the last solution. + * + * @param carrier The carrier for which we generate the serviceTime + * @param carrierAttributes attributes of the carrier to generate the service time for. + * @param key key for the service duration + * @param additionalTravelBufferPerIterationInMinutes additional buffer for the travel time + * @return new service duration + */ + @Override + public int changeServiceTimePerStop(Carrier carrier, GenerateSmallScaleCommercialTrafficDemand.CarrierAttributes carrierAttributes, + GenerateSmallScaleCommercialTrafficDemand.ServiceDurationPerCategoryKey key, + int additionalTravelBufferPerIterationInMinutes) { + + double maxVehicleAvailability = carrier.getCarrierCapabilities().getCarrierVehicles().values().stream().mapToDouble(vehicle -> vehicle.getLatestEndTime() - vehicle.getEarliestStartTime()).max().orElse(0); + int usedTravelTimeBuffer = additionalTravelBufferPerIterationInMinutes * 60; // buffer for the driving time; for unsolved carriers the buffer will be increased over time + for (int j = 0; j < 200; j++) { + if (generator.getServiceDurationTimeSelector().get(key) == null) { + System.out.println("key: " + key); + System.out.println(generator.getServiceDurationTimeSelector().keySet()); + throw new RuntimeException("No service duration found for employee category '" + carrierAttributes.selectedStartCategory() + "' and mode '" + + carrierAttributes.modeORvehType() + "' in traffic type '" + carrierAttributes.smallScaleCommercialTrafficType() + "'"); + } + GenerateSmallScaleCommercialTrafficDemand.DurationsBounds serviceDurationBounds = generator.getServiceDurationTimeSelector().get(key).sample(); + + for (int i = 0; i < 10; i++) { + int serviceDurationLowerBound = serviceDurationBounds.minDuration(); + int serviceDurationUpperBound = serviceDurationBounds.maxDuration(); + int possibleValue = rnd.nextInt(serviceDurationLowerBound * 60, serviceDurationUpperBound * 60); + // checks if the service duration will not exceed the vehicle availability including the buffer + if (possibleValue + usedTravelTimeBuffer <= maxVehicleAvailability) + return possibleValue; + } + if (j > 100){ + CarrierVehicle carrierVehicleToChange = carrier.getCarrierCapabilities().getCarrierVehicles().values().stream().sorted(Comparator.comparingDouble(vehicle -> vehicle.getLatestEndTime() - vehicle.getEarliestStartTime())).toList().getFirst(); + log.info("Changing vehicle availability for carrier {}. Old maxVehicleAvailability: {}", carrier.getId(), maxVehicleAvailability); + int tourDuration = 0; + int vehicleStartTime = 0; + int vehicleEndTime = 0; + while (tourDuration < maxVehicleAvailability) { + GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration t = generator.getTourDistribution().get(carrierAttributes.smallScaleCommercialTrafficType()).sample(); + vehicleStartTime = t.getVehicleStartTime(); + tourDuration = t.getVehicleTourDuration(); + vehicleEndTime = vehicleStartTime + tourDuration; + } + CarrierVehicle newCarrierVehicle = CarrierVehicle.Builder.newInstance(carrierVehicleToChange.getId(), carrierVehicleToChange.getLinkId(), + carrierVehicleToChange.getType()).setEarliestStart(vehicleStartTime).setLatestEnd(vehicleEndTime).build(); + carrier.getCarrierCapabilities().getCarrierVehicles().remove(carrierVehicleToChange.getId()); + carrier.getCarrierCapabilities().getCarrierVehicles().put(newCarrierVehicle.getId(), newCarrierVehicle); + maxVehicleAvailability = carrier.getCarrierCapabilities().getCarrierVehicles().values().stream().mapToDouble(vehicle -> vehicle.getLatestEndTime() - vehicle.getEarliestStartTime()).max().orElse(0); + log.info("New maxVehicleAvailability: {}", maxVehicleAvailability); + } + } + + throw new RuntimeException("No possible service duration found for employee category '" + carrierAttributes.selectedStartCategory() + "' and mode '" + + carrierAttributes.modeORvehType() + "' in traffic type '" + carrierAttributes.smallScaleCommercialTrafficType() + "'"); + } } diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java index 553b9abc689..094c2f753f4 100644 --- a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java @@ -481,7 +481,8 @@ private void solveSeparatedVRPs(Scenario originalScenario) throws Exception { // Map the values to the new subcarriers for (Id oldCarrierId : carrierId2subCarrierIds.keySet()) { for (Id newCarrierId : carrierId2subCarrierIds.get(oldCarrierId)) { - carrierId2carrierAttributes.put(newCarrierId, carrierId2carrierAttributes.get(oldCarrierId)); + if (carrierId2carrierAttributes.putIfAbsent(newCarrierId, carrierId2carrierAttributes.get(oldCarrierId)) != null) + throw new Exception("CarrierAttributes already exist for the carrier " + newCarrierId.toString()); } } @@ -679,14 +680,26 @@ public void createCarriers(Scenario scenario, vehicleTypes.add(possibleVehicleType); } - // find a (random) start category with existing employees in this zone Collections.shuffle(odMatrixEntry.possibleStartCategories, rnd); String selectedStartCategory = odMatrixEntry.possibleStartCategories.getFirst(); + // Find a (random) start category with existing employees in this zone + // we start with count = 1 because the first category is already selected, and if this category has employees, we can use it. + // Otherwise, we have to find another category. for (int count = 1; resultingDataPerZone.get(startZone).getDouble(selectedStartCategory) == 0; count++) { - if (count <= odMatrixEntry.possibleStartCategories.size()) - selectedStartCategory = odMatrixEntry.possibleStartCategories.get(rnd.nextInt(odMatrixEntry.possibleStartCategories.size())); - else + if (count < odMatrixEntry.possibleStartCategories.size()) + selectedStartCategory = odMatrixEntry.possibleStartCategories.get(count); + else { + // if no possible start category with employees is found, take a random category of the stop categories, + // the reason that no start category with employees is found is that traffic volume for employees in general is created, + // so that it is possible that we have traffic, although we have no employees in the given start category. + // That's why we exclude Inhabitants as a possible start category. selectedStartCategory = odMatrixEntry.possibleStopCategories.get(rnd.nextInt(odMatrixEntry.possibleStopCategories.size())); + if (selectedStartCategory.equals("Inhabitants")) + selectedStartCategory = odMatrixEntry.possibleStopCategories.get(rnd.nextInt(odMatrixEntry.possibleStopCategories.size())); + if (resultingDataPerZone.get(startZone).getDouble(selectedStartCategory) > 0) + log.warn("No possible start category with employees found for zone {}. Take a random category of the stop categories: {}. The possible start categories are: {}", + startZone, selectedStartCategory, odMatrixEntry.possibleStartCategories); + } } // Generate carrierName @@ -709,11 +722,10 @@ public void createCarriers(Scenario scenario, CarrierAttributes carrierAttributes = new CarrierAttributes(purpose, startZone, selectedStartCategory, modeORvehType, smallScaleCommercialTrafficType, vehicleDepots, odMatrixEntry); - carrierId2carrierAttributes.put(Id.create(carrierName, Carrier.class), carrierAttributes); + if(carrierId2carrierAttributes.putIfAbsent(Id.create(carrierName, Carrier.class), carrierAttributes) != null) + throw new RuntimeException("CarrierAttributes already exist for the carrier " + carrierName); - createNewCarrierAndAddVehicleTypes( - scenario, carrierName, carrierAttributes, - vehicleTypes, numberOfDepots, fleetSize, + createNewCarrierAndAddVehicleTypes(scenario, carrierName, carrierAttributes, vehicleTypes, numberOfDepots, fleetSize, fixedNumberOfVehiclePerTypeAndLocation); // Now Create services for this carrier @@ -731,8 +743,7 @@ public void createCarriers(Scenario scenario, /** * Generates and adds the services for the given carrier. */ - private void createServices(Carrier newCarrier, - CarrierAttributes carrierAttributes) { + private void createServices(Carrier newCarrier, CarrierAttributes carrierAttributes) { log.info("Create services for carrier: {}", newCarrier.getId()); for (String stopZone : odMatrix.getListOfZones()) { int trafficVolumeForOD = Math.round((float)odMatrix.getTripDistributionValue(carrierAttributes.startZone, @@ -745,25 +756,54 @@ private void createServices(Carrier newCarrier, while (resultingDataPerZone.get(stopZone).getDouble(selectedStopCategory) == 0) selectedStopCategory = carrierAttributes.odMatrixEntry.possibleStopCategories.get(rnd.nextInt(carrierAttributes.odMatrixEntry.possibleStopCategories.size())); for (int i = 0; i < numberOfJobs; i++) { - int serviceTimePerStop; - if (carrierAttributes.selectedStartCategory.equals("Inhabitants")){ - CarrierAttributes inhabitantAttributes = new CarrierAttributes(carrierAttributes.purpose, carrierAttributes.startZone, - carrierAttributes.odMatrixEntry.possibleStartCategories.getFirst(), carrierAttributes.modeORvehType, - carrierAttributes.smallScaleCommercialTrafficType, carrierAttributes.vehicleDepots, carrierAttributes.odMatrixEntry); - serviceTimePerStop = unhandledServicesSolution.getServiceTimePerStop(newCarrier, inhabitantAttributes, 0); - - } - else { - serviceTimePerStop = unhandledServicesSolution.getServiceTimePerStop(newCarrier, carrierAttributes, 0); - } + // additionalTravelBufferPerIterationInMinutes is only used for recalculation of the service time if a carrier solution could not handle all services + int serviceTimePerStop = getServiceTimePerStop(newCarrier, carrierAttributes, 0); - TimeWindow serviceTimeWindow = TimeWindow.newInstance(0, - 36 * 3600); // extended time window, so that late tours can handle it + TimeWindow serviceTimeWindow = TimeWindow.newInstance(0, 36 * 3600); // extended time window, so that late tours can handle it createService(newCarrier, carrierAttributes.vehicleDepots, selectedStopCategory, stopZone, serviceTimePerStop, serviceTimeWindow); } } } + /** + * Give a service duration based on the purpose and the trafficType under a given probability + * + * @param carrier The carrier for which the service time should be calculated + * @param carrierAttributes The attributes of the carrier + * @param additionalTravelBufferPerIterationInMinutes Additional travel buffer per recalculation iteration for a carrier in minutes + * @return The service time in seconds + */ + public Integer getServiceTimePerStop(Carrier carrier, GenerateSmallScaleCommercialTrafficDemand.CarrierAttributes carrierAttributes, + int additionalTravelBufferPerIterationInMinutes) { + GenerateSmallScaleCommercialTrafficDemand.ServiceDurationPerCategoryKey key; + // we use the start category for the service time selection because the start category represents the employees + if (carrierAttributes.smallScaleCommercialTrafficType().equals( + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.commercialPersonTraffic.toString())) { + if (!carrierAttributes.odMatrixEntry().possibleStartCategories.contains(carrierAttributes.selectedStartCategory())) + key = GenerateSmallScaleCommercialTrafficDemand.makeServiceDurationPerCategoryKey(carrierAttributes.odMatrixEntry().possibleStartCategories.get(rnd.nextInt(carrierAttributes.odMatrixEntry().possibleStartCategories.size())), null, carrierAttributes.smallScaleCommercialTrafficType()); + else + key = GenerateSmallScaleCommercialTrafficDemand.makeServiceDurationPerCategoryKey(carrierAttributes.selectedStartCategory(), null, + carrierAttributes.smallScaleCommercialTrafficType()); + } + else if (carrierAttributes.smallScaleCommercialTrafficType().equals( + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString())) { + key = GenerateSmallScaleCommercialTrafficDemand.makeServiceDurationPerCategoryKey(carrierAttributes.selectedStartCategory(), + carrierAttributes.modeORvehType(), carrierAttributes.smallScaleCommercialTrafficType()); + } else { + throw new RuntimeException("Unknown traffic type: " + carrierAttributes.smallScaleCommercialTrafficType()); + } + // additionalTravelBufferPerIterationInMinutes is only used for recalculation of the service time if a carrier solution could not handle all services + if (additionalTravelBufferPerIterationInMinutes == 0) { + GenerateSmallScaleCommercialTrafficDemand.DurationsBounds serviceDurationBounds = serviceDurationTimeSelector.get(key).sample(); + + int serviceDurationLowerBound = serviceDurationBounds.minDuration(); + int serviceDurationUpperBound = serviceDurationBounds.maxDuration(); + return rnd.nextInt(serviceDurationLowerBound * 60, serviceDurationUpperBound * 60); + } else { + return unhandledServicesSolution.changeServiceTimePerStop(carrier, carrierAttributes, key, additionalTravelBufferPerIterationInMinutes); + } + } + /** * Adds a service with the given attributes to the carrier. */ @@ -814,7 +854,6 @@ private void createNewCarrierAndAddVehicleTypes(Scenario scenario, String carrie for (String singleDepot : carrierAttributes.vehicleDepots) { GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration t = tourDistribution.get(carrierAttributes.smallScaleCommercialTrafficType).sample(); - int vehicleStartTime = t.getVehicleStartTime(); int tourDuration = t.getVehicleTourDuration(); int vehicleEndTime = vehicleStartTime + tourDuration; diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/UnhandledServicesSolution.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/UnhandledServicesSolution.java index e5db51e8557..c65c75deee7 100644 --- a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/UnhandledServicesSolution.java +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/UnhandledServicesSolution.java @@ -17,17 +17,6 @@ public interface UnhandledServicesSolution { */ List createListOfCarrierWithUnhandledJobs(Scenario scenario); - /** - * Give a service duration based on the purpose and the trafficType under a given probability - * - * @param carrier The carrier for which we generate the serviceTime - * @param carrierAttributes attributes of the carrier to generate the service time for. - * selectedStartCategory: the category of the employee - * @param additionalTravelBufferPerIterationInMinutes additional buffer for the travel time - * @return the service duration - */ - int getServiceTimePerStop(Carrier carrier, GenerateSmallScaleCommercialTrafficDemand.CarrierAttributes carrierAttributes, int additionalTravelBufferPerIterationInMinutes); - /** * * Checks and recalculates plans of carriers, which did not serve all services. @@ -36,4 +25,15 @@ public interface UnhandledServicesSolution { * @param nonCompleteSolvedCarriers List of carriers, that are not solved. Can be obtained by {@link UnhandledServicesSolution#createListOfCarrierWithUnhandledJobs(Scenario)} */ void tryToSolveAllCarriersCompletely(Scenario scenario, List nonCompleteSolvedCarriers); + + /** + * Change the service duration for a given carrier, because the service could not be handled in the last solution. + * + * @param carrier The carrier for which we generate the serviceTime + * @param carrierAttributes attributes of the carrier to generate the service time for. + * @param key key for the service duration + * @param additionalTravelBufferPerIterationInMinutes additional buffer for the travel time + * @return new service duration + */ + int changeServiceTimePerStop(Carrier carrier, GenerateSmallScaleCommercialTrafficDemand.CarrierAttributes carrierAttributes, GenerateSmallScaleCommercialTrafficDemand.ServiceDurationPerCategoryKey key, int additionalTravelBufferPerIterationInMinutes); } diff --git a/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/RunGenerateSmallScaleCommercialTrafficTest.java b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/RunGenerateSmallScaleCommercialTrafficTest.java index 7aeefbf5925..999ea549ccf 100644 --- a/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/RunGenerateSmallScaleCommercialTrafficTest.java +++ b/contribs/small-scale-traffic-generation/src/test/java/org/matsim/smallScaleCommercialTrafficGeneration/RunGenerateSmallScaleCommercialTrafficTest.java @@ -73,7 +73,7 @@ void testMainRunAndResults() { String sample = "0.1"; String jspritIterations = "2"; String creationOption = "createNewCarrierFile"; - String smallScaleCommercialTrafficType = "commercialPersonTraffic"; + String smallScaleCommercialTrafficType = "completeSmallScaleCommercialTraffic"; String zoneShapeFileName = utils.getPackageInputDirectory() + "/shp/testZones.shp"; String zoneShapeFileNameColumn = "name"; String shapeCRS = "EPSG:4326"; diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/TrafficVolume_goodsTraffic_startPerZone_10pt.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/TrafficVolume_goodsTraffic_startPerZone_10pt.csv new file mode 100644 index 00000000000..bb4a958810a --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/TrafficVolume_goodsTraffic_startPerZone_10pt.csv @@ -0,0 +1,16 @@ +zoneID mode/vehType 1 2 3 4 5 +area1 vehTyp3 0 1 4 4 3 +area2 vehTyp4 0 0 1 4 1 +area3 vehTyp5 0 0 1 3 1 +area1 vehTyp4 0 0 1 1 0 +area2 vehTyp5 0 0 3 21 9 +area1 vehTyp1 1 2 10 4 3 +area2 vehTyp2 0 0 2 3 7 +area3 vehTyp3 0 0 1 2 1 +area1 vehTyp2 0 0 2 1 2 +area2 vehTyp3 0 1 4 13 8 +area3 vehTyp4 0 0 0 1 0 +area3 vehTyp1 0 0 2 1 1 +area2 vehTyp1 1 2 11 10 9 +area3 vehTyp2 0 0 0 0 1 +area1 vehTyp5 0 0 3 7 3 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/TrafficVolume_goodsTraffic_stopPerZone_10pt.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/TrafficVolume_goodsTraffic_stopPerZone_10pt.csv new file mode 100644 index 00000000000..8eacf8fd4d5 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/TrafficVolume_goodsTraffic_stopPerZone_10pt.csv @@ -0,0 +1,16 @@ +zoneID mode/vehType 1 2 3 4 5 +area1 vehTyp3 0 1 3 7 1 +area2 vehTyp4 0 0 1 2 0 +area3 vehTyp5 0 0 0 3 0 +area1 vehTyp4 0 0 0 2 0 +area2 vehTyp5 0 1 3 12 1 +area1 vehTyp1 1 2 7 5 1 +area2 vehTyp2 0 0 1 2 1 +area3 vehTyp3 0 0 1 1 0 +area1 vehTyp2 0 0 1 2 1 +area2 vehTyp3 0 1 3 7 1 +area3 vehTyp4 0 0 0 0 0 +area3 vehTyp1 0 0 2 1 0 +area2 vehTyp1 1 2 9 5 1 +area3 vehTyp2 0 0 0 0 0 +area1 vehTyp5 0 1 2 13 1 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose1.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose1.csv new file mode 100644 index 00000000000..cc8a668c7b8 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose1.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 1 1 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose2.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose2.csv new file mode 100644 index 00000000000..de59ab8889f --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose2.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 1 0 0 +area2 1 2 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose3.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose3.csv new file mode 100644 index 00000000000..26a96bff6fd --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose3.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 3 3 0 +area2 4 5 1 +area3 0 1 1 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose4.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose4.csv new file mode 100644 index 00000000000..12ec403fccd --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose4.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 2 1 0 +area2 3 4 0 +area3 0 0 1 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose5.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose5.csv new file mode 100644 index 00000000000..7e6891a86a5 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose5.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 1 0 0 +area2 0 1 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose6.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose6.csv new file mode 100644 index 00000000000..4f394b5d502 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp1_purpose6.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 0 0 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose1.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose1.csv new file mode 100644 index 00000000000..4f394b5d502 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose1.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 0 0 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose2.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose2.csv new file mode 100644 index 00000000000..4f394b5d502 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose2.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 0 0 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose3.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose3.csv new file mode 100644 index 00000000000..2bf59089a18 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose3.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 1 1 0 +area2 0 0 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose4.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose4.csv new file mode 100644 index 00000000000..0ae1ae162f4 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose4.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 1 0 +area2 2 1 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose5.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose5.csv new file mode 100644 index 00000000000..c53d46eaaae --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose5.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 0 0 0 +area3 1 1 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose6.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose6.csv new file mode 100644 index 00000000000..2bf59089a18 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp2_purpose6.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 1 1 0 +area2 0 0 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose1.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose1.csv new file mode 100644 index 00000000000..4f394b5d502 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose1.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 0 0 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose2.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose2.csv new file mode 100644 index 00000000000..cc8a668c7b8 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose2.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 1 1 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose3.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose3.csv new file mode 100644 index 00000000000..72ffd6bb344 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose3.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 1 2 0 +area2 2 1 0 +area3 0 0 1 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose4.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose4.csv new file mode 100644 index 00000000000..4f435ce0431 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose4.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 1 1 0 +area2 5 5 1 +area3 1 1 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose5.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose5.csv new file mode 100644 index 00000000000..cc8a668c7b8 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose5.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 1 1 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose6.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose6.csv new file mode 100644 index 00000000000..8b670f48efc --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp3_purpose6.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 1 2 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose1.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose1.csv new file mode 100644 index 00000000000..4f394b5d502 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose1.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 0 0 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose2.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose2.csv new file mode 100644 index 00000000000..4f394b5d502 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose2.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 0 0 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose3.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose3.csv new file mode 100644 index 00000000000..89e40cb7518 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose3.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 1 0 +area2 0 0 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose4.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose4.csv new file mode 100644 index 00000000000..9a8d21f3eeb --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose4.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 1 1 0 +area3 1 1 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose5.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose5.csv new file mode 100644 index 00000000000..4f394b5d502 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose5.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 0 0 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose6.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose6.csv new file mode 100644 index 00000000000..7e6891a86a5 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp4_purpose6.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 1 0 0 +area2 0 1 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose1.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose1.csv new file mode 100644 index 00000000000..4f394b5d502 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose1.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 0 0 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose2.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose2.csv new file mode 100644 index 00000000000..7e6891a86a5 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose2.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 1 0 0 +area2 0 1 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose3.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose3.csv new file mode 100644 index 00000000000..dae6ecd671c --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose3.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 2 0 +area2 2 1 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose4.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose4.csv new file mode 100644 index 00000000000..ab520bdffca --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose4.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 3 3 1 +area2 9 8 2 +area3 1 1 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose5.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose5.csv new file mode 100644 index 00000000000..2bf59089a18 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose5.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 1 1 0 +area2 0 0 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose6.csv b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose6.csv new file mode 100644 index 00000000000..4f394b5d502 --- /dev/null +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/calculatedData/odMatrix_goodsTraffic_vehTyp5_purpose6.csv @@ -0,0 +1,4 @@ +O/D area1 area2 area3 +area1 0 0 0 +area2 0 0 0 +area3 0 0 0 diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/existingModels/exampleServiceCarrier/vehicleTypes.xml.gz b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/existingModels/exampleServiceCarrier/vehicleTypes.xml.gz index e9f770072c4..1e5c09a053f 100644 Binary files a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/existingModels/exampleServiceCarrier/vehicleTypes.xml.gz and b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/existingModels/exampleServiceCarrier/vehicleTypes.xml.gz differ diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/existingModels/exampleShipmentCarrier/vehicleTypes.xml.gz b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/existingModels/exampleShipmentCarrier/vehicleTypes.xml.gz index e9f770072c4..b110aa96838 100644 Binary files a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/existingModels/exampleShipmentCarrier/vehicleTypes.xml.gz and b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/existingModels/exampleShipmentCarrier/vehicleTypes.xml.gz differ diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/test.output_events.xml.gz b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/test.output_events.xml.gz index 4cac3132da0..8feaf9c0273 100644 Binary files a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/test.output_events.xml.gz and b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/test.output_events.xml.gz differ diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/vehicleTypes.xml b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/vehicleTypes.xml index efe44ed5710..2b11da8b0cb 100644 --- a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/vehicleTypes.xml +++ b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/vehicleTypes.xml @@ -5,20 +5,22 @@ Golf 1.4 Trendline - - - + + - diesel + PASSENGER_CAR + petrol + average + average - + - 0.00948 - 0.00948 + 0.0049 + 0.0049 @@ -26,21 +28,22 @@ - - - Heavy Vehicle 26t - + - + VW Caddy 2.0 Maxi TDI + + - 0.0 - diesel + PASSENGER_CAR + diesel + average + average - + 0.0049 0.0049 @@ -51,180 +54,178 @@ - - - Light Vehicle 7.5t - + - + Mercedes 313 CDI + + + LIGHT_COMMERCIAL_VEHICLE diesel + average + average - + 0.0049 0.0049 - + + - - - Medium Vehicle 18t - - - + Mercedes 313 CDI + + + LIGHT_COMMERCIAL_VEHICLE diesel + average + average - + 0.0049 0.0049 - + - - - Mercedes 313 CDI - + - + Light Vehicle 7.5t + + + LIGHT_COMMERCIAL_VEHICLE diesel + average + average - + 0.0049 0.0049 - + + - - - VW Caddy 2.0 Maxi TDI - - - + Medium Vehicle 18t + + + HEAVY_GOODS_VEHICLE diesel + average + average - + - 0.00948 - 0.00948 + 0.0049 + 0.0049 - + - - - - Heavy Vehicle 26t - + - + Medium Vehicle 18t + + + HEAVY_GOODS_VEHICLE diesel + average + average - - + + + 0.0049 + 0.0049 + - + - Heavy Vehicle 40t - - - - + + + + HEAVY_GOODS_VEHICLE diesel + average + average - - - - - - - - - - Light Vehicle 7.5t Frozen - - - - - - - diesel + 0.00559 + 0.00559 - - - - + - - - + + Waste collection vehicle - - + + HEAVY_GOODS_VEHICLE + diesel + average + average 0.5 - 60.0 - diesel + 0.0006 - + + 0.0 + 0.0 + + - \ No newline at end of file + diff --git a/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkConverter.java b/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkConverter.java index b563e1325d4..b384b50d8d0 100644 --- a/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkConverter.java +++ b/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkConverter.java @@ -246,7 +246,11 @@ public SumoNetworkHandler convert(Network network) throws ParserConfigurationExc Map linkProperties = LinkProperties.createLinkProperties(); // add additional service tag - linkProperties.put(OsmTags.SERVICE, new LinkProperties(LinkProperties.LEVEL_LIVING_STREET, 1, 15 / 3.6, 450, false)); + linkProperties.put(OsmTags.SERVICE, new LinkProperties(LinkProperties.LEVEL_PATH, 1, 15 / 3.6, 450, false)); + linkProperties.put(OsmTags.PATH, new LinkProperties(LinkProperties.LEVEL_PATH, 1, 15 / 3.6, 300, false)); + + // This is for bikes + linkProperties.put(OsmTags.CYCLEWAY, new LinkProperties(LinkProperties.LEVEL_PATH, 1, 15 / 3.6, 300, false)); for (SumoNetworkHandler.Edge edge : sumoHandler.edges.values()) { diff --git a/contribs/vsp/src/test/java/playground/vsp/cadyts/marginals/ModalDistanceAndCountsCadytsIT.java b/contribs/vsp/src/test/java/playground/vsp/cadyts/marginals/ModalDistanceAndCountsCadytsIT.java index dbdb804cb9b..3f1ed342aa5 100644 --- a/contribs/vsp/src/test/java/playground/vsp/cadyts/marginals/ModalDistanceAndCountsCadytsIT.java +++ b/contribs/vsp/src/test/java/playground/vsp/cadyts/marginals/ModalDistanceAndCountsCadytsIT.java @@ -1,5 +1,4 @@ package playground.vsp.cadyts.marginals; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -63,13 +62,14 @@ private static DistanceDistribution createDistanceDistribution() { return result; } - private Config createConfig() { + private Config createConfig(String outputSuffix) { Config config = ConfigUtils.createConfig(); String[] modes = new String[]{TransportMode.car, TransportMode.bike}; config.routing().setNetworkRouteConsistencyCheck(RoutingConfigGroup.NetworkRouteConsistencyCheck.disable); - config.controller().setOutputDirectory(this.utils.getOutputDirectory()); + String outputDirectory = this.utils.getOutputDirectory(); + config.controller().setOutputDirectory(outputDirectory.substring(0,outputDirectory.length()-1)+outputSuffix); config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); config.controller().setLastIteration(40); @@ -244,7 +244,7 @@ private static Plan createPlan(String mode, String endLink, Network network, Pop @MethodSource("arguments") void test(double countsWeight, double modalDistanceWeight) { - Config config = createConfig(); + Config config = createConfig(countsWeight+"_"+modalDistanceWeight); CadytsConfigGroup cadytsConfigGroup = new CadytsConfigGroup(); cadytsConfigGroup.setWriteAnalysisFile(true); config.addModule(cadytsConfigGroup); diff --git a/examples/scenarios/emissions-sampleScenario/testv2_Vehv2/sample_emissionVehicles_v2.xml b/examples/scenarios/emissions-sampleScenario/testv2_Vehv2/sample_emissionVehicles_v2.xml index 566a49585bd..36079e8d101 100644 --- a/examples/scenarios/emissions-sampleScenario/testv2_Vehv2/sample_emissionVehicles_v2.xml +++ b/examples/scenarios/emissions-sampleScenario/testv2_Vehv2/sample_emissionVehicles_v2.xml @@ -14,6 +14,7 @@ average + @@ -27,6 +28,7 @@ PC-P-Euro-1 + @@ -40,6 +42,7 @@ PC-D-Euro-3 + @@ -56,6 +59,7 @@ average + @@ -66,4 +70,4 @@ - \ No newline at end of file + diff --git a/examples/scenarios/freight-chessboard-9x9/vehicleTypes.xml b/examples/scenarios/freight-chessboard-9x9/vehicleTypes.xml index 27a7d8e1255..df4c6c7c95f 100644 --- a/examples/scenarios/freight-chessboard-9x9/vehicleTypes.xml +++ b/examples/scenarios/freight-chessboard-9x9/vehicleTypes.xml @@ -10,11 +10,13 @@ A heavy truck + A light truck + - \ No newline at end of file + diff --git a/matsim/src/main/java/ch/sbb/matsim/routing/pt/raptor/SwissRailRaptorCore.java b/matsim/src/main/java/ch/sbb/matsim/routing/pt/raptor/SwissRailRaptorCore.java index d6c059897d8..521c237d412 100644 --- a/matsim/src/main/java/ch/sbb/matsim/routing/pt/raptor/SwissRailRaptorCore.java +++ b/matsim/src/main/java/ch/sbb/matsim/routing/pt/raptor/SwissRailRaptorCore.java @@ -38,15 +38,7 @@ import org.matsim.pt.transitSchedule.api.TransitStopFacility; import org.matsim.vehicles.Vehicle; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.BitSet; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; +import java.util.*; /** * The actual RAPTOR implementation, based on Delling et al, Round-Based Public Transit Routing. @@ -118,7 +110,8 @@ public RaptorRoute calcLeastCostRoute(double depTime, Facility fromFacility, Fac reset(); CachingTransferProvider transferProvider = this.data.new CachingTransferProvider(); - Map destinationStops = new HashMap<>(); + // Using a LinkedHashMap instead of a regular HashMap here is necessary to have a deterministic behaviour + Map destinationStops = new LinkedHashMap<>(); // go through all egressStops; check if already in destinationStops; if so, check if current cost is smaller; if so, then replace. This can // presumably happen when the same stop can be reached at lower cost by a different egress mode. (*) @@ -141,7 +134,8 @@ public RaptorRoute calcLeastCostRoute(double depTime, Facility fromFacility, Fac } // same as (*) for access stops: - Map initialStops = new HashMap<>(); + // Also, using a LinkedHashMap instead of a regular HashMap here is necessary to have a deterministic behaviour + Map initialStops = new LinkedHashMap<>(); for (InitialStop accessStop : accessStops) { InitialStop alternative = initialStops.get(accessStop.stop); if (alternative == null || accessStop.accessCost < alternative.accessCost) { @@ -833,7 +827,7 @@ private void handleTransfers(boolean strict, RaptorParameters raptorParams, Cach final int firstTransferIndex; final int lastTransferIndex; final RTransfer[] transfers; - + if (!useAdaptiveTransferCalculation) { // efficient lookup from the precomputed transfer candidates transfers = this.data.transfers; diff --git a/matsim/src/main/java/ch/sbb/matsim/routing/pt/raptor/SwissRailRaptorData.java b/matsim/src/main/java/ch/sbb/matsim/routing/pt/raptor/SwissRailRaptorData.java index a02b58c7b35..e4d4f28a1c5 100644 --- a/matsim/src/main/java/ch/sbb/matsim/routing/pt/raptor/SwissRailRaptorData.java +++ b/matsim/src/main/java/ch/sbb/matsim/routing/pt/raptor/SwissRailRaptorData.java @@ -20,17 +20,7 @@ package ch.sbb.matsim.routing.pt.raptor; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -148,7 +138,8 @@ public static SwissRailRaptorData create(TransitSchedule schedule, @Nullable Veh // enumerate TransitStopFacilities along their usage in transit routes to (hopefully) achieve a better memory locality // well, I'm not even sure how often we'll need the transit stop facilities, likely we'll use RouteStops more often Map stopFacilityIndices = new HashMap<>((int) (schedule.getFacilities().size() * 1.5)); - Map routeStopsPerStopFacility = new HashMap<>(); + // Using a LinkedHashMap instead of a regular HashMap here is necessary to have a deterministic behaviour + Map routeStopsPerStopFacility = new LinkedHashMap<>(); boolean useModeMapping = staticConfig.isUseModeMappingForPassengers(); for (TransitLine line : schedule.getTransitLines().values()) { diff --git a/matsim/src/main/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysis.java b/matsim/src/main/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysis.java index 222b2d825af..370c8567348 100644 --- a/matsim/src/main/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysis.java +++ b/matsim/src/main/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysis.java @@ -42,24 +42,26 @@ import org.matsim.vehicles.Vehicles; import java.io.IOException; +import java.net.URL; +import java.nio.file.Path; import java.util.*; -import java.util.function.BinaryOperator; import java.util.stream.Collectors; /** * Processes events to create a csv file with passenger volumes, delays and similar information for each stop to stop * segment of a pt {@link org.matsim.pt.transitSchedule.api.Departure}. - * + *

* This class is entirely based on events. In case simulated pt should deviate from the * {@link org.matsim.pt.transitSchedule.api.TransitSchedule} this class provides data on what the simulation really gave * ignoring the TransitSchedule. - * - * Currently there are no integrity checks, if the sequence of events is wrong or an event is missing, this class might + *

+ * Currently, there are no integrity checks, if the sequence of events is wrong or an event is missing, this class might * silently produce invalid output. * This class was intended to be run after the last iteration and the simulation has finished and no preconditions were * taken for TransitVehicle fleets which might change over the course of iterations (e.g. minibus). So running this * class as an EventsListener during the simulation might give wrong results and might need work to get the transit - * vehicles updated before mobsim in each iteration. + * vehicles updated before mobsim in each iteration. Still it could be useful to run in each iteration in special cases, + * such as the minibus contrib. * * @author vsp-gleich */ @@ -70,10 +72,16 @@ public class PtStop2StopAnalysis implements TransitDriverStartsEventHandler, Veh private final Vehicles transitVehicles; // for vehicle capacity private final Map, PtVehicleData> transitVehicle2temporaryVehicleData = new HashMap<>(); private final List stop2StopEntriesForEachDeparture; // the output + private final double sampleUpscaleFactor; private static final Logger log = LogManager.getLogger(PtStop2StopAnalysis.class); - public PtStop2StopAnalysis(Vehicles transitVehicles) { + /** + * @param transitVehicles needed to look up vehicle capacity + * @param sampleUpscaleFactor : factor to scale up output passenger volumes to 100% + */ + public PtStop2StopAnalysis(Vehicles transitVehicles, double sampleUpscaleFactor) { this.transitVehicles = transitVehicles; + this.sampleUpscaleFactor = sampleUpscaleFactor; // set initial capacity to rough estimate of 30 entries by vehicle (should be sufficient) stop2StopEntriesForEachDeparture = new ArrayList<>(transitVehicles.getVehicles().size() * 30); } @@ -95,7 +103,7 @@ public void handleEvent(TransitDriverStartsEvent event) { public void handleEvent(VehicleArrivesAtFacilityEvent event) { PtVehicleData ptVehicleData = transitVehicle2temporaryVehicleData.get(event.getVehicleId()); if (ptVehicleData == null) { - log.error("Encountered a VehicleArrivesAtFacilityEvent without a previous TransitDriverStartsEvent for vehicle " + event.getVehicleId() + " at facility " + event.getFacilityId() + " at time " + event.getTime() + ". This should not happen, this analysis might fail subsequently."); + log.error("Encountered a VehicleArrivesAtFacilityEvent without a previous TransitDriverStartsEvent for vehicle {} at facility {} at time {}. This should not happen, this analysis might fail subsequently.", event.getVehicleId(), event.getFacilityId(), event.getTime()); } else { ptVehicleData.lastVehicleArrivesAtFacilityEvent = event; } @@ -108,16 +116,17 @@ public void handleEvent(VehicleArrivesAtFacilityEvent event) { public void handleEvent(VehicleDepartsAtFacilityEvent event) { PtVehicleData ptVehicleData = transitVehicle2temporaryVehicleData.get(event.getVehicleId()); if (ptVehicleData == null) { - log.error("Encountered a VehicleDepartsAtFacilityEvent without a previous TransitDriverStartsEvent for vehicle " + event.getVehicleId() + " at facility " + event.getFacilityId() + " at time " + event.getTime() + ". This should not happen, this analysis might fail subsequently."); + log.error("Encountered a VehicleDepartsAtFacilityEvent without a previous TransitDriverStartsEvent for vehicle {} at facility {} at time {}. This should not happen, this analysis might fail subsequently.", event.getVehicleId(), event.getFacilityId(), event.getTime()); } else { // produce output entry - stop2StopEntriesForEachDeparture.add(new Stop2StopEntry(ptVehicleData.transitLineId, - ptVehicleData.transitRouteId, ptVehicleData.departureId, event.getFacilityId(), - ptVehicleData.stopSequenceCounter, ptVehicleData.lastStopId, - ptVehicleData.lastVehicleArrivesAtFacilityEvent.getTime() - ptVehicleData.lastVehicleArrivesAtFacilityEvent.getDelay(), - ptVehicleData.lastVehicleArrivesAtFacilityEvent.getDelay(), event.getTime() - event.getDelay(), - event.getDelay(), ptVehicleData.currentPax, ptVehicleData.totalVehicleCapacity, - ptVehicleData.alightings, ptVehicleData.boardings, ptVehicleData.linksTravelledOnSincePreviousStop)); + stop2StopEntriesForEachDeparture.add(new Stop2StopEntry(ptVehicleData.transitLineId, + ptVehicleData.transitRouteId, ptVehicleData.departureId, event.getFacilityId(), + ptVehicleData.stopSequenceCounter, ptVehicleData.lastStopId, + ptVehicleData.lastVehicleArrivesAtFacilityEvent.getTime() - ptVehicleData.lastVehicleArrivesAtFacilityEvent.getDelay(), + ptVehicleData.lastVehicleArrivesAtFacilityEvent.getDelay(), event.getTime() - event.getDelay(), + event.getDelay(), ptVehicleData.currentPax * sampleUpscaleFactor, ptVehicleData.totalVehicleCapacity, + ptVehicleData.alightings * sampleUpscaleFactor, ptVehicleData.boardings * sampleUpscaleFactor, + List.copyOf(ptVehicleData.linksTravelledOnSincePreviousStop))); // calculate number of passengers at departure // (the Stop2StopEntry before needed the number of passengers at arrival so do not move this up!) ptVehicleData.currentPax = ptVehicleData.currentPax - ptVehicleData.alightings + ptVehicleData.boardings; @@ -167,8 +176,8 @@ public void handleEvent(PersonLeavesVehicleEvent event) { @Override public void reset(int iteration) { - if(transitVehicle2temporaryVehicleData.size() > 0) { - log.warn(transitVehicle2temporaryVehicleData.size() + " transit vehicles did not finish service in the last iteration."); + if(!transitVehicle2temporaryVehicleData.isEmpty()) { + log.warn("{} transit vehicles did not finish service in the last iteration.", transitVehicle2temporaryVehicleData.size()); } transitVehicle2temporaryVehicleData.clear(); stop2StopEntriesForEachDeparture.clear(); @@ -225,132 +234,48 @@ private PtVehicleData(Id transitLineId, Id transitRou } } - /** - * output data structure - */ - static final class Stop2StopEntry { - final Id transitLineId;// for aggregation -> set null or leave out and use Map lineId -> Stop2StopEntry? - final Id transitRouteId; - final Id departureId; - final Id stopId; - final int stopSequence; - final Id stopPreviousId; - final double arrivalTimeScheduled; - final double arrivalDelay; - final double departureTimeScheduled; - final double departureDelay; - final int passengersAtArrival; - final double totalVehicleCapacity; - final int passengersAlighting; - final int passengersBoarding; - final List> linkIdsSincePreviousStop; - - Stop2StopEntry(Id transitLineId, Id transitRouteId, - Id departureId, Id stopId, int stopSequence, - Id stopPreviousId, double arrivalTimeScheduled, double arrivalDelay, - double departureTimeScheduled, double departureDelay, int passengersAtArrival, - double totalVehicleCapacity, int passengersAlighting, int passengersBoarding, - List> linkIdsSincePreviousStop) { - this.transitLineId = transitLineId; - this.transitRouteId = transitRouteId; - this.departureId = departureId; - this.stopId = stopId; - this.stopSequence = stopSequence; - this.stopPreviousId = stopPreviousId; - this.arrivalTimeScheduled = arrivalTimeScheduled; - this.arrivalDelay = arrivalDelay; - this.departureTimeScheduled = departureTimeScheduled; - this.departureDelay = departureDelay; - this.passengersAtArrival = passengersAtArrival; - this.totalVehicleCapacity = totalVehicleCapacity; - this.passengersAlighting = passengersAlighting; - this.passengersBoarding = passengersBoarding; - this.linkIdsSincePreviousStop = List.copyOf(linkIdsSincePreviousStop); - } - - // getter for usage of standard Comparator implementations below and more - public Id getTransitLineId() { - return transitLineId; - } - - public Id getTransitRouteId() { - return transitRouteId; - } - - public Id getDepartureId() { - return departureId; - } - - public Id getStopId() { - return stopId; - } - - public int getStopSequence() { - return stopSequence; - } - - public Id getStopPreviousId() { - return stopPreviousId; - } - - public double getArrivalTimeScheduled() { - return arrivalTimeScheduled; - } - - public double getArrivalDelay() { - return arrivalDelay; - } - - public double getDepartureTimeScheduled() { - return departureTimeScheduled; - } - - public double getDepartureDelay() { - return departureDelay; - } - - public int getPassengersAtArrival() { - return passengersAtArrival; - } - - public double getTotalVehicleCapacity() { - return totalVehicleCapacity; - } - - public int getPassengersAlighting() { - return passengersAlighting; - } - - public int getPassengersBoarding() { - return passengersBoarding; - } - - public List> getLinkIdsSincePreviousStop() { - return linkIdsSincePreviousStop; - } - } + /** + * output data structure + * + * @param transitLineId for aggregation -> set null or leave out and use Map lineId -> Stop2StopEntry? + */ + record Stop2StopEntry(Id transitLineId, Id transitRouteId, Id departureId, Id stopId, + int stopSequence, Id stopPreviousId, double arrivalTimeScheduled, double arrivalDelay, + double departureTimeScheduled, double departureDelay, double passengersAtArrival, double totalVehicleCapacity, + double passengersAlighting, double passengersBoarding, List> linkIdsSincePreviousStop) {} static final String[] HEADER = {"transitLine", "transitRoute", "departure", "stop", "stopSequence", "stopPrevious", "arrivalTimeScheduled", "arrivalDelay", "departureTimeScheduled", "departureDelay", "passengersAtArrival", "totalVehicleCapacity", "passengersAlighting", "passengersBoarding", "linkIdsSincePreviousStop"}; - public static Comparator stop2StopEntryByTransitLineComparator = - Comparator.nullsLast(Comparator.comparing(Stop2StopEntry::getTransitLineId)); - public static Comparator stop2StopEntryByTransitRouteComparator = - Comparator.nullsLast(Comparator.comparing(Stop2StopEntry::getTransitRouteId)); - public static Comparator stop2StopEntryByDepartureComparator = - Comparator.nullsLast(Comparator.comparing(Stop2StopEntry::getDepartureId)); - public static Comparator stop2StopEntryByStopSequenceComparator = - Comparator.nullsLast(Comparator.comparing(Stop2StopEntry::getStopSequence)); + static Comparator stop2StopEntryByTransitLineComparator = + Comparator.nullsLast(Comparator.comparing(Stop2StopEntry::transitLineId)); + static Comparator stop2StopEntryByTransitRouteComparator = + Comparator.nullsLast(Comparator.comparing(Stop2StopEntry::transitRouteId)); + static Comparator stop2StopEntryByDepartureComparator = + Comparator.nullsLast(Comparator.comparing(Stop2StopEntry::departureId)); + static Comparator stop2StopEntryByStopSequenceComparator = + Comparator.nullsLast(Comparator.comparing(Stop2StopEntry::stopSequence)); + + public void writeStop2StopEntriesByDepartureCsv(String fileName, String columnSeparator, String listSeparatorInsideColumn) { + writeStop2StopEntriesByDepartureCsv(IOUtils.getFileUrl(fileName), columnSeparator, listSeparatorInsideColumn); + } + + public void writeStop2StopEntriesByDepartureCsv(Path path, String columnSeparator, String listSeparatorInsideColumn) { + writeStop2StopEntriesByDepartureCsv(IOUtils.getFileUrl(path.toString()), columnSeparator, listSeparatorInsideColumn); + } - public void writeStop2StopEntriesByDepartureCsv(String fileName, String columnSeparator, String listSeparatorInsideColumn) { + public void writeStop2StopEntriesByDepartureCsv(URL url, String columnSeparator, String listSeparatorInsideColumn) { stop2StopEntriesForEachDeparture.sort(stop2StopEntryByTransitLineComparator. thenComparing(stop2StopEntryByTransitRouteComparator). thenComparing(stop2StopEntryByDepartureComparator). thenComparing(stop2StopEntryByStopSequenceComparator)); - try (CSVPrinter printer = new CSVPrinter(IOUtils.getBufferedWriter(fileName), - CSVFormat.DEFAULT.withDelimiter(columnSeparator.charAt(0)).withHeader(HEADER)) + try (CSVPrinter printer = new CSVPrinter(IOUtils.getBufferedWriter(url), + CSVFormat.Builder.create() + .setDelimiter(columnSeparator) + .setHeader(HEADER) + .build()) ) { for (Stop2StopEntry entry : stop2StopEntriesForEachDeparture) { printer.print(entry.transitLineId); @@ -367,45 +292,15 @@ public void writeStop2StopEntriesByDepartureCsv(String fileName, String columnSe printer.print(entry.totalVehicleCapacity); printer.print(entry.passengersAlighting); printer.print(entry.passengersBoarding); - printer.print(entry.linkIdsSincePreviousStop.stream().map(id -> id.toString()).collect(Collectors.joining(listSeparatorInsideColumn))); + printer.print(entry.linkIdsSincePreviousStop.stream().map(Object::toString).collect(Collectors.joining(listSeparatorInsideColumn))); printer.println(); } } catch (IOException e) { - e.printStackTrace(); + log.error(e); } } - public List getStop2StopEntriesByDeparture () { + List getStop2StopEntriesByDeparture () { return List.copyOf(stop2StopEntriesForEachDeparture); } - - static final class Stop2StopAggregation { - - private final int departures; - private final long passengers; - private final double totalVehicleCapacity; - - Stop2StopAggregation (int departures, long passengers, double totalVehicleCapacity) { - this.departures = departures; - this.passengers = passengers; - this.totalVehicleCapacity = totalVehicleCapacity; - } - - public int getDepartures() { - return departures; - } - - public long getPassengers() { - return passengers; - } - - public double getTotalVehicleCapacity() { - return totalVehicleCapacity; - } - } - - public static BinaryOperator aggregateStop2StopAggregations() { - return (entry1, entry2) -> new PtStop2StopAnalysis.Stop2StopAggregation(entry1.getDepartures() + entry2.getDepartures(), entry1.getPassengers() + entry2.getPassengers(), - entry1.getTotalVehicleCapacity() + entry2.getTotalVehicleCapacity()); - } } diff --git a/matsim/src/main/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysis2Shp.java b/matsim/src/main/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysis2Shp.java deleted file mode 100644 index 1599a5ba979..00000000000 --- a/matsim/src/main/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysis2Shp.java +++ /dev/null @@ -1,164 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2021 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.analysis.pt.stop2stop; - -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVPrinter; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.geotools.api.feature.simple.SimpleFeature; -import org.geotools.feature.simple.SimpleFeatureBuilder; -import org.geotools.feature.simple.SimpleFeatureTypeBuilder; -import org.locationtech.jts.geom.Coordinate; -import org.locationtech.jts.geom.GeometryFactory; -import org.locationtech.jts.geom.LineString; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.Scenario; -import org.matsim.api.core.v01.network.Link; -import org.matsim.core.utils.geometry.geotools.MGC; -import org.matsim.core.utils.gis.GeoFileWriter; -import org.matsim.core.utils.io.IOUtils; -import org.matsim.pt.transitSchedule.api.TransitLine; - -import java.io.IOException; -import java.util.*; -import java.util.stream.Collectors; - -import static org.matsim.analysis.pt.stop2stop.PtStop2StopAnalysis.aggregateStop2StopAggregations; - -/** - * Write a shape file with passenger volumes, delays and similar information for each stop to stop - * segment of a pt {@link org.matsim.pt.transitSchedule.api.TransitLine}. - * - * @author vsp-gleich - */ -public class PtStop2StopAnalysis2Shp { - - private static final String[] headerCsv = {"link", "transitLine", "stop", "departures", "passengers", "totalVehicleCapacity"}; - private static final Logger log = LogManager.getLogger(PtStop2StopAnalysis2Shp.class); - - public static void writePtStop2StopAnalysisByTransitLine2ShpFile( - final Scenario scenario, final List stop2StopEntriesForEachDeparture, String shpFileName, String coordinateSystem) { - - // sum per link and transit line - Map, Map, PtStop2StopAnalysis.Stop2StopAggregation>> stop2stopByLinkAndTransitLineAggregates = aggregatePerLinkAndLine(stop2StopEntriesForEachDeparture); - - SimpleFeatureTypeBuilder simpleFeatureBuilder = new SimpleFeatureTypeBuilder(); - try { - simpleFeatureBuilder.setCRS(MGC.getCRS(coordinateSystem)); - } catch (IllegalArgumentException e) { - log.warn("Coordinate reference system \"" + coordinateSystem + "\" is unknown."); - } - - simpleFeatureBuilder.setName("ptLinkPerLinePaxFeature"); - // note: column names may not be longer than 10 characters. Otherwise the name is cut after the 10th character and the avalue is NULL in QGis - simpleFeatureBuilder.add("the_geom", LineString.class); - simpleFeatureBuilder.add("linkId", String.class); - simpleFeatureBuilder.add("lineId", String.class); - // simpleFeatureBuilder.add("transitStopIdPrevious", String.class); //not unique, could be multiple - // simpleFeatureBuilder.add("transitStopIdFollowing", String.class); //not unique, could be multiple - simpleFeatureBuilder.add("departures", Integer.class); - simpleFeatureBuilder.add("passengers", Double.class); - simpleFeatureBuilder.add("totVehCapa", Double.class); - simpleFeatureBuilder.add("loadFactor", Double.class); - SimpleFeatureBuilder linkFeatureBuilder = new SimpleFeatureBuilder(simpleFeatureBuilder.buildFeatureType()); - - Collection features = new ArrayList<>(); - GeometryFactory geofac = new GeometryFactory(); - - for(Map.Entry, Map, PtStop2StopAnalysis.Stop2StopAggregation>> entryLinkLevel: stop2stopByLinkAndTransitLineAggregates.entrySet()) { - for (Map.Entry, PtStop2StopAnalysis.Stop2StopAggregation> entryLineLevel : entryLinkLevel.getValue().entrySet()) { - createLinkFeatureFromStop2StopAggregation(scenario, linkFeatureBuilder, features, geofac, entryLinkLevel.getKey(), entryLineLevel.getKey().toString(), entryLineLevel.getValue()); - } - } - - // sum per link of all transit lines - Map, PtStop2StopAnalysis.Stop2StopAggregation> stop2stopByLinkAggregates = stop2StopEntriesForEachDeparture.stream() - .flatMap(stop2StopEntry -> stop2StopEntry.linkIdsSincePreviousStop.stream() - .map(linkId -> new AbstractMap.SimpleEntry<>(linkId, stop2StopEntry))) - .collect(Collectors.toMap( - entry -> entry.getKey(), - entry -> new PtStop2StopAnalysis.Stop2StopAggregation(1, entry.getValue().passengersAtArrival, entry.getValue().totalVehicleCapacity), - aggregateStop2StopAggregations(), - HashMap::new)); - - for(Map.Entry, PtStop2StopAnalysis.Stop2StopAggregation> entryLinkLevel: stop2stopByLinkAggregates.entrySet()) { - createLinkFeatureFromStop2StopAggregation(scenario, linkFeatureBuilder, features, geofac, entryLinkLevel.getKey(), "all", entryLinkLevel.getValue()); - } - - // TODO: add stops? - GeoFileWriter.writeGeometries(features, shpFileName); - } - - public static void writePtStop2StopAnalysisByTransitLine2CsvFile( - final List stop2StopEntriesForEachDeparture, String fileNameCsv, String separatorCsv) { - - // sum per link and transit line - Map, Map, PtStop2StopAnalysis.Stop2StopAggregation>> stop2stopByLinkAndTransitLineAggregates = aggregatePerLinkAndLine(stop2StopEntriesForEachDeparture); - - try (CSVPrinter printer = new CSVPrinter(IOUtils.getBufferedWriter(fileNameCsv), - CSVFormat.DEFAULT.withDelimiter(separatorCsv.charAt(0)).withHeader(headerCsv)) - ) { - for(Map.Entry, Map, PtStop2StopAnalysis.Stop2StopAggregation>> entryLinkLevel: stop2stopByLinkAndTransitLineAggregates.entrySet()) { - for (Map.Entry, PtStop2StopAnalysis.Stop2StopAggregation> entryLineLevel : entryLinkLevel.getValue().entrySet()) { - printer.print(entryLinkLevel.getKey()); - printer.print(entryLineLevel.getKey()); - printer.print(entryLineLevel.getValue().getDepartures()); - printer.print(entryLineLevel.getValue().getPassengers()); - printer.print(entryLineLevel.getValue().getTotalVehicleCapacity()); - printer.println(); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - private static Map, Map, PtStop2StopAnalysis.Stop2StopAggregation>> aggregatePerLinkAndLine(List stop2StopEntriesForEachDeparture) { - return stop2StopEntriesForEachDeparture.stream() - .flatMap(stop2StopEntry -> stop2StopEntry.linkIdsSincePreviousStop.stream() - .map(linkId -> new AbstractMap.SimpleEntry<>(linkId, stop2StopEntry))) - .collect(Collectors.groupingBy(entry -> entry.getKey(), Collectors.toMap( - entry -> entry.getValue().transitLineId, - entry -> new PtStop2StopAnalysis.Stop2StopAggregation(1, entry.getValue().passengersAtArrival, entry.getValue().totalVehicleCapacity), - aggregateStop2StopAggregations(), - TreeMap::new))); - } - - private static void createLinkFeatureFromStop2StopAggregation(Scenario scenario, SimpleFeatureBuilder linkFeatureBuilder, Collection features, GeometryFactory geofac, Id linkId, String transitLineId, PtStop2StopAnalysis.Stop2StopAggregation stop2StopAggregation) { - Link link = scenario.getNetwork().getLinks().get(linkId); - LineString ls = geofac.createLineString(new Coordinate[] {MGC.coord2Coordinate(link.getFromNode().getCoord()), - MGC.coord2Coordinate(link.getToNode().getCoord())}); - Object[] linkFeatureAttributes = new Object[7]; - linkFeatureAttributes[0] = ls; - linkFeatureAttributes[1] = linkId; - linkFeatureAttributes[2] = transitLineId; - linkFeatureAttributes[3] = stop2StopAggregation.getDepartures(); - linkFeatureAttributes[4] = stop2StopAggregation.getPassengers(); - linkFeatureAttributes[5] = stop2StopAggregation.getTotalVehicleCapacity(); - linkFeatureAttributes[6] = stop2StopAggregation.getPassengers() / stop2StopAggregation.getTotalVehicleCapacity(); - try { - features.add(linkFeatureBuilder.buildFeature(stop2StopAggregation + "_line_" + transitLineId, linkFeatureAttributes)); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } - } - -} diff --git a/matsim/src/main/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysisControlerListener.java b/matsim/src/main/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysisControlerListener.java index 8259ad38828..7047436a44e 100644 --- a/matsim/src/main/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysisControlerListener.java +++ b/matsim/src/main/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysisControlerListener.java @@ -46,7 +46,8 @@ public class PtStop2StopAnalysisControlerListener implements IterationStartsList PtStop2StopAnalysisControlerListener(Scenario scenario, EventsManager eventsManager, OutputDirectoryHierarchy controlerIO) { this.eventsManager = eventsManager; this.controlerIO = controlerIO; - ptStop2StopAnalysis = new PtStop2StopAnalysis(scenario.getTransitVehicles()); + // TODO: Sample size is only available in simwrapper config group which is not available here. Setting to 1, needs to be upscaled later. + ptStop2StopAnalysis = new PtStop2StopAnalysis(scenario.getTransitVehicles(), 1.0); sep = scenario.getConfig().global().getDefaultDelimiter(); sep2 = sep.equals(";") ? "_" : ";"; // TODO: move sep2 to global config } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/ActivityEndEvent.java b/matsim/src/main/java/org/matsim/api/core/v01/events/ActivityEndEvent.java index 39e0e36bbac..76bc4427498 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/ActivityEndEvent.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/ActivityEndEvent.java @@ -29,6 +29,8 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.facilities.ActivityFacility; +import static org.matsim.core.utils.io.XmlUtils.writeEncodedAttributeKeyValue; + public final class ActivityEndEvent extends Event implements HasPersonId, HasLinkId, HasFacilityId, BasicLocation { public static final String EVENT_TYPE = "actend"; @@ -49,7 +51,7 @@ public ActivityEndEvent( final double time, final Id agentId, final Id agentId, final Id linkId, + public ActivityEndEvent(final double time, final Id agentId, final Id linkId, final Id facilityId, final String acttype, final Coord coord) { super(time); this.linkId = linkId; @@ -79,7 +81,7 @@ public String getActType() { @Override public Id getPersonId() { return this.personId; } - + @Override public Map getAttributes() { Map attr = super.getAttributes(); @@ -95,4 +97,12 @@ public void setCoord( Coord coord ) { // yy this is to retrofit the coordinate into existing events that don't have it. this.coord = coord; } + + @Override + public void writeAsXML(StringBuilder out) { + // Writes common attributes + writeXMLStart(out); + writeEncodedAttributeKeyValue(out, ATTRIBUTE_ACTTYPE, this.acttype); + writeXMLEnd(out); + } } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/ActivityStartEvent.java b/matsim/src/main/java/org/matsim/api/core/v01/events/ActivityStartEvent.java index f58a5b9a506..b0786093572 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/ActivityStartEvent.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/ActivityStartEvent.java @@ -20,8 +20,6 @@ package org.matsim.api.core.v01.events; -import java.util.Map; - import org.matsim.api.core.v01.BasicLocation; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; @@ -29,6 +27,10 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.facilities.ActivityFacility; +import java.util.Map; + +import static org.matsim.core.utils.io.XmlUtils.writeEncodedAttributeKeyValue; + public class ActivityStartEvent extends Event implements HasFacilityId, HasPersonId, HasLinkId, BasicLocation{ public static final String EVENT_TYPE = "actstart"; @@ -91,7 +93,7 @@ public String getActType() { @Override public Id getPersonId() { return this.personId; } - + @Override public Map getAttributes() { Map attr = super.getAttributes(); @@ -109,4 +111,12 @@ public void setCoord( Coord coord ) { // yy this is to retrofit the coordinate into existing events that don't have it. :-( kai, mar'20 this.coord = coord; } + + @Override + public void writeAsXML(StringBuilder out) { + // Writes common attributes + writeXMLStart(out); + writeEncodedAttributeKeyValue(out, ATTRIBUTE_ACTTYPE, this.acttype); + writeXMLEnd(out); + } } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/Event.java b/matsim/src/main/java/org/matsim/api/core/v01/events/Event.java index 09852740b7a..c51a90610fe 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/Event.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/Event.java @@ -24,6 +24,9 @@ import java.util.Map; import org.matsim.api.core.v01.BasicLocation; +import org.matsim.core.utils.io.XmlUtils; + +import static org.matsim.core.utils.io.XmlUtils.writeEncodedAttributeValue; public abstract class Event { @@ -105,6 +108,69 @@ public boolean equals(Object obj) { public int hashCode() { return getAttributes().hashCode(); // Two equal events must at least have the same attributes, so they will get the same hashCode like this. } + + + /** + * Write the start of the xml representation and some common attributes. This method should be called first by {@link #writeAsXML(StringBuilder)}. + */ + protected final void writeXMLStart(StringBuilder out) { + out.append("\t\n"); + } + + /** + * Write a xml representation of this event to the given writer. + * The implementation must write the whole xml element . Starting with \t and adding a newline at the end. + * + * The provided default implementation writes the whole element based on {@link #getAttributes()}. This is slow and should be overridden. + * The overriding implementation must *not* call the super method. + */ + public void writeAsXML(StringBuilder out) { + out.append("\t attr = getAttributes(); + for (Map.Entry entry : attr.entrySet()) { + out.append(entry.getKey()); + out.append("=\""); + out.append(XmlUtils.encodeAttributeValue(entry.getValue())); + out.append("\" "); + } + out.append(" />\n"); + } + } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/LinkEnterEvent.java b/matsim/src/main/java/org/matsim/api/core/v01/events/LinkEnterEvent.java index 63250efa333..310521abc11 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/LinkEnterEvent.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/LinkEnterEvent.java @@ -73,4 +73,11 @@ public Map getAttributes() { // linkId, vehicleId handled by superclass return atts; } + + @Override + public void writeAsXML(StringBuilder out) { + // Writes all common attributes + writeXMLStart(out); + writeXMLEnd(out); + } } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/LinkLeaveEvent.java b/matsim/src/main/java/org/matsim/api/core/v01/events/LinkLeaveEvent.java index 06018363204..0491771b110 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/LinkLeaveEvent.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/LinkLeaveEvent.java @@ -76,4 +76,11 @@ public Map getAttributes() { // linkId, vehicleId handled by superclass return atts; } + + @Override + public void writeAsXML(StringBuilder out) { + // Writes all common attributes + writeXMLStart(out); + writeXMLEnd(out); + } } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonArrivalEvent.java b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonArrivalEvent.java index 6e947aaff11..9e45e10e7da 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonArrivalEvent.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonArrivalEvent.java @@ -26,6 +26,8 @@ import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.population.Person; +import static org.matsim.core.utils.io.XmlUtils.writeEncodedAttributeKeyValue; + public class PersonArrivalEvent extends Event implements HasPersonId, HasLinkId { public static final String EVENT_TYPE = "arrival"; @@ -71,4 +73,14 @@ public Map getAttributes() { } return attr; } + + @Override + public void writeAsXML(StringBuilder out) { + // Writes all common attributes + writeXMLStart(out); + if (this.legMode != null) { + writeEncodedAttributeKeyValue(out, ATTRIBUTE_LEGMODE, this.legMode); + } + writeXMLEnd(out); + } } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonDepartureEvent.java b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonDepartureEvent.java index 425d8ad4e78..d98e05e8708 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonDepartureEvent.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonDepartureEvent.java @@ -25,6 +25,7 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.population.Person; +import org.matsim.core.utils.io.XmlUtils; public class PersonDepartureEvent extends Event implements HasPersonId, HasLinkId { @@ -82,4 +83,16 @@ public Map getAttributes() { } return attr; } + + @Override + public void writeAsXML(StringBuilder out) { + writeXMLStart(out); + if (this.legMode != null) { + XmlUtils.writeEncodedAttributeKeyValue(out, ATTRIBUTE_LEGMODE, this.legMode); + } + if (this.routingMode != null) { + XmlUtils.writeEncodedAttributeKeyValue(out, ATTRIBUTE_ROUTING_MODE, this.routingMode); + } + writeXMLEnd(out); + } } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonEntersVehicleEvent.java b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonEntersVehicleEvent.java index a3e051f44c4..db694dff953 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonEntersVehicleEvent.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonEntersVehicleEvent.java @@ -68,4 +68,11 @@ public Map getAttributes() { // personId, vehicleId handled by superclass return atts; } + + @Override + public void writeAsXML(StringBuilder out) { + // Writes all common attributes + writeXMLStart(out); + writeXMLEnd(out); + } } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonLeavesVehicleEvent.java b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonLeavesVehicleEvent.java index 27a3b5b2bdd..3a2bad23e44 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonLeavesVehicleEvent.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonLeavesVehicleEvent.java @@ -69,4 +69,11 @@ public Map getAttributes() { // personId, vehicleId handled by superclass return attrs; } + + @Override + public void writeAsXML(StringBuilder out) { + // Writes all common attributes + writeXMLStart(out); + writeXMLEnd(out); + } } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonMoneyEvent.java b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonMoneyEvent.java index e61a8a85b32..1b08399d47f 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonMoneyEvent.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonMoneyEvent.java @@ -25,6 +25,8 @@ import java.util.Map; +import static org.matsim.core.utils.io.XmlUtils.writeEncodedAttributeKeyValue; + /** * This event specifies that an agent has gained (or paid) some money. * Scoring functions should handle these Events by adding the amount somehow @@ -134,4 +136,23 @@ public Map getAttributes() { } return attr; } + + @Override + public void writeAsXML(StringBuilder out) { + // Writes all common attributes + writeXMLStart(out); + + out.append("amount=\"").append(this.amount).append("\" "); + if (this.purpose != null) { + writeEncodedAttributeKeyValue(out, ATTRIBUTE_PURPOSE, this.purpose); + } + if (this.transactionPartner != null) { + writeEncodedAttributeKeyValue(out, ATTRIBUTE_TRANSACTION_PARTNER, this.transactionPartner); + } + if (this.reference != null) { + writeEncodedAttributeKeyValue(out, ATTRIBUTE_REFERENCE, this.reference); + } + + writeXMLEnd(out); + } } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonScoreEvent.java b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonScoreEvent.java index 96019b6242f..893769df004 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonScoreEvent.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonScoreEvent.java @@ -20,6 +20,7 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Person; +import org.matsim.core.utils.io.XmlUtils; import java.util.Map; @@ -75,4 +76,14 @@ public Map getAttributes() { } return attr; } + + @Override + public void writeAsXML(StringBuilder out) { + writeXMLStart(out); + out.append("amount=\"").append(this.amount).append("\" "); + if (this.kind != null) { + XmlUtils.writeEncodedAttributeKeyValue(out, ATTRIBUTE_KIND, this.kind); + } + writeXMLEnd(out); + } } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonStuckEvent.java b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonStuckEvent.java index b2439dd8b96..2eca25c0eab 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/PersonStuckEvent.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/PersonStuckEvent.java @@ -25,6 +25,7 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.population.Person; +import org.matsim.core.utils.io.XmlUtils; public class PersonStuckEvent extends Event implements HasPersonId, HasLinkId { @@ -71,4 +72,16 @@ public Map getAttributes() { } return attr; } + + @Override + public void writeAsXML(StringBuilder out) { + // Writes all common attributes + writeXMLStart(out); + + if (this.legMode != null) { + XmlUtils.writeEncodedAttributeKeyValue(out, ATTRIBUTE_LEGMODE, this.legMode); + } + + writeXMLEnd(out); + } } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/TransitDriverStartsEvent.java b/matsim/src/main/java/org/matsim/api/core/v01/events/TransitDriverStartsEvent.java index f58b1536fa9..801b2ec44c4 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/TransitDriverStartsEvent.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/TransitDriverStartsEvent.java @@ -23,6 +23,7 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Person; +import org.matsim.core.utils.io.XmlUtils; import org.matsim.pt.transitSchedule.api.Departure; import org.matsim.pt.transitSchedule.api.TransitLine; import org.matsim.pt.transitSchedule.api.TransitRoute; @@ -45,7 +46,7 @@ public class TransitDriverStartsEvent extends Event { private final Id transitLineId; private final Id departureId; - public TransitDriverStartsEvent(final double time, final Id driverId, final Id vehicleId, + public TransitDriverStartsEvent(final double time, final Id driverId, final Id vehicleId, final Id transitLineId, final Id transitRouteId, final Id departureId) { super(time); this.driverId = driverId; @@ -54,23 +55,23 @@ public TransitDriverStartsEvent(final double time, final Id driverId, fi this.transitLineId = transitLineId; this.departureId = departureId; } - + public Id getDriverId() { return driverId; } - + public Id getVehicleId() { return vehicleId; } - + public Id getTransitRouteId() { return transitRouteId; } - + public Id getTransitLineId() { return transitLineId; } - + public Id getDepartureId() { return departureId; } @@ -79,7 +80,7 @@ public Id getDepartureId() { public String getEventType() { return EVENT_TYPE; } - + @Override public Map getAttributes() { Map atts = super.getAttributes(); @@ -90,4 +91,17 @@ public Map getAttributes() { atts.put(ATTRIBUTE_DEPARTURE_ID, this.getDepartureId().toString()); return atts; } -} \ No newline at end of file + + @Override + public void writeAsXML(StringBuilder out) { + writeXMLStart(out); + + XmlUtils.writeEncodedAttributeKeyValue(out, ATTRIBUTE_DRIVER_ID, this.getDriverId().toString()); + XmlUtils.writeEncodedAttributeKeyValue(out, ATTRIBUTE_VEHICLE_ID, this.getVehicleId().toString()); + XmlUtils.writeEncodedAttributeKeyValue(out, ATTRIBUTE_TRANSIT_LINE_ID, this.getTransitLineId().toString()); + XmlUtils.writeEncodedAttributeKeyValue(out, ATTRIBUTE_TRANSIT_ROUTE_ID, this.getTransitRouteId().toString()); + XmlUtils.writeEncodedAttributeKeyValue(out, ATTRIBUTE_DEPARTURE_ID, this.getDepartureId().toString()); + + writeXMLEnd(out); + } +} diff --git a/matsim/src/main/java/org/matsim/api/core/v01/events/VehicleAbortsEvent.java b/matsim/src/main/java/org/matsim/api/core/v01/events/VehicleAbortsEvent.java index a623a758bd0..ba0ec9bbeff 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/events/VehicleAbortsEvent.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/events/VehicleAbortsEvent.java @@ -61,4 +61,10 @@ public Map getAttributes() { // linkId, vehicleId handled by superclass return atts; } + + @Override + public void writeAsXML(StringBuilder out) { + writeXMLStart(out); + writeXMLEnd(out); + } } diff --git a/matsim/src/main/java/org/matsim/core/config/consistency/VspConfigConsistencyCheckerImpl.java b/matsim/src/main/java/org/matsim/core/config/consistency/VspConfigConsistencyCheckerImpl.java index 9fd9e5045b7..a7dba48bdb6 100644 --- a/matsim/src/main/java/org/matsim/core/config/consistency/VspConfigConsistencyCheckerImpl.java +++ b/matsim/src/main/java/org/matsim/core/config/consistency/VspConfigConsistencyCheckerImpl.java @@ -46,13 +46,7 @@ * */ public final class VspConfigConsistencyCheckerImpl implements ConfigConsistencyChecker { - // yyyy TODOS: - // VSP now regularly uses marg utls of travelling != null to fit distance distributions. There should be a switch to switch off the warnings. - - // VSP says that people < 18J should not use car, and implements that via car availability. How to handle that? - - // private static final Logger log = LogManager.getLogger(VspConfigConsistencyCheckerImpl.class); public VspConfigConsistencyCheckerImpl() { @@ -96,10 +90,6 @@ public void checkConsistency(Config config) { problem = checkLocationChoiceConfigGroup( config, problem ); - // === mode choice: - - problem = checkModeChoiceConfigGroup( config, lvl, problem ); - // === planCalcScore: problem = checkPlanCalcScoreConfigGroup( config, lvl, problem ); @@ -116,10 +106,6 @@ public void checkConsistency(Config config) { problem = checkQsimConfigGroup( config, lvl, problem ); - // === subtour mode choice: - - problem = checkSubtourModeChoiceConfigGroup( config, lvl, problem ); - // === strategy: problem = checkStrategyConfigGroup( config, lvl, problem ); @@ -157,20 +143,20 @@ public void checkConsistency(Config config) { } } - private boolean checkSubtourModeChoiceConfigGroup( Config config, Level lvl, boolean problem ){ - if ( config.subtourModeChoice().considerCarAvailability() ) { -// problem = true; - log.log( lvl, "you are considering car abailability; vsp config is not doing that. Instead, we are using a daily monetary constant for car."); - } - return problem; - } - private boolean checkModeChoiceConfigGroup( Config config, Level lvl, boolean problem ){ - if ( !config.changeMode().getIgnoreCarAvailability() ) { -// problem = true; - log.log( lvl, "you are considering car abailability; vsp config is not doing that. Instead, we are using a daily monetary constant for car."); - } - return problem; - } +// private boolean checkSubtourModeChoiceConfigGroup( Config config, Level lvl, boolean problem ){ +// if ( config.subtourModeChoice().considerCarAvailability() ) { +//// problem = true; +// log.log( lvl, "you are considering car abailability; vsp config is not doing that. Instead, we are using a daily monetary constant for car."); +// } +// return problem; +// } +// private boolean checkModeChoiceConfigGroup( Config config, Level lvl, boolean problem ){ +// if ( !config.changeMode().getIgnoreCarAvailability() ) { +//// problem = true; +// log.log( lvl, "you are considering car abailability; vsp config is not doing that. Instead, we are using a daily monetary constant for car."); +// } +// return problem; +// } private static boolean checkGlobalConfigGroup( Config config, Level lvl, boolean problem ){ if ( config.global().isInsistingOnDeprecatedConfigVersion() ) { problem = true ; @@ -263,7 +249,7 @@ private static boolean checkQsimConfigGroup( Config config, Level lvl, boolean p if ( config.qsim().getVehiclesSource()==VehiclesSource.defaultVehicle ) { log.log( lvl, "found qsim.vehiclesSource=defaultVehicle; vsp should use one of the other settings or talk to kai"); } - if ( config.qsim().getLinkDynamics() != QSimConfigGroup.LinkDynamics.PassingQ ) { + if ( config.qsim().getLinkDynamics() != QSimConfigGroup.LinkDynamics.PassingQ && config.qsim().getMainModes().contains(TransportMode.bike) ) { log.log( lvl, "found qsim.linkDynamics=" + config.qsim().getLinkDynamics() + "; vsp should use PassingQ or talk to kai"); } @@ -428,7 +414,7 @@ private static boolean checkPlanCalcScoreConfigGroup( Config config, Level lvl, // added may'23 for ( ModeParams params : config.scoring().getModes().values() ){ if ( config.vspExperimental().getCheckingOfMarginalUtilityOfTravellng()== CheckingOfMarginalUtilityOfTravellng.allZero ){ - if( params.getMarginalUtilityOfTraveling() != 0. ){ + if( params.getMarginalUtilityOfTraveling() != 0. && !params.getMode().equals( TransportMode.ride ) && !params.getMode().equals( TransportMode.bike ) ){ log.log( lvl, "You are setting the marginal utility of traveling with mode " + params.getMode() + " to " + params.getMarginalUtilityOfTraveling() + ". VSP standard is to set this to zero. Please document carefully why you are using a value different from zero, e.g. by showing distance distributions." ); } diff --git a/matsim/src/main/java/org/matsim/core/config/groups/QSimConfigGroup.java b/matsim/src/main/java/org/matsim/core/config/groups/QSimConfigGroup.java index f8d59f01e01..97c175243e0 100644 --- a/matsim/src/main/java/org/matsim/core/config/groups/QSimConfigGroup.java +++ b/matsim/src/main/java/org/matsim/core/config/groups/QSimConfigGroup.java @@ -431,8 +431,15 @@ public void setInsertingWaitingVehiclesBeforeDrivingVehicles(boolean val) { this.insertingWaitingVehiclesBeforeDrivingVehicles = val; } + /** + * This determines the traffic dynamics of a link. The default is 'queue', but the recommended setting is kinematic waves. + * + * DEPRECATION NOTE: 'withHoles' is deprecated, use 'kinematicWaves' instead, as that uses 'withHoles' and adds an inflow capacity on top. + */ public enum TrafficDynamics { - queue, withHoles, + queue, + @Deprecated + withHoles, kinematicWaves // MATSim-630; previously, the switch was InflowConstraint.maxflowFromFdiag. Amit Jan 2017. } @@ -440,11 +447,19 @@ public enum TrafficDynamics { * Defines how the qsim sets the inflow and/or how it reacts to link attributes which are inconsistent with regard to the fundamental diagram.
* *

  • Note that {@code MAX_CAP_FOR_ONE_LANE} is backwards-compatible but always sets the inflow capacity to the maximum according to the fundamental diagram for one lane, - * so it essentially sets the inflow capacity too low for multiple-lane-links.
  • - *
  • {@code INFLOW_FROM_FDIAG} sets the inflow capacity to maximum flow capacity according to the fundamental diagram, assuming the nr of lanes in the link attributes to be correct.
  • - *
  • {@code NR_OF_LANES_FROM_FDIAG} sets the number of lanes to minimum required according to the fundamental diagram, assuming the flow capacity in the link attributes to be correct.
  • + * so it essentially sets the inflow capacity too low for multiple-lane-links. DEPRECATED: This is only for backwards compatibility. Use + * INFLOW_FROM_FDIAG instead. + *
  • {@code INFLOW_FROM_FDIAG} sets the inflow capacity to maximum flow capacity according to the + * fundamental diagram, assuming the nr of lanes in the link attributes to be correct.
  • + *
  • {@code NR_OF_LANES_FROM_FDIAG} sets the number of lanes to minimum required according to the fundamental + * diagram, assuming the flow capacity in the link attributes to be correct. DEPRECATED: In practice the other setting is used most often! Use\ + * INFLOW_FROM_FDIAG instead.
  • */ - public enum InflowCapacitySetting {INFLOW_FROM_FDIAG, NR_OF_LANES_FROM_FDIAG, MAX_CAP_FOR_ONE_LANE} + public enum InflowCapacitySetting {INFLOW_FROM_FDIAG, + @Deprecated + NR_OF_LANES_FROM_FDIAG, + @Deprecated + MAX_CAP_FOR_ONE_LANE} @StringSetter(TRAFFIC_DYNAMICS) public void setTrafficDynamics(final TrafficDynamics str) { diff --git a/matsim/src/main/java/org/matsim/core/controler/ControlerDefaultsModule.java b/matsim/src/main/java/org/matsim/core/controler/ControlerDefaultsModule.java index 293ac9ed415..0de32d9c47b 100755 --- a/matsim/src/main/java/org/matsim/core/controler/ControlerDefaultsModule.java +++ b/matsim/src/main/java/org/matsim/core/controler/ControlerDefaultsModule.java @@ -51,6 +51,7 @@ import java.io.File; public final class ControlerDefaultsModule extends AbstractModule { + @Override public void install() { install(new EventsManagerModule()); @@ -85,9 +86,10 @@ public void install() { // Maybe not the best place to but this but since ChartUtils is used by many modules, including default ones, // the cache needs to be always set correctly. addControlerListenerBinding().toInstance(new StartupListener() { - @Inject private OutputDirectoryHierarchy outputDirectoryHierarchy; - @Override public void notifyStartup(StartupEvent event) { - ImageIO.setCacheDirectory(new File(outputDirectoryHierarchy.getTempPath())); + + @Override + public void notifyStartup(StartupEvent event) { + ImageIO.setCacheDirectory(new File(event.getServices().getControlerIO().getTempPath())); } }); diff --git a/matsim/src/main/java/org/matsim/core/controler/OutputDirectoryHierarchy.java b/matsim/src/main/java/org/matsim/core/controler/OutputDirectoryHierarchy.java index 86272160a77..9decfe75a1a 100644 --- a/matsim/src/main/java/org/matsim/core/controler/OutputDirectoryHierarchy.java +++ b/matsim/src/main/java/org/matsim/core/controler/OutputDirectoryHierarchy.java @@ -47,6 +47,8 @@ public enum OverwriteFileSetting {failIfDirectoryExists, overwriteExistingFiles, private static final String DIRECTORY_ITERS = "ITERS"; + public static final String MATSIM_TEMP_DIR_PROPERTY = "matsim.tempDir"; + private static final Logger log = LogManager.getLogger(OutputDirectoryHierarchy.class); private String runId = null; @@ -108,7 +110,11 @@ public OutputDirectoryHierarchy(String outputPath, String runId, OverwriteFileSe * @return path to a temp-directory. */ public final String getTempPath() { - return outputPath + "/tmp"; + String matsimTempDir = System.getProperty(MATSIM_TEMP_DIR_PROPERTY); + if (matsimTempDir == null) { + matsimTempDir = outputPath + "/tmp"; + } + return matsimTempDir; } /** diff --git a/matsim/src/main/java/org/matsim/core/events/algorithms/EventWriterXML.java b/matsim/src/main/java/org/matsim/core/events/algorithms/EventWriterXML.java index 54b731771e1..4b29ae4ac55 100644 --- a/matsim/src/main/java/org/matsim/core/events/algorithms/EventWriterXML.java +++ b/matsim/src/main/java/org/matsim/core/events/algorithms/EventWriterXML.java @@ -32,13 +32,17 @@ import java.io.OutputStreamWriter; import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; -import java.util.Map; public class EventWriterXML implements EventWriter, BasicEventHandler { private static final Logger LOG = LogManager.getLogger(EventWriterXML.class); private final BufferedWriter out; + /** + * Cache for StringBuilder instances to avoid creating a new one for each event. + */ + private final ThreadLocal stringBuilder = ThreadLocal.withInitial(StringBuilder::new); + public EventWriterXML(final String outfilename) { this.out = IOUtils.getBufferedWriter(outfilename); this.writeHeader(); @@ -83,73 +87,14 @@ public void reset(final int iter) { @Override public void handleEvent(final Event event) { try { - this.out.append("\t attr = event.getAttributes(); - for (Map.Entry entry : attr.entrySet()) { - this.out.append(entry.getKey()); - this.out.append("=\""); - this.out.append(encodeAttributeValue(entry.getValue())); - this.out.append("\" "); - } - this.out.append(" />\n"); - } catch (IOException e) { - LOG.error(e.getMessage(), e); - } - } + StringBuilder b = stringBuilder.get(); - // the following method was taken from MatsimXmlWriter in order to correctly encode attributes, but - // to forego the overhead of using the full MatsimXmlWriter. - /** - * Encodes the given string in such a way that it no longer contains - * characters that have a special meaning in xml. - * - * @see http://www.w3.org/International/questions/qa-escapes#use - * @param attributeValue - * @return String with some characters replaced by their xml-encoding. - */ - private String encodeAttributeValue(final String attributeValue) { - if (attributeValue == null) { - return null; - } - int len = attributeValue.length(); - boolean encode = false; - for (int pos = 0; pos < len; pos++) { - char ch = attributeValue.charAt(pos); - if (ch == '<') { - encode = true; - break; - } else if (ch == '>') { - encode = true; - break; - } else if (ch == '\"') { - encode = true; - break; - } else if (ch == '&') { - encode = true; - break; - } - } - if (encode) { - StringBuilder bf = new StringBuilder(attributeValue.length() + 30); - for (int pos = 0; pos < len; pos++) { - char ch = attributeValue.charAt(pos); - if (ch == '<') { - bf.append("<"); - } else if (ch == '>') { - bf.append(">"); - } else if (ch == '\"') { - bf.append("""); - } else if (ch == '&') { - bf.append("&"); - } else { - bf.append(ch); - } - } + b.setLength(0); + event.writeAsXML(b); + this.out.append(b); - return bf.toString(); + } catch (IOException e) { + LOG.error(e.getMessage(), e); } - return attributeValue; - } - } diff --git a/matsim/src/main/java/org/matsim/core/router/MultimodalLinkChooser.java b/matsim/src/main/java/org/matsim/core/router/MultimodalLinkChooser.java index a7239e98198..4d8cf318622 100644 --- a/matsim/src/main/java/org/matsim/core/router/MultimodalLinkChooser.java +++ b/matsim/src/main/java/org/matsim/core/router/MultimodalLinkChooser.java @@ -2,9 +2,8 @@ import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; -import org.matsim.facilities.Facility; public interface MultimodalLinkChooser { - - public Link decideOnLink( final Facility facility, final Network network ); + public Link decideAccessLink(RoutingRequest request, Network network); + public Link decideEgressLink(RoutingRequest request, Network network); } diff --git a/matsim/src/main/java/org/matsim/core/router/MultimodalLinkChooserDefaultImpl.java b/matsim/src/main/java/org/matsim/core/router/MultimodalLinkChooserDefaultImpl.java index cd37d0f0098..00b93eb363a 100644 --- a/matsim/src/main/java/org/matsim/core/router/MultimodalLinkChooserDefaultImpl.java +++ b/matsim/src/main/java/org/matsim/core/router/MultimodalLinkChooserDefaultImpl.java @@ -15,7 +15,16 @@ class MultimodalLinkChooserDefaultImpl implements MultimodalLinkChooser { private static final Logger log = LogManager.getLogger( FacilitiesUtils.class ) ; @Override - public Link decideOnLink(Facility facility, Network network) { + public Link decideAccessLink(RoutingRequest request, Network network) { + return decideOnLink(request.getFromFacility(), network); + } + + @Override + public Link decideEgressLink(RoutingRequest request, Network network) { + return decideOnLink(request.getToFacility(), network); + } + + private Link decideOnLink(Facility facility, Network network) { Link accessActLink = null ; Id accessActLinkId = null ; diff --git a/matsim/src/main/java/org/matsim/core/router/NetworkRoutingInclAccessEgressModule.java b/matsim/src/main/java/org/matsim/core/router/NetworkRoutingInclAccessEgressModule.java index 1a24567b1dd..39338b527dd 100644 --- a/matsim/src/main/java/org/matsim/core/router/NetworkRoutingInclAccessEgressModule.java +++ b/matsim/src/main/java/org/matsim/core/router/NetworkRoutingInclAccessEgressModule.java @@ -140,9 +140,8 @@ public synchronized List calcRoute(RoutingRequest request Gbl.assertNotNull(fromFacility); Gbl.assertNotNull(toFacility); - Link accessActLink = multimodalLinkChooser.decideOnLink(fromFacility, filteredNetwork); - - Link egressActLink = multimodalLinkChooser.decideOnLink(toFacility, filteredNetwork); + Link accessActLink = multimodalLinkChooser.decideAccessLink(request, filteredNetwork); + Link egressActLink = multimodalLinkChooser.decideEgressLink(request, filteredNetwork); double now = departureTime; diff --git a/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyALT.java b/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyALT.java index 47c2f16de86..62b5d21590e 100644 --- a/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyALT.java +++ b/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyALT.java @@ -91,6 +91,7 @@ public Path calcLeastCostPath(Node startNode, Node endNode, double startTime, Pe Arrays.fill(this.iterationIds, this.currentIteration); this.currentIteration = Integer.MIN_VALUE; } + boolean hasTurnRestrictions = this.graph.hasTurnRestrictions(); int startNodeIndex = startNode.getId().index(); int endNodeIndex = endNode.getId().index(); @@ -111,6 +112,11 @@ public Path calcLeastCostPath(Node startNode, Node endNode, double startTime, Pe foundEndNode = true; break; } + // if turn restrictions are used, we might be on a colored node, so check for the original node + if (hasTurnRestrictions && this.graph.getNode(nodeIdx).getId().index() == endNodeIndex) { + foundEndNode = true; + break; + } // ignore dead-ends int deadend = this.astarData.getNodeDeadend(nodeIdx); diff --git a/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyDijkstra.java b/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyDijkstra.java index 735a9795fcf..ec3eb1b3035 100644 --- a/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyDijkstra.java +++ b/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyDijkstra.java @@ -73,6 +73,7 @@ public Path calcLeastCostPath(Node startNode, Node endNode, double startTime, Pe this.currentIteration = Integer.MIN_VALUE; } + boolean hasTurnRestrictions = this.graph.hasTurnRestrictions(); int startNodeIndex = startNode.getId().index(); int endNodeIndex = endNode.getId().index(); @@ -88,6 +89,11 @@ public Path calcLeastCostPath(Node startNode, Node endNode, double startTime, Pe foundEndNode = true; break; } + // if turn restrictions are used, we might be on a colored node, so check for the original node + if (hasTurnRestrictions && this.graph.getNode(nodeIdx).getId().index() == endNodeIndex) { + foundEndNode = true; + break; + } double currTime = getTimeRaw(nodeIdx); if (Double.isInfinite(currTime)) { diff --git a/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyGraph.java b/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyGraph.java index e7cd69bcf3d..7666909ca01 100644 --- a/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyGraph.java +++ b/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyGraph.java @@ -54,14 +54,16 @@ public class SpeedyGraph { private final int[] linkData; private final Link[] links; private final Node[] nodes; + private final boolean hasTurnRestrictions; - SpeedyGraph(int[] nodeData, int[] linkData, Node[] nodes, Link[] links) { + SpeedyGraph(int[] nodeData, int[] linkData, Node[] nodes, Link[] links, boolean hasTurnRestrictions) { this.nodeData = nodeData; this.linkData = linkData; this.nodes = nodes; this.links = links; this.nodeCount = this.nodes.length; this.linkCount = this.links.length; + this.hasTurnRestrictions = hasTurnRestrictions; } public LinkIterator getOutLinkIterator() { @@ -80,6 +82,10 @@ Node getNode(int index) { return this.nodes[index]; } + boolean hasTurnRestrictions() { + return this.hasTurnRestrictions; + } + public interface LinkIterator { void reset(int nodeIdx); diff --git a/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyGraphBuilder.java b/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyGraphBuilder.java index 724343da24d..54f41ee1aa4 100644 --- a/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyGraphBuilder.java +++ b/matsim/src/main/java/org/matsim/core/router/speedy/SpeedyGraphBuilder.java @@ -132,7 +132,7 @@ private SpeedyGraph buildWithTurnRestrictions(Network network) { addLink(link); } - return new SpeedyGraph(this.nodeData, this.linkData, this.nodes, this.links); + return new SpeedyGraph(this.nodeData, this.linkData, this.nodes, this.links, true); } private ColoredLink applyTurnRestriction(TurnRestrictionsContext context, Collection>> restrictions, Link startingLink) { @@ -314,7 +314,7 @@ private SpeedyGraph buildWithoutTurnRestrictions(Network network) { addLink(link); } - return new SpeedyGraph(this.nodeData, this.linkData, this.nodes, this.links); + return new SpeedyGraph(this.nodeData, this.linkData, this.nodes, this.links, false); } private void addLink(Link link) { diff --git a/matsim/src/main/java/org/matsim/core/utils/io/XmlUtils.java b/matsim/src/main/java/org/matsim/core/utils/io/XmlUtils.java index 57fa2f0b63a..85df85a9fd5 100644 --- a/matsim/src/main/java/org/matsim/core/utils/io/XmlUtils.java +++ b/matsim/src/main/java/org/matsim/core/utils/io/XmlUtils.java @@ -39,12 +39,88 @@ private XmlUtils() { * @return String with some characters replaced by their xml-encoding. */ public static String encodeAttributeValue(final String attributeValue) { - if (attributeValue.contains("&") || attributeValue.contains("\"") || attributeValue.contains("<") || attributeValue.contains(">")) { - return attributeValue.replace("&", "&").replace("\"", """).replace("<", "<").replace(">", ">"); + if (attributeValue == null) { + return null; + } + int len = attributeValue.length(); + boolean encode = false; + for (int pos = 0; pos < len; pos++) { + char ch = attributeValue.charAt(pos); + if (ch == '<') { + encode = true; + break; + } else if (ch == '>') { + encode = true; + break; + } else if (ch == '\"') { + encode = true; + break; + } else if (ch == '&') { + encode = true; + break; + } + } + if (encode) { + StringBuilder bf = new StringBuilder(attributeValue.length() + 30); + for (int pos = 0; pos < len; pos++) { + char ch = attributeValue.charAt(pos); + if (ch == '<') { + bf.append("<"); + } else if (ch == '>') { + bf.append(">"); + } else if (ch == '\"') { + bf.append("""); + } else if (ch == '&') { + bf.append("&"); + } else { + bf.append(ch); + } + } + + return bf.toString(); } return attributeValue; } + /** + * Write encoded attribute value to the given StringBuilder. + * This is an optimized version of {@link #encodeAttributeValue(String)}, which does not create any intermediate objects. + */ + public static StringBuilder writeEncodedAttributeValue(StringBuilder out, String attributeValue) { + + if (attributeValue == null) { + // By convention, null values are written as "null" in the xml output. + out.append("null"); + return out; + } + + int len = attributeValue.length(); + + for (int pos = 0; pos < len; pos++) { + char ch = attributeValue.charAt(pos); + switch (ch) { + case '<' -> out.append("<"); + case '>' -> out.append(">"); + case '\"' -> out.append("""); + case '&' -> out.append("&"); + default -> out.append(ch); + }; + } + + return out; + } + + /** + * Helper function to write an attribute key-value pair to the given StringBuilder. + * Note, do not use this for primitive types as these don't need to be encoded and the {@link StringBuilder} has specialized methods fot these. + */ + public static StringBuilder writeEncodedAttributeKeyValue(StringBuilder out, String key, String value) { + out.append(key).append("=\""); + writeEncodedAttributeValue(out, value); + out.append("\" "); + return out; + } + public static String encodeContent(final String content) { if (content.contains("&") || content.contains("<") || content.contains(">")) { return content.replace("&", "&").replace("<", "<").replace(">", ">"); diff --git a/matsim/src/main/java/org/matsim/facilities/FacilitiesWriterV1.java b/matsim/src/main/java/org/matsim/facilities/FacilitiesWriterV1.java index b312ad56cc6..17751b78d4c 100644 --- a/matsim/src/main/java/org/matsim/facilities/FacilitiesWriterV1.java +++ b/matsim/src/main/java/org/matsim/facilities/FacilitiesWriterV1.java @@ -99,7 +99,6 @@ private void writeFacility(final ActivityFacilityImpl f) { } this.attributesWriter.writeAttributes("\t\t", this.writer, f.getAttributes(), false); this.endFacility(); - this.writer.flush(); } catch (IOException e) { throw new UncheckedIOException(e); } diff --git a/matsim/src/main/java/org/matsim/facilities/FacilitiesWriterV2.java b/matsim/src/main/java/org/matsim/facilities/FacilitiesWriterV2.java index a740d2ae014..d156cda5ff0 100644 --- a/matsim/src/main/java/org/matsim/facilities/FacilitiesWriterV2.java +++ b/matsim/src/main/java/org/matsim/facilities/FacilitiesWriterV2.java @@ -99,7 +99,6 @@ private void writeFacility(final ActivityFacilityImpl f) { } this.attributesWriter.writeAttributes("\t\t", this.writer, f.getAttributes(), false); this.endFacility(); - this.writer.flush(); } catch (IOException e) { throw new UncheckedIOException(e); } diff --git a/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java index 906c97396ee..104860e67bb 100644 --- a/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java +++ b/matsim/src/main/java/org/matsim/pt/utils/CreatePseudoNetwork.java @@ -152,7 +152,14 @@ private Link getNetworkLink(final TransitRouteStop fromStop, final TransitRouteS } Id newId = Id.create(toFacility.getId().toString() + "." + Integer.toString(copies.size() + 1), TransitStopFacility.class); TransitStopFacility newFacility = this.schedule.getFactory().createTransitStopFacility(newId, toFacility.getCoord(), toFacility.getIsBlockingLane()); - newFacility.setStopAreaId(Id.create(toFacility.getId(), TransitStopArea.class)); + Id transitStopAreaId; + if (toFacility.getStopAreaId() == null) { + transitStopAreaId = Id.create(toFacility.getId(), TransitStopArea.class); + toFacility.setStopAreaId(transitStopAreaId); + } else { + transitStopAreaId = toFacility.getStopAreaId(); + } + newFacility.setStopAreaId(transitStopAreaId); newFacility.setLinkId(link.getId()); newFacility.setName(toFacility.getName()); copies.add(newFacility); diff --git a/matsim/src/main/java/org/matsim/pt/utils/CreateVehiclesForSchedule.java b/matsim/src/main/java/org/matsim/pt/utils/CreateVehiclesForSchedule.java index 3adbd0b8407..287fac979f9 100644 --- a/matsim/src/main/java/org/matsim/pt/utils/CreateVehiclesForSchedule.java +++ b/matsim/src/main/java/org/matsim/pt/utils/CreateVehiclesForSchedule.java @@ -21,6 +21,7 @@ package org.matsim.pt.utils; import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.TransportMode; import org.matsim.pt.transitSchedule.api.Departure; import org.matsim.pt.transitSchedule.api.TransitLine; import org.matsim.pt.transitSchedule.api.TransitRoute; @@ -45,13 +46,18 @@ public CreateVehiclesForSchedule(final TransitSchedule schedule, final Vehicles this.schedule = schedule; this.vehicles = vehicles; } - + public void run() { + run(TransportMode.car); + } + + public void run(String networkMode) { VehiclesFactory vb = this.vehicles.getFactory(); VehicleType vehicleType = vb.createVehicleType(Id.create("defaultTransitVehicleType", VehicleType.class)); // VehicleCapacity capacity = new VehicleCapacity(); vehicleType.getCapacity().setSeats( 101 ); vehicleType.getCapacity().setStandingRoom( 0 ); + vehicleType.setNetworkMode(networkMode); // vehicleType.setCapacity(capacity); this.vehicles.addVehicleType(vehicleType); diff --git a/matsim/src/main/java/org/matsim/vehicles/VehicleReaderV1.java b/matsim/src/main/java/org/matsim/vehicles/VehicleReaderV1.java index 697958b0fd6..b2847dc404e 100644 --- a/matsim/src/main/java/org/matsim/vehicles/VehicleReaderV1.java +++ b/matsim/src/main/java/org/matsim/vehicles/VehicleReaderV1.java @@ -3,6 +3,7 @@ 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.utils.io.MatsimXmlParser; import org.xml.sax.Attributes; @@ -38,6 +39,10 @@ public void endTag( final String name, final String content, final Stack public void startTag( final String name, final Attributes atts, final Stack context ){ if( VehicleSchemaV1Names.VEHICLETYPE.equalsIgnoreCase( name ) ){ this.currentVehType = this.builder.createVehicleType( Id.create( atts.getValue( VehicleSchemaV1Names.ID ), VehicleType.class ) ); + // In the old format there is no network mode, and everything was basically a car. + // Vehicle type does not contain a default network mode anymore, therefore we need to set it here. + this.currentVehType.setNetworkMode( TransportMode.car ); + } else if( VehicleSchemaV1Names.LENGTH.equalsIgnoreCase( name ) ){ this.currentVehType.setLength( Double.parseDouble( atts.getValue( VehicleSchemaV1Names.METER ) ) ); } else if( VehicleSchemaV1Names.WIDTH.equalsIgnoreCase( name ) ){ diff --git a/matsim/src/main/java/org/matsim/vehicles/VehicleType.java b/matsim/src/main/java/org/matsim/vehicles/VehicleType.java index 9aef2a705e1..512705d4f0d 100644 --- a/matsim/src/main/java/org/matsim/vehicles/VehicleType.java +++ b/matsim/src/main/java/org/matsim/vehicles/VehicleType.java @@ -26,6 +26,8 @@ import org.matsim.utils.objectattributes.attributable.Attributes; import org.matsim.utils.objectattributes.attributable.AttributesImpl; +import java.util.Objects; + /** * @author dgrether */ @@ -46,13 +48,22 @@ public final class VehicleType implements Attributable, Identifiable id; private final Attributes attributes = new AttributesImpl(); VehicleType( Id typeId ) { this.id = typeId; + // For car typ default network mode is assumed, for others it needs to be set explicitly. + if (typeId != null && Objects.equals(typeId.toString(), TransportMode.car)) + this.networkMode = TransportMode.car; + } + + VehicleType(Id typeId, String networkMode) { + this.id = typeId; + this.networkMode = networkMode; } + public final String getDescription() { return description; } @@ -114,7 +125,7 @@ public final CostInformation getCostInformation() { return costInformation; } public final String getNetworkMode() { - return networkMode; + return Objects.requireNonNull(networkMode, () -> "Network mode not set for vehicle type %s. Network mode needs to be set explicitly for non car modes. You can do this in XML by adding \t\n".formatted(id, id)); } public final VehicleType setNetworkMode( String networkMode ) { this.networkMode = networkMode; diff --git a/matsim/src/main/java/org/matsim/vehicles/VehicleUtils.java b/matsim/src/main/java/org/matsim/vehicles/VehicleUtils.java index aac3e537da9..7c263b086e3 100644 --- a/matsim/src/main/java/org/matsim/vehicles/VehicleUtils.java +++ b/matsim/src/main/java/org/matsim/vehicles/VehicleUtils.java @@ -27,6 +27,7 @@ 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.TransportMode; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.population.Person; import org.matsim.core.gbl.Gbl; @@ -64,6 +65,10 @@ public static VehicleType createVehicleType( Id typeId ){ return new VehicleType( typeId ); } + public static VehicleType createVehicleType( Id typeId, String networkMode){ + return new VehicleType( typeId, networkMode ); + } + public static VehiclesFactory getFactory() { return new VehiclesFactoryImpl(); } @@ -75,9 +80,9 @@ public static Vehicles createVehiclesContainer() { public static VehicleType createDefaultVehicleType() { VehicleType defaultVehicleType = VehicleUtils.getFactory() .createVehicleType(Id.create(DEFAULT_VEHICLE_TYPE_ID, VehicleType.class)); - + defaultVehicleType.getCapacity().setSeats(4); - + defaultVehicleType.setNetworkMode(TransportMode.car); return defaultVehicleType; } @@ -434,7 +439,7 @@ public static void writeVehicles( Vehicles vehicles, String filename ) { new MatsimVehicleWriter( vehicles ).writeFile( filename ); } - + public static Id getInitialLinkId(Vehicle vehicle) { String attribute = (String) vehicle.getAttributes().getAttribute(INITIAL_LINK_ID); return attribute == null ? null : Id.createLinkId(attribute); diff --git a/matsim/src/main/resources/dtd/chargers_v1.dtd b/matsim/src/main/resources/dtd/chargers_v1.dtd index 5e849dddd91..c9c4f13184d 100644 --- a/matsim/src/main/resources/dtd/chargers_v1.dtd +++ b/matsim/src/main/resources/dtd/chargers_v1.dtd @@ -9,7 +9,7 @@ - + @@ -21,3 +21,10 @@ plug_power CDATA #REQUIRED plug_count CDATA #IMPLIED type CDATA #IMPLIED > + + + + + diff --git a/matsim/src/test/java/ch/sbb/matsim/RaptorDeterminismTest.java b/matsim/src/test/java/ch/sbb/matsim/RaptorDeterminismTest.java new file mode 100644 index 00000000000..99689ade903 --- /dev/null +++ b/matsim/src/test/java/ch/sbb/matsim/RaptorDeterminismTest.java @@ -0,0 +1,207 @@ +package ch.sbb.matsim; + +import ch.sbb.matsim.routing.pt.raptor.SwissRailRaptorData; +import ch.sbb.matsim.routing.pt.raptor.RaptorStopFinder; +import ch.sbb.matsim.routing.pt.raptor.RaptorParametersForPerson; +import ch.sbb.matsim.routing.pt.raptor.SwissRailRaptor; +import ch.sbb.matsim.routing.pt.raptor.RaptorParameters; +import ch.sbb.matsim.routing.pt.raptor.InitialStop; +import com.google.inject.Injector; +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.api.core.v01.population.*; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.controler.AbstractModule; +import org.matsim.core.events.EventsManagerModule; +import org.matsim.core.router.TripRouter; +import org.matsim.core.router.TripRouterModule; +import org.matsim.core.router.TripStructureUtils; +import org.matsim.core.router.costcalculators.TravelDisutilityModule; +import org.matsim.core.scenario.ScenarioByInstanceModule; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.core.trafficmonitoring.TravelTimeCalculatorModule; +import org.matsim.core.utils.io.IOUtils; +import org.matsim.core.utils.timing.TimeInterpretationModule; +import org.matsim.examples.ExamplesUtils; +import org.matsim.facilities.ActivityFacilities; +import org.matsim.facilities.FacilitiesUtils; +import org.matsim.facilities.Facility; +import org.matsim.pt.routes.DefaultTransitPassengerRoute; +import org.matsim.pt.transitSchedule.api.TransitStopFacility; + + +import java.net.URL; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; + +public class RaptorDeterminismTest { + + public static boolean comparePlan(List left, List right) { + if(left.size() != right.size()) { + return false; + } + for(int i=0; i[] transitStopFacilitiesByScenario = new List[scenarioSamples]; + List[] personLists = new List[scenarioSamples]; + TripRouter[] tripRouters = new TripRouter[scenarioSamples]; + + logger.info(String.format("Loading scenario %d times", scenarioSamples)); + for(int scenarioIndex=0; scenarioIndex(scenario.getTransitSchedule().getFacilities().values()); + swissRailRaptorData[scenarioIndex] = swissRailRaptors[scenarioIndex].getUnderlyingData(); + personLists[scenarioIndex] = scenario.getPopulation().getPersons().values().stream().toList(); + + tripRouters[scenarioIndex] = injector.getInstance(TripRouter.class); + } + + logger.info(String.format("Comparing stop facilities order %d", scenarioSamples)); + + for(int scenarioIndex=1; scenarioIndex referenceElements = tripRouters[0].calcRoute("pt", fromFacility, toFacility, referenceTrip.getOriginActivity().getEndTime().seconds(), referencePerson, referenceTrip.getTripAttributes()); + + for(int scenarioIndex=1; scenarioIndex referenceInitialStops = raptorStopFinders[0].findStops(fromFacility, toFacility, referencePerson, referenceTrip.getOriginActivity().getEndTime().seconds(), referenceTrip.getTripAttributes(), referenceRaptorParameters, swissRailRaptorData[0], direction); + List sortedReferenceInitialStops = new ArrayList<>(referenceInitialStops); + sortedReferenceInitialStops.sort(Comparator.comparing(InitialStop::toString)); + + List comparedInitialStops = raptorStopFinders[scenarioIndex].findStops(otherFromFacility, otherToFacility, referencePerson, referenceTrip.getOriginActivity().getEndTime().seconds(), referenceTrip.getTripAttributes(), otherRaptorParameters, swissRailRaptorData[scenarioIndex], direction); + + assert referenceInitialStops.size() == comparedInitialStops.size(); + + List sortedComparedInitialStops = new ArrayList<>(comparedInitialStops); + sortedComparedInitialStops.sort(Comparator.comparing(InitialStop::toString)); + for(int j=0; j comparedElements = tripRouters[scenarioIndex].calcRoute("pt", otherFromFacility, otherToFacility, referenceTrip.getOriginActivity().getEndTime().seconds(), otherPerson, referenceTrip.getTripAttributes()); + assert comparePlan(referenceElements, comparedElements); + } + } + } + } + +} diff --git a/matsim/src/test/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysisTest.java b/matsim/src/test/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysisTest.java index 88e5fb60349..f7d680241db 100644 --- a/matsim/src/test/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysisTest.java +++ b/matsim/src/test/java/org/matsim/analysis/pt/stop2stop/PtStop2StopAnalysisTest.java @@ -42,7 +42,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; /** * @author dtamleh @@ -107,7 +106,7 @@ void testPtStop2StopAnalysisSingle() { String networkMode_bus = TransportMode.car; - PtStop2StopAnalysis ptStop2StopAnalysis = new PtStop2StopAnalysis(scenario.getTransitVehicles()); + PtStop2StopAnalysis ptStop2StopAnalysis = new PtStop2StopAnalysis(scenario.getTransitVehicles(), 1.0); ParallelEventsManager events = new ParallelEventsManager(false); events.addHandler(ptStop2StopAnalysis); @@ -141,34 +140,34 @@ void testPtStop2StopAnalysisSingle() { // Tests List line1_route1_dep1_stop1 = ptStop2StopAnalysis.getStop2StopEntriesByDeparture().stream() - .filter(entry -> entry.transitLineId.equals(transitLineId_bus1) && entry.transitRouteId.equals(transitRouteId_bus1_route1) - && entry.departureId.equals(departureId_bus1_route1_dep1) && entry.stopId.equals(transitStopFacilityId1) - && entry.stopSequence == 0).collect(Collectors.toList()); + .filter(entry -> entry.transitLineId().equals(transitLineId_bus1) && entry.transitRouteId().equals(transitRouteId_bus1_route1) + && entry.departureId().equals(departureId_bus1_route1_dep1) && entry.stopId().equals(transitStopFacilityId1) + && entry.stopSequence() == 0).toList(); System.out.println(line1_route1_dep1_stop1.size()); Assertions.assertEquals(1, line1_route1_dep1_stop1.size(), "Either no entry or more than entry for " + transitLineId_bus1 + ", " + transitRouteId_bus1_route1 + ", " + departureId_bus1_route1_dep1 + ", " + departureId_bus1_route1_dep1 + ", " + transitStopFacilityId1 + ", 0"); - Assertions.assertNull(line1_route1_dep1_stop1.get(0).stopPreviousId, "There should be no previous stop, but there was"); - Assertions.assertEquals(1.0, line1_route1_dep1_stop1.get(0).arrivalTimeScheduled, MatsimTestUtils.EPSILON, "Wrong arrivalTimeScheduled"); - Assertions.assertEquals(0.0, line1_route1_dep1_stop1.get(0).arrivalDelay, MatsimTestUtils.EPSILON, "Wrong arrivalDelay"); - Assertions.assertEquals(3.0, line1_route1_dep1_stop1.get(0).departureTimeScheduled, MatsimTestUtils.EPSILON); - Assertions.assertEquals(0.0, line1_route1_dep1_stop1.get(0).departureDelay, MatsimTestUtils.EPSILON); - Assertions.assertEquals(0.0, line1_route1_dep1_stop1.get(0).passengersAtArrival, MatsimTestUtils.EPSILON); - Assertions.assertEquals(veh_bus1.getType().getCapacity().getSeats() + veh_bus1.getType().getCapacity().getStandingRoom(), line1_route1_dep1_stop1.get(0).totalVehicleCapacity, MatsimTestUtils.EPSILON); - Assertions.assertEquals(0.0, line1_route1_dep1_stop1.get(0).passengersAlighting, MatsimTestUtils.EPSILON); - Assertions.assertEquals(2.0, line1_route1_dep1_stop1.get(0).passengersBoarding, MatsimTestUtils.EPSILON); + Assertions.assertNull(line1_route1_dep1_stop1.get(0).stopPreviousId(), "There should be no previous stop, but there was"); + Assertions.assertEquals(1.0, line1_route1_dep1_stop1.get(0).arrivalTimeScheduled(), MatsimTestUtils.EPSILON, "Wrong arrivalTimeScheduled"); + Assertions.assertEquals(0.0, line1_route1_dep1_stop1.get(0).arrivalDelay(), MatsimTestUtils.EPSILON, "Wrong arrivalDelay"); + Assertions.assertEquals(3.0, line1_route1_dep1_stop1.get(0).departureTimeScheduled(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.0, line1_route1_dep1_stop1.get(0).departureDelay(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.0, line1_route1_dep1_stop1.get(0).passengersAtArrival(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(veh_bus1.getType().getCapacity().getSeats() + veh_bus1.getType().getCapacity().getStandingRoom(), line1_route1_dep1_stop1.get(0).totalVehicleCapacity(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.0, line1_route1_dep1_stop1.get(0).passengersAlighting(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2.0, line1_route1_dep1_stop1.get(0).passengersBoarding(), MatsimTestUtils.EPSILON); List> linkList = new ArrayList<>(); linkList.add(linkId1); - Assertions.assertEquals(linkList, line1_route1_dep1_stop1.get(0).linkIdsSincePreviousStop, "Wrong links"); + Assertions.assertEquals(linkList, line1_route1_dep1_stop1.get(0).linkIdsSincePreviousStop(), "Wrong links"); List line1_route1_dep1_stop3 = ptStop2StopAnalysis.getStop2StopEntriesByDeparture().stream() - .filter(entry -> entry.transitLineId.equals(transitLineId_bus1) && entry.transitRouteId.equals(transitRouteId_bus1_route1) - && entry.departureId.equals(departureId_bus1_route1_dep1) && entry.stopId.equals(transitStopFacilityId3) - && entry.stopSequence == 2).collect(Collectors.toList()); + .filter(entry -> entry.transitLineId().equals(transitLineId_bus1) && entry.transitRouteId().equals(transitRouteId_bus1_route1) + && entry.departureId().equals(departureId_bus1_route1_dep1) && entry.stopId().equals(transitStopFacilityId3) + && entry.stopSequence() == 2).toList(); Assertions.assertEquals(1, line1_route1_dep1_stop3.size(), "Either no entry or more than entry for " + transitLineId_bus1 + ", " + transitRouteId_bus1_route1 + ", " + departureId_bus1_route1_dep1 + ", " + departureId_bus1_route1_dep1 + ", " + transitStopFacilityId3 + ", 0"); - Assertions.assertEquals(transitStopFacilityId2, line1_route1_dep1_stop3.get(0).stopPreviousId, "There is no previous stop"); - Assertions.assertEquals(12.0, line1_route1_dep1_stop3.get(0).departureTimeScheduled, MatsimTestUtils.EPSILON); - Assertions.assertEquals(12.0, line1_route1_dep1_stop3.get(0).arrivalTimeScheduled, MatsimTestUtils.EPSILON, "Wrong arrivalTimeScheduled"); - Assertions.assertEquals(-1.0, line1_route1_dep1_stop3.get(0).arrivalDelay, MatsimTestUtils.EPSILON, "Wrong arrival delay"); - Assertions.assertEquals(1.0, line1_route1_dep1_stop3.get(0).departureDelay, MatsimTestUtils.EPSILON, "Wrong departure delay"); + Assertions.assertEquals(transitStopFacilityId2, line1_route1_dep1_stop3.get(0).stopPreviousId(), "There is no previous stop"); + Assertions.assertEquals(12.0, line1_route1_dep1_stop3.get(0).departureTimeScheduled(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(12.0, line1_route1_dep1_stop3.get(0).arrivalTimeScheduled(), MatsimTestUtils.EPSILON, "Wrong arrivalTimeScheduled"); + Assertions.assertEquals(-1.0, line1_route1_dep1_stop3.get(0).arrivalDelay(), MatsimTestUtils.EPSILON, "Wrong arrival delay"); + Assertions.assertEquals(1.0, line1_route1_dep1_stop3.get(0).departureDelay(), MatsimTestUtils.EPSILON, "Wrong departure delay"); } // ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ @@ -257,7 +256,7 @@ void testPtStop2StopAnalysisMulti() { String networkMode_bus = TransportMode.car; String networkMode_train = TransportMode.train; - PtStop2StopAnalysis ptStop2StopAnalysis = new PtStop2StopAnalysis(scenario.getTransitVehicles()); + PtStop2StopAnalysis ptStop2StopAnalysis = new PtStop2StopAnalysis(scenario.getTransitVehicles(), 1.0); ParallelEventsManager events = new ParallelEventsManager(false); events.addHandler(ptStop2StopAnalysis); @@ -444,54 +443,54 @@ void testPtStop2StopAnalysisMulti() { // Tests - List bus1_dep1_stop1 = ptStop2StopAnalysis.getStop2StopEntriesByDeparture().stream().filter(entry -> entry.transitLineId.equals(transitLineId_bus1) && entry.transitRouteId.equals(transitRouteId_bus1_route1) && entry.departureId.equals(departureId_bus1_dep1) && entry.stopId.equals(transitStopFacilityId1) && entry.stopSequence == 0).collect(Collectors.toList()); + List bus1_dep1_stop1 = ptStop2StopAnalysis.getStop2StopEntriesByDeparture().stream().filter(entry -> entry.transitLineId().equals(transitLineId_bus1) && entry.transitRouteId().equals(transitRouteId_bus1_route1) && entry.departureId().equals(departureId_bus1_dep1) && entry.stopId().equals(transitStopFacilityId1) && entry.stopSequence() == 0).toList(); Assertions.assertEquals(1, bus1_dep1_stop1.size(), "Either no entry or more than entry for " + transitLineId_bus1 + ", " + transitRouteId_bus1_route1 + ", " + departureId_bus1_dep1 + ", " + departureId_bus1_dep1 + ", " + transitStopFacilityId1 + ", 0"); - Assertions.assertNull(bus1_dep1_stop1.get(0).stopPreviousId, "There should be no previous stop, but there was"); - Assertions.assertEquals(1.0, bus1_dep1_stop1.get(0).arrivalTimeScheduled, MatsimTestUtils.EPSILON, "Wrong arrivalTimeScheduled"); - Assertions.assertEquals(0.0, bus1_dep1_stop1.get(0).arrivalDelay, MatsimTestUtils.EPSILON, "Wrong arrivalDelay"); - Assertions.assertEquals(3.0, bus1_dep1_stop1.get(0).departureTimeScheduled, MatsimTestUtils.EPSILON); - Assertions.assertEquals(0.0, bus1_dep1_stop1.get(0).departureDelay, MatsimTestUtils.EPSILON); - Assertions.assertEquals(0.0, bus1_dep1_stop1.get(0).passengersAtArrival, MatsimTestUtils.EPSILON); - Assertions.assertEquals(veh_bus1_dep1.getType().getCapacity().getSeats() + veh_bus1_dep1.getType().getCapacity().getStandingRoom(), bus1_dep1_stop1.get(0).totalVehicleCapacity, MatsimTestUtils.EPSILON); - Assertions.assertEquals(0.0, bus1_dep1_stop1.get(0).passengersAlighting, MatsimTestUtils.EPSILON); - Assertions.assertEquals(2.0, bus1_dep1_stop1.get(0).passengersBoarding, MatsimTestUtils.EPSILON); + Assertions.assertNull(bus1_dep1_stop1.get(0).stopPreviousId(), "There should be no previous stop, but there was"); + Assertions.assertEquals(1.0, bus1_dep1_stop1.get(0).arrivalTimeScheduled(), MatsimTestUtils.EPSILON, "Wrong arrivalTimeScheduled"); + Assertions.assertEquals(0.0, bus1_dep1_stop1.get(0).arrivalDelay(), MatsimTestUtils.EPSILON, "Wrong arrivalDelay"); + Assertions.assertEquals(3.0, bus1_dep1_stop1.get(0).departureTimeScheduled(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.0, bus1_dep1_stop1.get(0).departureDelay(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.0, bus1_dep1_stop1.get(0).passengersAtArrival(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(veh_bus1_dep1.getType().getCapacity().getSeats() + veh_bus1_dep1.getType().getCapacity().getStandingRoom(), bus1_dep1_stop1.get(0).totalVehicleCapacity(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.0, bus1_dep1_stop1.get(0).passengersAlighting(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2.0, bus1_dep1_stop1.get(0).passengersBoarding(), MatsimTestUtils.EPSILON); List> linkList = new ArrayList<>(); linkList.add(linkId1); - Assertions.assertEquals(linkList, bus1_dep1_stop1.get(0).linkIdsSincePreviousStop, "Wrong links"); + Assertions.assertEquals(linkList, bus1_dep1_stop1.get(0).linkIdsSincePreviousStop(), "Wrong links"); - List bus1_dep1_stop3 = ptStop2StopAnalysis.getStop2StopEntriesByDeparture().stream().filter(entry -> entry.transitLineId.equals(transitLineId_bus1) && entry.transitRouteId.equals(transitRouteId_bus1_route1) && entry.departureId.equals(departureId_bus1_dep1) && entry.stopId.equals(transitStopFacilityId4) && entry.stopSequence == 2).collect(Collectors.toList()); + List bus1_dep1_stop3 = ptStop2StopAnalysis.getStop2StopEntriesByDeparture().stream().filter(entry -> entry.transitLineId().equals(transitLineId_bus1) && entry.transitRouteId().equals(transitRouteId_bus1_route1) && entry.departureId().equals(departureId_bus1_dep1) && entry.stopId().equals(transitStopFacilityId4) && entry.stopSequence() == 2).toList(); System.out.println(bus1_dep1_stop3.isEmpty()); Assertions.assertEquals(1, bus1_dep1_stop3.size(), "Either no entry or more than entry for " + transitLineId_bus1 + ", " + transitRouteId_bus1_route1 + ", " + departureId_bus1_dep1 + ", " + departureId_bus1_dep1 + ", " + transitStopFacilityId4 + ", 0"); - Assertions.assertEquals(0.0, bus1_dep1_stop3.get(0).arrivalDelay, MatsimTestUtils.EPSILON, "Wrong arrivalDelay"); - Assertions.assertEquals(15.0, bus1_dep1_stop3.get(0).departureTimeScheduled, MatsimTestUtils.EPSILON); - Assertions.assertEquals(0.0, bus1_dep1_stop3.get(0).departureDelay, MatsimTestUtils.EPSILON); - Assertions.assertEquals(3.0, bus1_dep1_stop3.get(0).passengersAtArrival, MatsimTestUtils.EPSILON); - Assertions.assertEquals(veh_bus1_dep1.getType().getCapacity().getSeats() + veh_bus1_dep1.getType().getCapacity().getStandingRoom(), bus1_dep1_stop1.get(0).totalVehicleCapacity, MatsimTestUtils.EPSILON); - Assertions.assertEquals(3.0, bus1_dep1_stop3.get(0).passengersAlighting, MatsimTestUtils.EPSILON); - Assertions.assertEquals(0.0, bus1_dep1_stop3.get(0).passengersBoarding, MatsimTestUtils.EPSILON); - - List bus1_dep1_stop4 = ptStop2StopAnalysis.getStop2StopEntriesByDeparture().stream().filter(entry -> entry.transitLineId.equals(transitLineId_bus1) && entry.transitRouteId.equals(transitRouteId_bus1_route2) && entry.departureId.equals(departureId_bus1_dep1) && entry.stopId.equals(transitStopFacilityId2) && entry.stopSequence == 1).collect(Collectors.toList()); + Assertions.assertEquals(0.0, bus1_dep1_stop3.get(0).arrivalDelay(), MatsimTestUtils.EPSILON, "Wrong arrivalDelay"); + Assertions.assertEquals(15.0, bus1_dep1_stop3.get(0).departureTimeScheduled(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.0, bus1_dep1_stop3.get(0).departureDelay(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3.0, bus1_dep1_stop3.get(0).passengersAtArrival(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(veh_bus1_dep1.getType().getCapacity().getSeats() + veh_bus1_dep1.getType().getCapacity().getStandingRoom(), bus1_dep1_stop1.get(0).totalVehicleCapacity(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(3.0, bus1_dep1_stop3.get(0).passengersAlighting(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.0, bus1_dep1_stop3.get(0).passengersBoarding(), MatsimTestUtils.EPSILON); + + List bus1_dep1_stop4 = ptStop2StopAnalysis.getStop2StopEntriesByDeparture().stream().filter(entry -> entry.transitLineId().equals(transitLineId_bus1) && entry.transitRouteId().equals(transitRouteId_bus1_route2) && entry.departureId().equals(departureId_bus1_dep1) && entry.stopId().equals(transitStopFacilityId2) && entry.stopSequence() == 1).toList(); Assertions.assertEquals(1, bus1_dep1_stop4.size(), "Either no entry or more than entry for " + transitLineId_bus1 + ", " + transitRouteId_bus1_route2 + ", " + departureId_bus1_dep1 + ", " + departureId_bus1_dep1 + ", " + transitStopFacilityId2 + ", 0"); - Assertions.assertEquals(28.0, bus1_dep1_stop4.get(0).arrivalTimeScheduled, MatsimTestUtils.EPSILON, "Wrong arrivalTimeScheduled"); - Assertions.assertEquals(0.0, bus1_dep1_stop4.get(0).arrivalDelay, MatsimTestUtils.EPSILON, "Wrong arrivalDelay"); - Assertions.assertEquals(29.0, bus1_dep1_stop4.get(0).departureTimeScheduled, MatsimTestUtils.EPSILON); - Assertions.assertEquals(0.0, bus1_dep1_stop4.get(0).departureDelay, MatsimTestUtils.EPSILON); - Assertions.assertEquals(5.0, bus1_dep1_stop4.get(0).passengersAtArrival, MatsimTestUtils.EPSILON); - Assertions.assertEquals(veh_bus1_dep1.getType().getCapacity().getSeats() + veh_bus1_dep1.getType().getCapacity().getStandingRoom(), bus1_dep1_stop1.get(0).totalVehicleCapacity, MatsimTestUtils.EPSILON); - Assertions.assertEquals(2.0, bus1_dep1_stop4.get(0).passengersAlighting, MatsimTestUtils.EPSILON); - Assertions.assertEquals(2.0, bus1_dep1_stop4.get(0).passengersBoarding, MatsimTestUtils.EPSILON); - - List train1_dep1_stop4 = ptStop2StopAnalysis.getStop2StopEntriesByDeparture().stream().filter(entry -> entry.transitLineId.equals(transitLineId_train1) && entry.transitRouteId.equals(transitRouteId_train1_route1) && entry.departureId.equals(departureId_train1_dep1) && entry.stopId.equals(transitStopFacilityId6) && entry.stopSequence == 3).collect(Collectors.toList()); + Assertions.assertEquals(28.0, bus1_dep1_stop4.get(0).arrivalTimeScheduled(), MatsimTestUtils.EPSILON, "Wrong arrivalTimeScheduled"); + Assertions.assertEquals(0.0, bus1_dep1_stop4.get(0).arrivalDelay(), MatsimTestUtils.EPSILON, "Wrong arrivalDelay"); + Assertions.assertEquals(29.0, bus1_dep1_stop4.get(0).departureTimeScheduled(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.0, bus1_dep1_stop4.get(0).departureDelay(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(5.0, bus1_dep1_stop4.get(0).passengersAtArrival(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(veh_bus1_dep1.getType().getCapacity().getSeats() + veh_bus1_dep1.getType().getCapacity().getStandingRoom(), bus1_dep1_stop1.get(0).totalVehicleCapacity(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2.0, bus1_dep1_stop4.get(0).passengersAlighting(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2.0, bus1_dep1_stop4.get(0).passengersBoarding(), MatsimTestUtils.EPSILON); + + List train1_dep1_stop4 = ptStop2StopAnalysis.getStop2StopEntriesByDeparture().stream().filter(entry -> entry.transitLineId().equals(transitLineId_train1) && entry.transitRouteId().equals(transitRouteId_train1_route1) && entry.departureId().equals(departureId_train1_dep1) && entry.stopId().equals(transitStopFacilityId6) && entry.stopSequence() == 3).toList(); Assertions.assertEquals(1, train1_dep1_stop4.size(), "Either no entry or more than entry for " + transitLineId_train1 + ", " + transitRouteId_train1_route1 + ", " + departureId_train1_dep1 + ", " + transitStopFacilityId6 + ", 0"); - Assertions.assertEquals(19.0, train1_dep1_stop4.get(0).arrivalTimeScheduled, MatsimTestUtils.EPSILON, "Wrong arrivalTimeScheduled"); - Assertions.assertEquals(0.0, train1_dep1_stop4.get(0).arrivalDelay, MatsimTestUtils.EPSILON, "Wrong arrivalDelay"); - Assertions.assertEquals(21.0, train1_dep1_stop4.get(0).departureTimeScheduled, MatsimTestUtils.EPSILON); - Assertions.assertEquals(0.0, train1_dep1_stop4.get(0).departureDelay, MatsimTestUtils.EPSILON); - Assertions.assertEquals(6.0, train1_dep1_stop4.get(0).passengersAtArrival, MatsimTestUtils.EPSILON); - Assertions.assertEquals(veh_bus1_dep1.getType().getCapacity().getSeats() + veh_bus1_dep1.getType().getCapacity().getStandingRoom(), bus1_dep1_stop1.get(0).totalVehicleCapacity, MatsimTestUtils.EPSILON); - Assertions.assertEquals(4.0, train1_dep1_stop4.get(0).passengersAlighting, MatsimTestUtils.EPSILON); - Assertions.assertEquals(1.0, train1_dep1_stop4.get(0).passengersBoarding, MatsimTestUtils.EPSILON); + Assertions.assertEquals(19.0, train1_dep1_stop4.get(0).arrivalTimeScheduled(), MatsimTestUtils.EPSILON, "Wrong arrivalTimeScheduled"); + Assertions.assertEquals(0.0, train1_dep1_stop4.get(0).arrivalDelay(), MatsimTestUtils.EPSILON, "Wrong arrivalDelay"); + Assertions.assertEquals(21.0, train1_dep1_stop4.get(0).departureTimeScheduled(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(0.0, train1_dep1_stop4.get(0).departureDelay(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(6.0, train1_dep1_stop4.get(0).passengersAtArrival(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(veh_bus1_dep1.getType().getCapacity().getSeats() + veh_bus1_dep1.getType().getCapacity().getStandingRoom(), bus1_dep1_stop1.get(0).totalVehicleCapacity(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(4.0, train1_dep1_stop4.get(0).passengersAlighting(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(1.0, train1_dep1_stop4.get(0).passengersBoarding(), MatsimTestUtils.EPSILON); } -} \ No newline at end of file +} diff --git a/matsim/src/test/java/org/matsim/core/controler/OutputDirectoryHierarchyTest.java b/matsim/src/test/java/org/matsim/core/controler/OutputDirectoryHierarchyTest.java index 5fa3ccb628a..8a1f9c7ce16 100644 --- a/matsim/src/test/java/org/matsim/core/controler/OutputDirectoryHierarchyTest.java +++ b/matsim/src/test/java/org/matsim/core/controler/OutputDirectoryHierarchyTest.java @@ -21,14 +21,26 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.population.Activity; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; import org.matsim.core.config.groups.ControllerConfigGroup; +import org.matsim.core.controler.OutputDirectoryHierarchy.OverwriteFileSetting; +import org.matsim.core.scenario.ScenarioUtils; import org.matsim.core.utils.io.IOUtils; +import org.matsim.examples.ExamplesUtils; import org.matsim.testcases.MatsimTestUtils; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import java.io.UncheckedIOException; +import java.net.URL; +import java.util.Set; +import java.util.stream.Collectors; /** * @author thibautd @@ -146,4 +158,29 @@ void testDeleteIfDirectoryExists() { "Directory was not cleared" ); } + + @Test + void testTmpDir() { + + String javaTempDir = System.getProperty("java.io.tmpdir"); + System.setProperty(OutputDirectoryHierarchy.MATSIM_TEMP_DIR_PROPERTY, javaTempDir); + Assertions.assertNotNull(javaTempDir); + + System.setProperty("matsim.preferLocalDtds", "true"); + + URL scenarioURL = ExamplesUtils.getTestScenarioURL("siouxfalls-2014"); + + Config config = ConfigUtils.loadConfig(IOUtils.extendUrl(scenarioURL, "config_default.xml")); + config.controller().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setLastIteration(1); + + Scenario scenario = ScenarioUtils.loadScenario(config); + + Controler controller = new Controler(scenario); + controller.run(); + + String matsimTempDir = controller.getControlerIO().getTempPath(); + Assertions.assertEquals(javaTempDir, matsimTempDir); + } + } diff --git a/matsim/src/test/java/org/matsim/core/mobsim/qsim/qnetsimengine/SpeedCalculatorTest.java b/matsim/src/test/java/org/matsim/core/mobsim/qsim/qnetsimengine/SpeedCalculatorTest.java index ed394e4bd46..a697a42a9a7 100644 --- a/matsim/src/test/java/org/matsim/core/mobsim/qsim/qnetsimengine/SpeedCalculatorTest.java +++ b/matsim/src/test/java/org/matsim/core/mobsim/qsim/qnetsimengine/SpeedCalculatorTest.java @@ -40,7 +40,7 @@ public class SpeedCalculatorTest{ @Test void limitedByVehicleSpeed() { Link link = createLinkWithNoGradientAndNoSpecialSurface(); - VehicleType type = VehicleUtils.createVehicleType(Id.create("no-bike", VehicleType.class ) ); + VehicleType type = VehicleUtils.createVehicleType(Id.create("no-bike", VehicleType.class ), TransportMode.car ); type.setMaximumVelocity(link.getFreespeed() / 2); // less than the link's freespeed QVehicle vehicle = new QVehicleImpl(VehicleUtils.createVehicle(Id.createVehicleId(1), type)); @@ -55,7 +55,7 @@ void limitedByLinkSpeed() { Link link = createLinkWithNoGradientAndNoSpecialSurface(); - VehicleType type = VehicleUtils.createVehicleType(Id.create("no-bike", VehicleType.class ) ); + VehicleType type = VehicleUtils.createVehicleType(Id.create("no-bike", VehicleType.class ), TransportMode.car ); type.setMaximumVelocity(link.getFreespeed() * 2); // _more_ than the link's freespeed QVehicle vehicle = new QVehicleImpl(VehicleUtils.createVehicle(Id.createVehicleId(1), type)); diff --git a/matsim/src/test/java/org/matsim/core/router/AbstractLeastCostPathCalculatorTestWithTurnRestrictions.java b/matsim/src/test/java/org/matsim/core/router/AbstractLeastCostPathCalculatorTestWithTurnRestrictions.java index 11e4ddfc1ce..3d96cd73091 100644 --- a/matsim/src/test/java/org/matsim/core/router/AbstractLeastCostPathCalculatorTestWithTurnRestrictions.java +++ b/matsim/src/test/java/org/matsim/core/router/AbstractLeastCostPathCalculatorTestWithTurnRestrictions.java @@ -1,12 +1,6 @@ package org.matsim.core.router; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.io.IOException; -import java.util.Arrays; - -import javax.xml.parsers.ParserConfigurationException; - +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; @@ -17,23 +11,27 @@ import org.matsim.api.core.v01.network.Node; import org.matsim.core.config.Config; import org.matsim.core.network.NetworkUtils; -import org.matsim.core.network.io.MatsimNetworkReader; import org.matsim.core.router.util.LeastCostPathCalculator; import org.matsim.core.router.util.LeastCostPathCalculator.Path; import org.matsim.core.scenario.ScenarioUtils; -import org.matsim.testcases.MatsimTestUtils; import org.xml.sax.SAXException; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.assertEquals; + public abstract class AbstractLeastCostPathCalculatorTestWithTurnRestrictions extends AbstractLeastCostPathCalculatorTest { @Test void testCalcLeastCostPath_TurnRestrictions() throws SAXException, ParserConfigurationException, IOException { Network network = createTurnRestrictionsTestNetwork(); - + Node nodeS = network.getNodes().get(Id.create("S", Node.class)); Node nodeT = network.getNodes().get(Id.create("T", Node.class)); LeastCostPathCalculator routerAlgo = getLeastCostPathCalculator(network); - Path path = routerAlgo.calcLeastCostPath(nodeS, nodeT, 8.0*3600, null, null); + Path path = routerAlgo.calcLeastCostPath(nodeS, nodeT, 8.0 * 3600, null, null); assertEquals(7, path.nodes.size(), "number of nodes wrong."); assertEquals(6, path.links.size(), "number of links wrong."); @@ -45,7 +43,7 @@ void testCalcLeastCostPath_TurnRestrictions() throws SAXException, ParserConfigu assertEquals(network.getNodes().get(Id.create("4", Node.class)), path.nodes.get(4)); assertEquals(network.getNodes().get(Id.create("5", Node.class)), path.nodes.get(5)); assertEquals(network.getNodes().get(Id.create("T", Node.class)), path.nodes.get(6)); - + assertEquals(network.getLinks().get(Id.create("S1", Link.class)), path.links.get(0)); assertEquals(network.getLinks().get(Id.create("12", Link.class)), path.links.get(1)); assertEquals(network.getLinks().get(Id.create("23", Link.class)), path.links.get(2)); @@ -54,9 +52,46 @@ void testCalcLeastCostPath_TurnRestrictions() throws SAXException, ParserConfigu assertEquals(network.getLinks().get(Id.create("5T", Link.class)), path.links.get(5)); } + @Test + void testCalcLeastCostPath_TurnRestrictions_IntermediateNode() { + Network network = createTurnRestrictionsTestNetwork(); + + Node nodeS = network.getNodes().get(Id.create("S", Node.class)); + Node node3 = network.getNodes().get(Id.create("3", Node.class)); + + LeastCostPathCalculator routerAlgo = getLeastCostPathCalculator(network); + Path path = routerAlgo.calcLeastCostPath(nodeS, node3, 8.0 * 3600, null, null); + Assertions.assertNotNull(path); + } + + @Test + void testCalcLeastCostPath_TurnRestrictions_simple() { + Network network = createTurnRestrictionsTestNetwork(); + + Node nodeS = network.getNodes().get(Id.create("S", Node.class)); + Node node1 = network.getNodes().get(Id.create("1", Node.class)); + + LeastCostPathCalculator routerAlgo = getLeastCostPathCalculator(network); + Path path = routerAlgo.calcLeastCostPath(nodeS, node1, 8.0 * 3600, null, null); + Assertions.assertNotNull(path); + } + + @Test + void testCalcLeastCostPath_noTurnRestrictions_simple() { + Network network = createTurnRestrictionsTestNetwork(); + + Node nodeS = network.getNodes().get(Id.create("5", Node.class)); + Node node1 = network.getNodes().get(Id.create("T", Node.class)); + + LeastCostPathCalculator routerAlgo = getLeastCostPathCalculator(network); + Path path = routerAlgo.calcLeastCostPath(nodeS, node1, 8.0 * 3600, null, null); + Assertions.assertNotNull(path); + } + + //@formatter:off /** * Creates a test network where the shortest path is impossible due to turn restrictions - * + * * S * | * \/ @@ -64,36 +99,37 @@ void testCalcLeastCostPath_TurnRestrictions() throws SAXException, ParserConfigu * | / /\ * \/ / | * 3--->4--->5 - * + * * Where S1 -> 1T and 23 -> 34 -> 4T are forbidden. - * + * * @return */ - private Network createTurnRestrictionsTestNetwork() { - Config config = utils.loadConfig((String)null); + //@formatter:on + private Network createTurnRestrictionsTestNetwork() { + Config config = utils.loadConfig((String) null); Scenario scenario = ScenarioUtils.createScenario(config); - final Network network = scenario.getNetwork(); - - final Node nodeS = NetworkUtils.createAndAddNode(network, Id.createNodeId("S"), new Coord(1,2)); - final Node node1 = NetworkUtils.createAndAddNode(network, Id.createNodeId("1"), new Coord(1,1)); - final Node node2 = NetworkUtils.createAndAddNode(network, Id.createNodeId("2"), new Coord(0,1)); - final Node node3 = NetworkUtils.createAndAddNode(network, Id.createNodeId("3"), new Coord(0,0)); - final Node node4 = NetworkUtils.createAndAddNode(network, Id.createNodeId("4"), new Coord(1,0)); - final Node node5 = NetworkUtils.createAndAddNode(network, Id.createNodeId("5"), new Coord(2,0)); - final Node nodeT = NetworkUtils.createAndAddNode(network, Id.createNodeId("T"), new Coord(2,0)); - - final Link linkS1 = NetworkUtils.createAndAddLink(network, Id.createLinkId("S1"), nodeS, node1, 1, 1,1, 1); - NetworkUtils.createAndAddLink(network, Id.createLinkId("12"), node1, node2, 1, 1,1, 1); - NetworkUtils.createAndAddLink(network, Id.createLinkId("1T"), node1, nodeT, 1, 1,1, 1); - final Link link23 = NetworkUtils.createAndAddLink(network, Id.createLinkId("23"), node2, node3, 1, 1,1, 1); - NetworkUtils.createAndAddLink(network, Id.createLinkId("34"), node3, node4, 1, 1,1, 1); - NetworkUtils.createAndAddLink(network, Id.createLinkId("4T"), node4, nodeT, 1, 1,1, 1); - NetworkUtils.createAndAddLink(network, Id.createLinkId("45"), node4, node5, 1, 1,1, 1); - NetworkUtils.createAndAddLink(network, Id.createLinkId("5T"), node5, nodeT, 1, 1,1, 1); - - NetworkUtils.addDisallowedNextLinks(linkS1, TransportMode.car, Arrays.asList(Id.createLinkId("1T"))); - NetworkUtils.addDisallowedNextLinks(link23, TransportMode.car, Arrays.asList(Id.createLinkId("34"), Id.createLinkId("4T"))); - - return network; - } + final Network network = scenario.getNetwork(); + + final Node nodeS = NetworkUtils.createAndAddNode(network, Id.createNodeId("S"), new Coord(1, 2)); + final Node node1 = NetworkUtils.createAndAddNode(network, Id.createNodeId("1"), new Coord(1, 1)); + final Node node2 = NetworkUtils.createAndAddNode(network, Id.createNodeId("2"), new Coord(0, 1)); + final Node node3 = NetworkUtils.createAndAddNode(network, Id.createNodeId("3"), new Coord(0, 0)); + final Node node4 = NetworkUtils.createAndAddNode(network, Id.createNodeId("4"), new Coord(1, 0)); + final Node node5 = NetworkUtils.createAndAddNode(network, Id.createNodeId("5"), new Coord(2, 0)); + final Node nodeT = NetworkUtils.createAndAddNode(network, Id.createNodeId("T"), new Coord(2, 0)); + + final Link linkS1 = NetworkUtils.createAndAddLink(network, Id.createLinkId("S1"), nodeS, node1, 1, 1, 1, 1); + NetworkUtils.createAndAddLink(network, Id.createLinkId("12"), node1, node2, 1, 1, 1, 1); + NetworkUtils.createAndAddLink(network, Id.createLinkId("1T"), node1, nodeT, 1, 1, 1, 1); + final Link link23 = NetworkUtils.createAndAddLink(network, Id.createLinkId("23"), node2, node3, 1, 1, 1, 1); + NetworkUtils.createAndAddLink(network, Id.createLinkId("34"), node3, node4, 1, 1, 1, 1); + NetworkUtils.createAndAddLink(network, Id.createLinkId("4T"), node4, nodeT, 1, 1, 1, 1); + NetworkUtils.createAndAddLink(network, Id.createLinkId("45"), node4, node5, 1, 1, 1, 1); + NetworkUtils.createAndAddLink(network, Id.createLinkId("5T"), node5, nodeT, 1, 1, 1, 1); + + NetworkUtils.addDisallowedNextLinks(linkS1, TransportMode.car, Arrays.asList(Id.createLinkId("1T"))); + NetworkUtils.addDisallowedNextLinks(link23, TransportMode.car, Arrays.asList(Id.createLinkId("34"), Id.createLinkId("4T"))); + + return network; + } } diff --git a/matsim/src/test/java/org/matsim/core/router/MultimodalLinkChooserTest.java b/matsim/src/test/java/org/matsim/core/router/MultimodalLinkChooserDefaultImplTest.java similarity index 92% rename from matsim/src/test/java/org/matsim/core/router/MultimodalLinkChooserTest.java rename to matsim/src/test/java/org/matsim/core/router/MultimodalLinkChooserDefaultImplTest.java index 78a0dba6426..cb93b4aff0b 100644 --- a/matsim/src/test/java/org/matsim/core/router/MultimodalLinkChooserTest.java +++ b/matsim/src/test/java/org/matsim/core/router/MultimodalLinkChooserDefaultImplTest.java @@ -41,7 +41,7 @@ * */ -public class MultimodalLinkChooserTest { +public class MultimodalLinkChooserDefaultImplTest { @Test void testDecideOnLink() { @@ -75,11 +75,13 @@ void testDecideOnLink() { MultimodalLinkChooser linkChooser = new MultimodalLinkChooserDefaultImpl(); - Link linkFromFacLinkId = linkChooser.decideOnLink(facilityLinkIdNotNull, network); + RoutingRequest request = DefaultRoutingRequest.of(facilityLinkIdNotNull, facilityLinkIdNull, 0, null, null); + + Link linkFromFacLinkId = linkChooser.decideAccessLink(request, network); Assertions.assertEquals(networkLink, linkFromFacLinkId); - Link linkFromFacCoord = linkChooser.decideOnLink(facilityLinkIdNull, network); + Link linkFromFacCoord = linkChooser.decideEgressLink(request, network); Assertions.assertEquals(networkLink, linkFromFacCoord);