From df25a0b64f75db82cd9e0d0fcc38e55a9fc1fdd0 Mon Sep 17 00:00:00 2001 From: GregorRyb Date: Tue, 4 Jul 2023 13:49:30 +0200 Subject: [PATCH 01/28] Started code review, changes, so it complies with vsp defaults --- pom.xml | 7 +- .../metropole-ruhr-v1.4-10pct.config.xml | 24 ++- .../input/metropole-ruhr-v1.4-3pct.config.xml | 25 ++- .../matsim/run/RunMetropoleRuhrScenario.java | 108 +++++------- .../org/matsim/run/StrategyWeightFadeout.java | 158 ------------------ 5 files changed, 83 insertions(+), 239 deletions(-) delete mode 100644 src/main/java/org/matsim/run/StrategyWeightFadeout.java diff --git a/pom.xml b/pom.xml index 1ae70bc..3b514e2 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - 15.0-PR2431 + 16.0-PR2673 UTF-8 UTF-8 @@ -127,6 +127,11 @@ application ${matsim.version} + + org.matsim.contrib + simwrapper + ${matsim.version} + org.matsim.contrib vsp diff --git a/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-10pct.config.xml b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-10pct.config.xml index 67a7b90..7062549 100644 --- a/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-10pct.config.xml +++ b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-10pct.config.xml @@ -25,7 +25,7 @@ - + + + + + + + + + + + + + + + + @@ -85,8 +100,7 @@ - - + @@ -104,10 +118,10 @@ - + - + diff --git a/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml index 9ba4f7c..a145342 100644 --- a/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml +++ b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml @@ -25,7 +25,7 @@ - + + + + + + + + + + + + + + + + + @@ -85,8 +101,7 @@ - - + @@ -104,10 +119,10 @@ - + - + diff --git a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java index d29480d..cc4ea0b 100644 --- a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java +++ b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java @@ -36,13 +36,15 @@ import org.matsim.api.core.v01.TransportMode; import org.matsim.application.MATSimApplication; import org.matsim.application.analysis.traffic.LinkStats; -import org.matsim.application.analysis.travelTimeValidation.TravelTimeAnalysis; import org.matsim.application.options.SampleOptions; import org.matsim.contrib.bicycle.BicycleConfigGroup; +import org.matsim.contrib.bicycle.BicycleModule; import org.matsim.contrib.bicycle.Bicycles; +import org.matsim.contrib.vsp.scenario.SnzActivities; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.config.groups.ChangeModeConfigGroup; +import org.matsim.core.config.groups.FacilitiesConfigGroup; import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; import org.matsim.core.config.groups.SubtourModeChoiceConfigGroup; import org.matsim.core.controler.AbstractModule; @@ -61,6 +63,8 @@ import org.matsim.prepare.AdjustDemand; import org.matsim.prepare.CreateSupply; import org.matsim.prepare.RuhrUtils; +import org.matsim.simwrapper.SimWrapperConfigGroup; +import org.matsim.simwrapper.SimWrapperModule; import org.matsim.vehicles.VehicleType; import picocli.CommandLine; import playground.vsp.scoring.IncomeDependentUtilityOfMoneyPersonScoringParameters; @@ -78,7 +82,7 @@ @CommandLine.Command(header = ":: Open Metropole Ruhr Scenario ::", version = RunMetropoleRuhrScenario.VERSION, showDefaultValues = true) @MATSimApplication.Analysis({ - TravelTimeAnalysis.class, LinkStats.class, TripMatrix.class + LinkStats.class, TripMatrix.class }) @MATSimApplication.Prepare({AdjustDemand.class}) public class RunMetropoleRuhrScenario extends MATSimApplication { @@ -137,6 +141,9 @@ protected Config prepareConfig(Config config) { PtIntermodalRoutingModesConfigGroup ptIntermodalRoutingModesConfigGroup = ConfigUtils.addOrGetModule(config, PtIntermodalRoutingModesConfigGroup.class); SwissRailRaptorConfigGroup swissRailRaptorConfigGroup = ConfigUtils.addOrGetModule(config, SwissRailRaptorConfigGroup.class); + // because vsp default reasons + config.facilities().setFacilitiesSource(FacilitiesConfigGroup.FacilitiesSource.onePerActivityLinkInPlansFile); + if (!intermodal) { log.info("Disabling intermodal config..."); @@ -189,9 +196,11 @@ protected Config prepareConfig(Config config) { OutputDirectoryLogging.catchLogEntries(); + // bike contrib is needed for bike highways and elevation routing BicycleConfigGroup bikeConfigGroup = ConfigUtils.addOrGetModule(config, BicycleConfigGroup.class); bikeConfigGroup.setBicycleMode(TransportMode.bike); + // this is needed for the parking cost money events ParkingCostConfigGroup parkingCostConfigGroup = ConfigUtils.addOrGetModule(config, ParkingCostConfigGroup.class); parkingCostConfigGroup.setFirstHourParkingCostLinkAttributeName(RuhrUtils.ONE_HOUR_P_COST); parkingCostConfigGroup.setExtraHourParkingCostLinkAttributeName(RuhrUtils.EXTRA_HOUR_P_COST); @@ -200,13 +209,15 @@ protected Config prepareConfig(Config config) { parkingCostConfigGroup.setParkingPenaltyAttributeName(RuhrUtils.P_FINE); parkingCostConfigGroup.setResidentialParkingFeeAttributeName(RuhrUtils.RES_P_COSTS); - //config.plansCalcRoute().setAccessEgressType(AccessEgressType.accessEgressModeToLink); log.info("using accessEgressModeToLinkPlusTimeConstant"); + // we do this to model parking search traffic, as on some links car agents have additional travel time config.plansCalcRoute().setAccessEgressType(accessEgressModeToLinkPlusTimeConstant); config.qsim().setUsingTravelTimeCheckInTeleportation(true); config.qsim().setUsePersonIdForMissingVehicleId(false); - config.subtourModeChoice().setProbaForRandomSingleTripMode(0.5); + SimWrapperConfigGroup simWrapperConfigGroup = ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class); + + // adjust if sample size specific parameters if (sample.isSet()) { config.controler().setRunId(sample.adjustName(config.controler().getRunId())); config.controler().setOutputDirectory(sample.adjustName(config.controler().getOutputDirectory())); @@ -214,8 +225,11 @@ protected Config prepareConfig(Config config) { config.qsim().setFlowCapFactor(sample.getSize() / 100.0); config.qsim().setStorageCapFactor(sample.getSize() / 100.0); + + simWrapperConfigGroup.defaultParams().sampleSize = String.valueOf(sample.getSample()); } + // changes so that input is downloaded if (download) { adjustURL(config.network()::getInputFile, config.network()::setInputFile); adjustURL(config.plans()::getInputFile, config.plans()::setInputFile); @@ -224,26 +238,8 @@ protected Config prepareConfig(Config config) { adjustURL(config.transit()::getTransitScheduleFile, config.transit()::setTransitScheduleFile); } - for (long ii = 600; ii <= 86400; ii += 600) { - - for (String act : List.of("home", "restaurant", "other", "visit", "errands", - "educ_higher", "educ_secondary", "educ_primary", "educ_tertiary", "educ_kiga", "educ_other")) { - config.planCalcScore() - .addActivityParams(new PlanCalcScoreConfigGroup.ActivityParams(act + "_" + ii).setTypicalDuration(ii)); - } - - config.planCalcScore().addActivityParams(new PlanCalcScoreConfigGroup.ActivityParams("work_" + ii).setTypicalDuration(ii) - .setOpeningTime(6. * 3600.).setClosingTime(20. * 3600.)); - config.planCalcScore().addActivityParams(new PlanCalcScoreConfigGroup.ActivityParams("business_" + ii).setTypicalDuration(ii) - .setOpeningTime(6. * 3600.).setClosingTime(20. * 3600.)); - config.planCalcScore().addActivityParams(new PlanCalcScoreConfigGroup.ActivityParams("leisure_" + ii).setTypicalDuration(ii) - .setOpeningTime(9. * 3600.).setClosingTime(27. * 3600.)); - - config.planCalcScore().addActivityParams(new PlanCalcScoreConfigGroup.ActivityParams("shop_daily_" + ii).setTypicalDuration(ii) - .setOpeningTime(8. * 3600.).setClosingTime(20. * 3600.)); - config.planCalcScore().addActivityParams(new PlanCalcScoreConfigGroup.ActivityParams("shop_other_" + ii).setTypicalDuration(ii) - .setOpeningTime(8. * 3600.).setClosingTime(20. * 3600.)); - } + // snz activtiy types that are always the same, Differentiated by typical duration + SnzActivities.addScoringParams(config); return config; } @@ -251,6 +247,7 @@ protected Config prepareConfig(Config config) { @Override protected void prepareScenario(Scenario scenario) { + //TODO ask Janek if he has no idea --> delete if (zeroBikePCU) { Id key = Id.create("bike", VehicleType.class); VehicleType bike = scenario.getVehicles().getVehicleTypes().get(key); @@ -262,22 +259,16 @@ protected void prepareScenario(Scenario scenario) { @Override protected void prepareControler(Controler controler) { - if (!controler.getConfig().transit().isUsingTransitInMobsim()) + if (!controler.getConfig().transit().isUsingTransitInMobsim()) { log.error("Public transit will be teleported and not simulated in the mobsim! " + "This will have a significant effect on pt-related parameters (travel times, modal split, and so on). " + "Should only be used for testing or car-focused studies with fixed modal split."); + throw new IllegalArgumentException("Pt is teleported, wich is not supported"); + } - controler.addOverridingModule(new SwissRailRaptorModule()); - - // intermodal pt - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { - bind(RaptorIntermodalAccessEgress.class).to(EnhancedRaptorIntermodalAccessEgress.class); - bind(AnalysisMainModeIdentifier.class).to(IntermodalPtAnalysisModeIdentifier.class); - } - }); + controler.addOverridingModule(new SimWrapperModule()); + //TODO ask Gregor L. controler.addOverridingModule(new PtIntermodalRoutingModesModule()); controler.addOverridingModule(new IntermodalTripFareCompensatorsModule()); @@ -288,56 +279,33 @@ public void install() { controler.addOverridingModule(new AbstractModule() { @Override public void install() { - bind(ScoringParametersForPerson.class).to(IncomeDependentUtilityOfMoneyPersonScoringParameters.class).in(Singleton.class); - } - }); - // use the (congested) car travel time for the teleported ride mode - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { + // use the (congested) car travel time for the teleported ride mode addTravelTimeBinding(TransportMode.ride).to(networkTravelTime()); addTravelDisutilityFactoryBinding(TransportMode.ride).to(carTravelDisutilityFactoryKey()); - addTravelTimeBinding(TransportMode.bike).to(networkTravelTime()); - -// bind(AnalysisMainModeIdentifier.class).to(DefaultAnalysisMainModeIdentifier.class); - addControlerListenerBinding().to(ModeChoiceCoverageControlerListener.class); + // intermodal pt + bind(RaptorIntermodalAccessEgress.class).to(EnhancedRaptorIntermodalAccessEgress.class); + bind(AnalysisMainModeIdentifier.class).to(IntermodalPtAnalysisModeIdentifier.class); - // Configure mode-choice strategy - addControlerListenerBinding().to(StrategyWeightFadeout.class).in(Singleton.class); - Multibinder schedules = Multibinder.newSetBinder(binder(), StrategyWeightFadeout.Schedule.class); - schedules.addBinding().toInstance(new StrategyWeightFadeout.Schedule(DefaultPlanStrategiesModule.DefaultStrategy.SubtourModeChoice, "person", 0.75, 0.85)); - schedules.addBinding().toInstance(new StrategyWeightFadeout.Schedule(DefaultPlanStrategiesModule.DefaultStrategy.ReRoute, "person", 0.78)); - + // for income dependent scoring --> this works with the bicycle contrib as we don´t use the scoring in the bicycle contrib + bind(ScoringParametersForPerson.class).to(IncomeDependentUtilityOfMoneyPersonScoringParameters.class).in(Singleton.class); } }); - /*log.info("Adding parking cost"); - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { - this.addEventHandlerBinding().to(UtilityBasedParkingPressureEventHandler.class); - } - });*/ log.info("Adding money event analysis"); - controler.addOverridingModule(new AbstractModule() { - @Override - public void install() { - //analyse PersonMoneyEvents - install(new PersonMoneyEventsAnalysisModule()); - } - }); - - controler.addOverridingModule(new ParkingCostModule()); + //analyse PersonMoneyEvents + controler.addOverridingModule(new PersonMoneyEventsAnalysisModule()); - - Bicycles.addAsOverridingModule(controler); + //this is needed for the parking cost + controler.addOverridingModule(new ParkingCostModule()); + // bicycle contrib + controler.addOverridingModule(new BicycleModule()); } /** diff --git a/src/main/java/org/matsim/run/StrategyWeightFadeout.java b/src/main/java/org/matsim/run/StrategyWeightFadeout.java deleted file mode 100644 index 393e771..0000000 --- a/src/main/java/org/matsim/run/StrategyWeightFadeout.java +++ /dev/null @@ -1,158 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * Controler.java - * * - * *********************************************************************** * - * * - * copyright : (C) 2007 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.run; - -import com.google.inject.Inject; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.matsim.api.core.v01.population.Person; -import org.matsim.api.core.v01.population.Plan; -import org.matsim.core.config.Config; -import org.matsim.core.config.groups.StrategyConfigGroup; -import org.matsim.core.controler.events.IterationStartsEvent; -import org.matsim.core.controler.listener.IterationStartsListener; -import org.matsim.core.replanning.GenericPlanStrategy; -import org.matsim.core.replanning.PlanStrategy; -import org.matsim.core.replanning.StrategyManager; - -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -/** - * Fade-out the strategy weight during the simulation. - * This class as well as the {@link Schedule}s has be bound with guice in the controller. - */ -public final class StrategyWeightFadeout implements IterationStartsListener { - - private final Logger log = LogManager.getLogger(StrategyWeightFadeout.class); - - @Inject - private Map planStrategies; - - @Inject - private Config config; - - @Inject - private StrategyManager strategyManager; - - @Inject - private Set schedules; - - @Override - public void notifyIterationStarts(IterationStartsEvent iterationStartsEvent) { - - for (Schedule s : schedules) { - - StrategyConfigGroup.StrategySettings settings = null; - - for (StrategyConfigGroup.StrategySettings strategySettings : planStrategies.keySet()) { - if (strategySettings.getStrategyName().equals(s.name) && strategySettings.getSubpopulation().equals(s.subpopulation)) { - settings = strategySettings; - break; - } - } - - if (settings == null) { - log.info("Strategy settings for {} not found", s.name); - return; - } - - String strategyName = settings.getStrategyName(); - - if (Double.isNaN(s.initialWeight)) { - s.initialWeight = settings.getWeight(); - s.startIteration = (int) (config.controler().getLastIteration() * s.startAt); - double disable = config.strategy().getFractionOfIterationsToDisableInnovation(); - - // use disable after if it is set - if (!Double.isNaN(s.endAt)) - s.endIteration = (int) (config.controler().getLastIteration() * s.endAt); - else if (settings.getDisableAfter() > 0 && settings.getDisableAfter() < Integer.MAX_VALUE && settings.getDisableAfter() <= disable) - s.endIteration = settings.getDisableAfter(); - else if (Double.isFinite(disable) && disable < Integer.MAX_VALUE) - s.endIteration = (int) (config.controler().getLastIteration() * disable); - else - s.endIteration = settings.getDisableAfter(); - - log.info("{} fadeout from iteration {} to {} with start weight {}", strategyName, s.startIteration, s.endIteration, s.initialWeight); - } - - // Find the implementation to update the strategy weight - List> strategies = strategyManager.getStrategies(s.subpopulation); - Optional> strategy = strategies.stream().filter(st -> st.toString().contains(strategyName)).findFirst(); - - if (strategy.isEmpty()) { - log.warn("Could not find loaded strategy for {}", s.name); - return; - } - - if (iterationStartsEvent.getIteration() > s.startIteration && iterationStartsEvent.getIteration() <= s.endIteration) { - double step = s.initialWeight / (s.endIteration - s.startIteration); - double weight = s.initialWeight + step * (s.startIteration - iterationStartsEvent.getIteration()); - - log.info("Setting {} weight at iteration {} to {}", strategyName, iterationStartsEvent.getIteration(), weight); - - strategyManager.changeWeightOfStrategy(strategy.get(), s.subpopulation, weight); - } - } - } - - /** - * Defines the fade-out schedule for certain strategies. - */ - public static class Schedule { - - /** - * Start weight for fade-out. - */ - private double initialWeight = Double.NaN; - - /** - * Start and end iteration for fade-out. - */ - private int startIteration; - private int endIteration; - - private final String name; - private final String subpopulation; - private final double startAt; - private final double endAt; - - /** - * Constructor where the end is taken from the config and not given explicitly. - */ - public Schedule(String name, String subpopulation, double startAt) { - this.name = name; - this.subpopulation = subpopulation; - this.startAt = startAt; - this.endAt = Double.NaN; - } - - public Schedule(String name, String subpopulation, double startAt, double endAt) { - this.name = name; - this.subpopulation = subpopulation; - this.startAt = startAt; - this.endAt = endAt; - } - } -} From 59c8bf353cb165061a254533f26927472f264e2f Mon Sep 17 00:00:00 2001 From: vsp-gleich Date: Thu, 6 Jul 2023 18:13:03 +0200 Subject: [PATCH 02/28] add pt comments --- .../java/org/matsim/run/RunMetropoleRuhrScenario.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java index cc4ea0b..9c660ef 100644 --- a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java +++ b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java @@ -144,6 +144,7 @@ protected Config prepareConfig(Config config) { // because vsp default reasons config.facilities().setFacilitiesSource(FacilitiesConfigGroup.FacilitiesSource.onePerActivityLinkInPlansFile); + // someone wished to have an easy option to remove all intermodal functionality, so remove it from config or switch off if (!intermodal) { log.info("Disabling intermodal config..."); @@ -268,11 +269,12 @@ protected void prepareControler(Controler controler) { controler.addOverridingModule(new SimWrapperModule()); - //TODO ask Gregor L. + // allow for separate pt routing modes (pure walk+pt, bike+walk+pt, car+walk+pt, ...) controler.addOverridingModule(new PtIntermodalRoutingModesModule()); + // throw additional score or money events if pt is combined with bike or car in the same trip controler.addOverridingModule(new IntermodalTripFareCompensatorsModule()); - // analysis + // additional analysis output controler.addOverridingModule(new LinkPaxVolumesAnalysisModule()); controler.addOverridingModule(new PtStop2StopAnalysisModule()); @@ -286,8 +288,9 @@ public void install() { addTravelTimeBinding(TransportMode.bike).to(networkTravelTime()); addControlerListenerBinding().to(ModeChoiceCoverageControlerListener.class); - // intermodal pt + // calculate access/egress leg generalized cost correctly for intermodal pt routing bind(RaptorIntermodalAccessEgress.class).to(EnhancedRaptorIntermodalAccessEgress.class); + // separate pure walk+pt from intermodal pt in mode stats etc. bind(AnalysisMainModeIdentifier.class).to(IntermodalPtAnalysisModeIdentifier.class); // for income dependent scoring --> this works with the bicycle contrib as we don´t use the scoring in the bicycle contrib From b955191fbb4d573dccf4455b0a571c831e3e3879 Mon Sep 17 00:00:00 2001 From: GregorRyb Date: Tue, 25 Jul 2023 14:03:12 +0200 Subject: [PATCH 03/28] Fix mistake with vehicle bike and update matsim version --- pom.xml | 2 +- src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3b514e2..ed97305 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - 16.0-PR2673 + 16.0-PR2693 UTF-8 UTF-8 diff --git a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java index 9c660ef..e31abfb 100644 --- a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java +++ b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java @@ -227,7 +227,7 @@ protected Config prepareConfig(Config config) { config.qsim().setFlowCapFactor(sample.getSize() / 100.0); config.qsim().setStorageCapFactor(sample.getSize() / 100.0); - simWrapperConfigGroup.defaultParams().sampleSize = String.valueOf(sample.getSample()); + simWrapperConfigGroup.defaultParams().sampleSize = Double.valueOf(String.valueOf(sample.getSample())); } // changes so that input is downloaded @@ -255,6 +255,8 @@ protected void prepareScenario(Scenario scenario) { bike.setPcuEquivalents(0); } + VehicleType bike = scenario.getVehicles().getVehicleTypes().get(Id.create("bike", VehicleType.class)); + bike.setNetworkMode(TransportMode.bike); } @Override From 43efb53ee0e7d2862c8f997cfbdd428a902ff460 Mon Sep 17 00:00:00 2001 From: GregorRyb Date: Wed, 26 Jul 2023 09:52:45 +0200 Subject: [PATCH 04/28] comment out old code and old csv dependency to fix test --- pom.xml | 8 +------- .../java/org/matsim/run/RunMetropoleRuhrScenario.java | 6 +++--- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index ed97305..068398d 100644 --- a/pom.xml +++ b/pom.xml @@ -149,13 +149,7 @@ - - org.apache.commons - commons-csv - 1.6 - - - + org.apache.poi poi-ooxml 4.1.1 diff --git a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java index e31abfb..5badc0b 100644 --- a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java +++ b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java @@ -249,11 +249,11 @@ protected Config prepareConfig(Config config) { protected void prepareScenario(Scenario scenario) { //TODO ask Janek if he has no idea --> delete - if (zeroBikePCU) { + /* if (zeroBikePCU) { Id key = Id.create("bike", VehicleType.class); VehicleType bike = scenario.getVehicles().getVehicleTypes().get(key); bike.setPcuEquivalents(0); - } + } */ VehicleType bike = scenario.getVehicles().getVehicleTypes().get(Id.create("bike", VehicleType.class)); bike.setNetworkMode(TransportMode.bike); @@ -277,7 +277,7 @@ protected void prepareControler(Controler controler) { controler.addOverridingModule(new IntermodalTripFareCompensatorsModule()); // additional analysis output - controler.addOverridingModule(new LinkPaxVolumesAnalysisModule()); + //controler.addOverridingModule(new LinkPaxVolumesAnalysisModule()); controler.addOverridingModule(new PtStop2StopAnalysisModule()); controler.addOverridingModule(new AbstractModule() { From 989b93d0f36678e547b94126cbd0fbf9f186f0e4 Mon Sep 17 00:00:00 2001 From: GregorRyb Date: Mon, 2 Oct 2023 13:29:03 +0200 Subject: [PATCH 05/28] Population Comparison --- .../matsim/analysis/PopulationComparison.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/main/java/org/matsim/analysis/PopulationComparison.java diff --git a/src/main/java/org/matsim/analysis/PopulationComparison.java b/src/main/java/org/matsim/analysis/PopulationComparison.java new file mode 100644 index 0000000..3bcfc00 --- /dev/null +++ b/src/main/java/org/matsim/analysis/PopulationComparison.java @@ -0,0 +1,67 @@ +package org.matsim.analysis; + +import org.matsim.application.MATSimAppCommand; +import org.matsim.application.MATSimApplication; +import org.matsim.application.analysis.CheckPopulation; +import org.matsim.application.analysis.population.PopulationAttributeAnalysis; +import org.matsim.application.analysis.population.SubTourAnalysis; +import org.matsim.application.options.CrsOptions; +import org.matsim.application.options.ShpOptions; +import picocli.CommandLine; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + + +public class PopulationComparison { + + + private static final Logger log = LogManager.getLogger(PopulationComparison.class); + public static void main(String [] args) { + + String openPopulation = "../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20230918_OpenData_Ruhr_300m/populaton.xml.gz"; + String oldPopulation = "../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population.xml.gz"; + String processedPopulation = "../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-25pct.plans.xml.gz"; + String shp ="../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20230918_OpenData_Ruhr_300m/dilutionArea.shp"; + + CheckPopulation checkPopulation = new CheckPopulation(); + + String[] argsNewPopulation = new String[]{ + openPopulation, + "--shp", shp, + "--input-crs", "EPSG:25832", + "--shp-crs", "EPSG:25832" + }; + + checkPopulation.execute(argsNewPopulation); + log.info("---------------"); + log.info("start check population analysis of old population"); + log.info("---------------"); + + String[] argsOldPopulation = new String[]{ + oldPopulation, + "--shp", shp, + "--input-crs", "EPSG:25832", + "--shp-crs", "EPSG:25832" + }; + checkPopulation.execute(argsOldPopulation); + + log.info("---------------"); + log.info("start check population analysis of processed population"); + log.info("---------------"); + + String[] argsProcessedPopulation = new String[]{ + processedPopulation, + "--shp", shp, + "--input-crs", "EPSG:25832", + "--shp-crs", "EPSG:25832" + }; + checkPopulation.execute(argsProcessedPopulation); + + //new PopulationAttributeAnalysis().execute("--population", "/Users/gregorr/Documents/work/respos/shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population.xml.gz"); + + //new SubTourAnalysis().execute(); + + + } + +} From ad581b329bdad241b03d4dced2fbca816afd9f86 Mon Sep 17 00:00:00 2001 From: GregorRyb Date: Tue, 10 Oct 2023 10:58:55 +0200 Subject: [PATCH 06/28] Add further analysis --- .../matsim/analysis/AttributeAnalysis.java | 74 +++++++++++++++++++ .../matsim/analysis/PopulationComparison.java | 11 +-- .../java/org/matsim/analysis/RunMATSim.java | 24 ++++++ 3 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/matsim/analysis/AttributeAnalysis.java create mode 100644 src/main/java/org/matsim/analysis/RunMATSim.java diff --git a/src/main/java/org/matsim/analysis/AttributeAnalysis.java b/src/main/java/org/matsim/analysis/AttributeAnalysis.java new file mode 100644 index 0000000..b2d6ffd --- /dev/null +++ b/src/main/java/org/matsim/analysis/AttributeAnalysis.java @@ -0,0 +1,74 @@ +package org.matsim.analysis; + +import com.google.common.collect.MapDifference; +import com.google.common.collect.Maps; +import org.apache.commons.collections.CollectionUtils; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.population.Activity; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.api.core.v01.population.Population; +import org.matsim.core.population.PopulationUtils; +import org.matsim.core.router.TripStructureUtils; +import org.matsim.utils.objectattributes.attributable.Attributes; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AttributeAnalysis { + + + public static void main (String args []) throws IOException { + + String openPopulationPath = "../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20230918_OpenData_Ruhr_300m/populaton.xml.gz"; + String oldPopulationPath = "../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population.xml.gz"; + String processedPopulationPath = "../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.plans.xml.gz"; + + Population closedPopulation = PopulationUtils.readPopulation(oldPopulationPath); + Population openPopulation = PopulationUtils.readPopulation(openPopulationPath); + //PopulationUtils.readPopulation(processedPopulationPath); + + List differenceAttributes = new ArrayList<>(); + List differenceActivities = new ArrayList<>(); + + for (Person personClosed: closedPopulation.getPersons().values()) { + for(Person personOpen: openPopulation.getPersons().values()) { + if (personClosed.getId().equals(personOpen.getId())) { + // first compare attributes + Map personClosedAttributes = personClosed.getAttributes().getAsMap(); + Map personOpenAttributes = personOpen.getAttributes().getAsMap(); + MapDifference diff = Maps.difference(personClosedAttributes, personOpenAttributes); + System.out.println(diff.toString()); + if (diff.equals(false)) { + System.out.println("This is not supposed to happen"); + } + + /* //second activities + List openActivities = PopulationUtils.getActivities(personClosed.getSelectedPlan(), TripStructureUtils.StageActivityHandling.ExcludeStageActivities); + List closedActivities = PopulationUtils.getActivities(personOpen.getSelectedPlan(), TripStructureUtils.StageActivityHandling.ExcludeStageActivities); + List differences = new ArrayList<>((CollectionUtils.removeAll(openActivities, closedActivities))); + differenceActivities.add(differences); + break;*/ + } + } + } + + /* System.out.println(differenceActivities.size()); + System.out.println(differenceAttributes.size());*/ + + + /* BufferedWriter br = new BufferedWriter(new FileWriter("activites.txt")); + for (String str : stringList) { + br.write(str + System.lineSeparator()); + } + br.close();*/ + + + + } +} diff --git a/src/main/java/org/matsim/analysis/PopulationComparison.java b/src/main/java/org/matsim/analysis/PopulationComparison.java index 3bcfc00..a33cba5 100644 --- a/src/main/java/org/matsim/analysis/PopulationComparison.java +++ b/src/main/java/org/matsim/analysis/PopulationComparison.java @@ -16,11 +16,12 @@ public class PopulationComparison { private static final Logger log = LogManager.getLogger(PopulationComparison.class); + public static void main(String [] args) { String openPopulation = "../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20230918_OpenData_Ruhr_300m/populaton.xml.gz"; String oldPopulation = "../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population.xml.gz"; - String processedPopulation = "../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-25pct.plans.xml.gz"; + String processedPopulation = "../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.plans.xml.gz"; String shp ="../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20230918_OpenData_Ruhr_300m/dilutionArea.shp"; CheckPopulation checkPopulation = new CheckPopulation(); @@ -32,7 +33,7 @@ public static void main(String [] args) { "--shp-crs", "EPSG:25832" }; - checkPopulation.execute(argsNewPopulation); + //checkPopulation.execute(argsNewPopulation); log.info("---------------"); log.info("start check population analysis of old population"); log.info("---------------"); @@ -43,7 +44,7 @@ public static void main(String [] args) { "--input-crs", "EPSG:25832", "--shp-crs", "EPSG:25832" }; - checkPopulation.execute(argsOldPopulation); + //checkPopulation.execute(argsOldPopulation); log.info("---------------"); log.info("start check population analysis of processed population"); @@ -57,9 +58,9 @@ public static void main(String [] args) { }; checkPopulation.execute(argsProcessedPopulation); - //new PopulationAttributeAnalysis().execute("--population", "/Users/gregorr/Documents/work/respos/shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population.xml.gz"); + //new PopulationAttributeAnalysis().execute("--population", openPopulation); - //new SubTourAnalysis().execute(); + //new SubTourAnalysis().execute("--population", openPopulation); } diff --git a/src/main/java/org/matsim/analysis/RunMATSim.java b/src/main/java/org/matsim/analysis/RunMATSim.java new file mode 100644 index 0000000..c51a6bb --- /dev/null +++ b/src/main/java/org/matsim/analysis/RunMATSim.java @@ -0,0 +1,24 @@ +package org.matsim.analysis; + +import org.matsim.api.core.v01.Scenario; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.controler.Controler; +import org.matsim.core.scenario.ScenarioUtils; + +public class RunMATSim { + + public static void main (String args[]) { + + Config config = ConfigUtils.createConfig(); + //Config config = ConfigUtils.loadConfig("/Users/gregorr/Documents/work/respos/git/matsim-metropole-ruhr/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml"); + config.plans().setInputFile("/Users/gregorr/Documents/work/respos/shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20230918_OpenData_Ruhr_300m/populaton.xml.gz"); + config.network().setInputFile("https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4.network_resolutionHigh-with-pt.xml.gz"); + config.controler().setLastIteration(0); + Scenario scenario = ScenarioUtils.loadScenario(config); + Controler controler = new Controler(scenario); + + controler.run(); + + } +} From 00c5a722b40effe33fce12efd99d7fedfdba6181 Mon Sep 17 00:00:00 2001 From: GregorRyb Date: Tue, 17 Oct 2023 17:33:25 +0200 Subject: [PATCH 07/28] {WIP} start processing of the open population --- .../java/org/matsim/analysis/RunMATSim.java | 24 ---------- .../java/org/matsim/prepare/CreateDemand.java | 44 ++++++++++++++----- 2 files changed, 33 insertions(+), 35 deletions(-) delete mode 100644 src/main/java/org/matsim/analysis/RunMATSim.java diff --git a/src/main/java/org/matsim/analysis/RunMATSim.java b/src/main/java/org/matsim/analysis/RunMATSim.java deleted file mode 100644 index c51a6bb..0000000 --- a/src/main/java/org/matsim/analysis/RunMATSim.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.matsim.analysis; - -import org.matsim.api.core.v01.Scenario; -import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigUtils; -import org.matsim.core.controler.Controler; -import org.matsim.core.scenario.ScenarioUtils; - -public class RunMATSim { - - public static void main (String args[]) { - - Config config = ConfigUtils.createConfig(); - //Config config = ConfigUtils.loadConfig("/Users/gregorr/Documents/work/respos/git/matsim-metropole-ruhr/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml"); - config.plans().setInputFile("/Users/gregorr/Documents/work/respos/shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20230918_OpenData_Ruhr_300m/populaton.xml.gz"); - config.network().setInputFile("https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4.network_resolutionHigh-with-pt.xml.gz"); - config.controler().setLastIteration(0); - Scenario scenario = ScenarioUtils.loadScenario(config); - Controler controler = new Controler(scenario); - - controler.run(); - - } -} diff --git a/src/main/java/org/matsim/prepare/CreateDemand.java b/src/main/java/org/matsim/prepare/CreateDemand.java index 6865b83..5c37344 100644 --- a/src/main/java/org/matsim/prepare/CreateDemand.java +++ b/src/main/java/org/matsim/prepare/CreateDemand.java @@ -21,12 +21,24 @@ public class CreateDemand { private static final Path heightData = rootFolder.resolve("./original-data/2021-05-29_RVR_Grid_10m.tif"); private static final Path outputFolder = Paths.get("../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input"); - private static final String OUTPUT = outputFolder.resolve("metropole-ruhr-" + RunMetropoleRuhrScenario.VERSION + "-25pct.plans.xml.gz").toString(); public static void main(String[] args) { + boolean openModel = args.length > 0 && args[0].equalsIgnoreCase("True"); + + String outputPlans = outputFolder.resolve("metropole-ruhr-" + RunMetropoleRuhrScenario.VERSION + "-25pct.plans.xml.gz").toString(); + + if (openModel) + outputPlans = outputPlans.replace(".plans", ".open-plans"); + + String input; + if (openModel) + input = "../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20230918_OpenData_Ruhr_300m/populaton.xml.gz"; + else + input = "../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population.xml.gz"; + String[] argsForRemoveRoutesFromPlans = new String[]{ - "--plans=../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population.xml.gz", + "--plans=" + input, "--keep-selected=true", "--output=../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population-without-routes.xml.gz", }; @@ -35,7 +47,7 @@ public static void main(String[] args) { new CloseTrajectories().execute( "../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population-without-routes.xml.gz", - "--output=" + OUTPUT, + "--output=" + outputPlans, "--min-duration=0", "--act-duration=" + 30 * 60 ); @@ -43,12 +55,22 @@ public static void main(String[] args) { new TrajectoryToPlans().execute( "--name=prepare", "--sample-size=0.25", - "--population=" + OUTPUT, - "--attributes=../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/personAttributes.xml.gz", + "--population=" + outputPlans, + "--attributes=../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/personAttributes.xml.gz", // TODO adapt for open scenario, "--output=../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/" ); - String tmp = OUTPUT.replace("25pct", "tmp"); + if (openModel) { + new ResolveGridCoordinates().execute( + "../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/prepare-25pct.plans.xml.gz", + "--output=../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/prepare-25pct.plans.xml.gz", + "--network=../public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4.network_resolutionHigh.xml.gz", + "--shp=../../shared-svn/projects/matsim-germany/landuse/landuse.shp", + "--grid-resolution", "300" + ); + } + + String tmp = outputPlans.replace("25pct", "tmp"); new GenerateShortDistanceTrips().execute( "--population=../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/prepare-25pct.plans.xml.gz", "--input-crs=EPSG:25832", @@ -90,7 +112,7 @@ public static void main(String[] args) { in.addAlgorithm(out); // open the output population - out.startStreaming(OUTPUT); + out.startStreaming(outputPlans); // read the population, add elevation to each person and write each person to output population in.readFile(tmp); // finish the output population after the reader is finished @@ -98,16 +120,16 @@ public static void main(String[] args) { //---------------------- - new ExtractHomeCoordinates().execute(OUTPUT, - "--csv="+ OUTPUT.replace(".xml.gz", "-homes.csv") + new ExtractHomeCoordinates().execute(outputPlans, + "--csv="+ outputPlans.replace(".xml.gz", "-homes.csv") ); - new DownSamplePopulation().execute(OUTPUT, + new DownSamplePopulation().execute(outputPlans, "--sample-size=0.25", "--samples", "0.1", "0.03", "0.01", "0.001" ); - new CheckPopulation().execute(OUTPUT, + new CheckPopulation().execute(outputPlans, "--input-crs=EPSG:25832", "--shp=../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/dilutionArea.shp", "--shp-crs=EPSG:25832" From 61f74c34b1173560047f7ec712aa249f7c4ec4d0 Mon Sep 17 00:00:00 2001 From: GregorRyb Date: Wed, 18 Oct 2023 17:23:55 +0200 Subject: [PATCH 08/28] switch to correct directory structure --- .../java/org/matsim/prepare/CreateDemand.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/matsim/prepare/CreateDemand.java b/src/main/java/org/matsim/prepare/CreateDemand.java index 5c37344..e238a7d 100644 --- a/src/main/java/org/matsim/prepare/CreateDemand.java +++ b/src/main/java/org/matsim/prepare/CreateDemand.java @@ -17,10 +17,10 @@ public class CreateDemand { - private static final Path rootFolder = Paths.get("../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0"); + private static final Path rootFolder = Paths.get("../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0"); private static final Path heightData = rootFolder.resolve("./original-data/2021-05-29_RVR_Grid_10m.tif"); - private static final Path outputFolder = Paths.get("../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input"); + private static final Path outputFolder = Paths.get("../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input"); public static void main(String[] args) { @@ -35,18 +35,18 @@ public static void main(String[] args) { if (openModel) input = "../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20230918_OpenData_Ruhr_300m/populaton.xml.gz"; else - input = "../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population.xml.gz"; + input = "../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population.xml.gz"; String[] argsForRemoveRoutesFromPlans = new String[]{ "--plans=" + input, "--keep-selected=true", - "--output=../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population-without-routes.xml.gz", + "--output=../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population-without-routes.xml.gz", }; new RemoveRoutesFromPlans().execute(argsForRemoveRoutesFromPlans); new CloseTrajectories().execute( - "../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population-without-routes.xml.gz", + "../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population-without-routes.xml.gz", "--output=" + outputPlans, "--min-duration=0", "--act-duration=" + 30 * 60 @@ -56,15 +56,15 @@ public static void main(String[] args) { "--name=prepare", "--sample-size=0.25", "--population=" + outputPlans, - "--attributes=../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/personAttributes.xml.gz", // TODO adapt for open scenario, - "--output=../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/" + "--attributes=../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/personAttributes.xml.gz", // TODO adapt for open scenario, + "--output=../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/" ); if (openModel) { new ResolveGridCoordinates().execute( - "../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/prepare-25pct.plans.xml.gz", - "--output=../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/prepare-25pct.plans.xml.gz", - "--network=../public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4.network_resolutionHigh.xml.gz", + "../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/prepare-25pct.plans.xml.gz", + "--output=../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/prepare-25pct.plans.xml.gz", + "--network=../../public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4.network_resolutionHigh.xml.gz", "--shp=../../shared-svn/projects/matsim-germany/landuse/landuse.shp", "--grid-resolution", "300" ); @@ -72,9 +72,9 @@ public static void main(String[] args) { String tmp = outputPlans.replace("25pct", "tmp"); new GenerateShortDistanceTrips().execute( - "--population=../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/prepare-25pct.plans.xml.gz", + "--population=../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/prepare-25pct.plans.xml.gz", "--input-crs=EPSG:25832", - "--shp=../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/dilutionArea.shp", + "--shp=../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/dilutionArea.shp", "--shp-crs=EPSG:25832", "--num-trips=551000", "--output=" + tmp @@ -83,7 +83,7 @@ public static void main(String[] args) { new XYToLinks().execute( "--input=" + tmp, "--output=" + tmp, - "--network=../public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4.network_resolutionHigh.xml.gz", + "--network=../../public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4.network_resolutionHigh.xml.gz", "--car-only" ); @@ -131,7 +131,7 @@ public static void main(String[] args) { new CheckPopulation().execute(outputPlans, "--input-crs=EPSG:25832", - "--shp=../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/dilutionArea.shp", + "--shp=../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/dilutionArea.shp", "--shp-crs=EPSG:25832" ); From 78863d8da13784c3be779c4d18bcdbaaa571ad54 Mon Sep 17 00:00:00 2001 From: rakow Date: Thu, 19 Oct 2023 09:55:59 +0200 Subject: [PATCH 09/28] fix arguments for resolve grid coordinates --- src/main/java/org/matsim/prepare/CreateDemand.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/matsim/prepare/CreateDemand.java b/src/main/java/org/matsim/prepare/CreateDemand.java index e238a7d..246f010 100644 --- a/src/main/java/org/matsim/prepare/CreateDemand.java +++ b/src/main/java/org/matsim/prepare/CreateDemand.java @@ -24,6 +24,7 @@ public class CreateDemand { public static void main(String[] args) { + // If true is given as argument, this class will build the open population boolean openModel = args.length > 0 && args[0].equalsIgnoreCase("True"); String outputPlans = outputFolder.resolve("metropole-ruhr-" + RunMetropoleRuhrScenario.VERSION + "-25pct.plans.xml.gz").toString(); @@ -63,9 +64,9 @@ public static void main(String[] args) { if (openModel) { new ResolveGridCoordinates().execute( "../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/prepare-25pct.plans.xml.gz", + "--input-crs=EPSG:25832", "--output=../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/prepare-25pct.plans.xml.gz", - "--network=../../public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4.network_resolutionHigh.xml.gz", - "--shp=../../shared-svn/projects/matsim-germany/landuse/landuse.shp", + "--landuse=../../shared-svn/projects/matsim-germany/landuse/landuse.shp", "--grid-resolution", "300" ); } From fdf88b50a242560581ed03d49eef74849e347e9a Mon Sep 17 00:00:00 2001 From: rakow Date: Tue, 28 Nov 2023 17:55:39 +0100 Subject: [PATCH 10/28] simplified run options, make URLs to public files the default --- .../metropole-ruhr-v1.4-10pct.config.xml | 8 ++-- .../input/metropole-ruhr-v1.4-3pct.config.xml | 8 ++-- .../matsim/run/RunMetropoleRuhrScenario.java | 38 ------------------- 3 files changed, 8 insertions(+), 46 deletions(-) diff --git a/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-10pct.config.xml b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-10pct.config.xml index 7062549..3efd39a 100644 --- a/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-10pct.config.xml +++ b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-10pct.config.xml @@ -20,11 +20,11 @@ + value="https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4.network_resolutionHigh-with-pt.xml.gz"/> + value="../../../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-10pct.plans.xml.gz"/> @@ -33,10 +33,10 @@ + value="https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-transitSchedule.xml.gz"/> + value="https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-transitVehicles.xml.gz"/> diff --git a/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml index a145342..56793c6 100644 --- a/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml +++ b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml @@ -20,11 +20,11 @@ + value="https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4.network_resolutionHigh-with-pt.xml.gz"/> + value="../../../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.plans.xml.gz"/> @@ -33,10 +33,10 @@ + value="https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-transitSchedule.xml.gz"/> + value="https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-transitVehicles.xml.gz"/> diff --git a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java index 5badc0b..561643a 100644 --- a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java +++ b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java @@ -91,17 +91,9 @@ public class RunMetropoleRuhrScenario extends MATSimApplication { private static final Logger log = LogManager.getLogger(RunMetropoleRuhrScenario.class); - public static final String URL = "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/"; - @CommandLine.Mixin private final SampleOptions sample = new SampleOptions(10, 25, 3, 1); - @CommandLine.Option(names = "--zero-bike-pcu", defaultValue = "false", description = "Set bike pcu to zero") - private boolean zeroBikePCU; - - @CommandLine.Option(names = "--download-input", defaultValue = "false", description = "Download input files from remote location") - private boolean download; - @CommandLine.Option(names = "--no-intermodal", defaultValue = "true", description = "Enable or disable intermodal routing", negatable = true) protected boolean intermodal; @@ -230,15 +222,6 @@ protected Config prepareConfig(Config config) { simWrapperConfigGroup.defaultParams().sampleSize = Double.valueOf(String.valueOf(sample.getSample())); } - // changes so that input is downloaded - if (download) { - adjustURL(config.network()::getInputFile, config.network()::setInputFile); - adjustURL(config.plans()::getInputFile, config.plans()::setInputFile); - adjustURL(config.vehicles()::getVehiclesFile, config.vehicles()::setVehiclesFile); - adjustURL(config.transit()::getVehiclesFile, config.transit()::setVehiclesFile); - adjustURL(config.transit()::getTransitScheduleFile, config.transit()::setTransitScheduleFile); - } - // snz activtiy types that are always the same, Differentiated by typical duration SnzActivities.addScoringParams(config); @@ -248,13 +231,6 @@ protected Config prepareConfig(Config config) { @Override protected void prepareScenario(Scenario scenario) { - //TODO ask Janek if he has no idea --> delete - /* if (zeroBikePCU) { - Id key = Id.create("bike", VehicleType.class); - VehicleType bike = scenario.getVehicles().getVehicleTypes().get(key); - bike.setPcuEquivalents(0); - } */ - VehicleType bike = scenario.getVehicles().getVehicleTypes().get(Id.create("bike", VehicleType.class)); bike.setNetworkMode(TransportMode.bike); } @@ -313,18 +289,4 @@ public void install() { controler.addOverridingModule(new BicycleModule()); } - /** - * Appends url to download a resource if not present. - */ - private void adjustURL(Supplier getter, Consumer setter) { - - String input = getter.get(); - if (input.startsWith("http")) - return; - - String name = new File(input).getName(); - - setter.accept(URL + name); - } - } \ No newline at end of file From b56b13a8fe39e00cf40e5a6c7192011349b0ae1a Mon Sep 17 00:00:00 2001 From: rakow Date: Wed, 29 Nov 2023 11:01:03 +0100 Subject: [PATCH 11/28] update MATSim version, add shp file for simwrapper dashboards --- .github/workflows/build.yaml | 2 +- .github/workflows/publish.yaml | 4 ++- pom.xml | 4 +-- scenarios/metropole-ruhr-v1.0/area/area.cpg | 1 + scenarios/metropole-ruhr-v1.0/area/area.dbf | Bin 0 -> 579 bytes scenarios/metropole-ruhr-v1.0/area/area.prj | 1 + scenarios/metropole-ruhr-v1.0/area/area.qmd | 27 ++++++++++++++++++ scenarios/metropole-ruhr-v1.0/area/area.shp | Bin 0 -> 44716 bytes scenarios/metropole-ruhr-v1.0/area/area.shx | Bin 0 -> 108 bytes .../metropole-ruhr-v1.4-10pct.config.xml | 15 ++++++++-- .../input/metropole-ruhr-v1.4-3pct.config.xml | 15 ++++++++-- .../java/org/matsim/prepare/CreateDemand.java | 1 + .../matsim/run/RunMetropoleRuhrScenario.java | 26 ++++++----------- .../org/matsim/run/TestBicycleRouting.java | 4 +-- src/test/java/org/matsim/run/TestParking.java | 15 +++++----- 15 files changed, 80 insertions(+), 35 deletions(-) create mode 100644 scenarios/metropole-ruhr-v1.0/area/area.cpg create mode 100644 scenarios/metropole-ruhr-v1.0/area/area.dbf create mode 100644 scenarios/metropole-ruhr-v1.0/area/area.prj create mode 100644 scenarios/metropole-ruhr-v1.0/area/area.qmd create mode 100644 scenarios/metropole-ruhr-v1.0/area/area.shp create mode 100644 scenarios/metropole-ruhr-v1.0/area/area.shx diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d169813..60aa666 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -35,4 +35,4 @@ jobs: run: mvn -B package --file pom.xml -Dmatsim.preferLocalDtds=true -Dmaven.javadoc.skip -e env: - MAVEN_OPTS: -Xmx10G \ No newline at end of file + MAVEN_OPTS: -Xmx512m \ No newline at end of file diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index d6a9746..bee26af 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -10,11 +10,13 @@ jobs: - uses: actions/setup-java@v3 with: java-version: 17 + architecture: x64 distribution: zulu + - name: Publish package run: mvn --batch-mode deploy env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} env: - MAVEN_OPTS: -Xmx10G \ No newline at end of file + MAVEN_OPTS: -Xmx512m \ No newline at end of file diff --git a/pom.xml b/pom.xml index 068398d..a1459a2 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - 16.0-PR2693 + 16.0-PR2895 UTF-8 UTF-8 @@ -172,7 +172,7 @@ once - -Xmx9500m -Djava.awt.headless=true -Dmatsim.preferLocalDtds=true + -Xmx6500m -Djava.awt.headless=true -Dmatsim.preferLocalDtds=true diff --git a/scenarios/metropole-ruhr-v1.0/area/area.cpg b/scenarios/metropole-ruhr-v1.0/area/area.cpg new file mode 100644 index 0000000..3ad133c --- /dev/null +++ b/scenarios/metropole-ruhr-v1.0/area/area.cpg @@ -0,0 +1 @@ +UTF-8 \ No newline at end of file diff --git a/scenarios/metropole-ruhr-v1.0/area/area.dbf b/scenarios/metropole-ruhr-v1.0/area/area.dbf new file mode 100644 index 0000000000000000000000000000000000000000..c52991806f86a788c29769a822394d165d08bb20 GIT binary patch literal 579 zcmZRs=9Xn-U|>*WR0L5Nz%eKUCgu!cXux<-+T9N>fK}d`ki5TtkW0LOkS7BJcKu*^ zcUPb>Smk{jUH#l$!3N-y2N{4>J~+hD&jsQIFvS7)4urw0;H^L$aLO+!DatR<@lQ%E z%1A6NPR-MCPt5^R*_lPj89-i8YI1f?W}bnmsiBd9fq{;JsiC1IgkfrE3}u)>r7R7J NvvuH90UZnmQUH3RML+-m literal 0 HcmV?d00001 diff --git a/scenarios/metropole-ruhr-v1.0/area/area.prj b/scenarios/metropole-ruhr-v1.0/area/area.prj new file mode 100644 index 0000000..bd846ae --- /dev/null +++ b/scenarios/metropole-ruhr-v1.0/area/area.prj @@ -0,0 +1 @@ +PROJCS["ETRS_1989_UTM_Zone_32N",GEOGCS["GCS_ETRS_1989",DATUM["D_ETRS_1989",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] \ No newline at end of file diff --git a/scenarios/metropole-ruhr-v1.0/area/area.qmd b/scenarios/metropole-ruhr-v1.0/area/area.qmd new file mode 100644 index 0000000..f8d419d --- /dev/null +++ b/scenarios/metropole-ruhr-v1.0/area/area.qmd @@ -0,0 +1,27 @@ + + + + + + dataset + + + + + + + + + + + 0 + 0 + + + + + false + + + + diff --git a/scenarios/metropole-ruhr-v1.0/area/area.shp b/scenarios/metropole-ruhr-v1.0/area/area.shp new file mode 100644 index 0000000000000000000000000000000000000000..e397cc97447c26bf342659eafd60cfcc62bd7fed GIT binary patch literal 44716 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%0Df{IZg~xSM>&+F zKcPrbW4dSyTohS08IwWZ+s}Eh%@>}Rq%V{$EDA3 zy?9r3bGWTIH7OQOuQ%Gg8~*1a5Kvr9kuPoH61H%RWz-gp=M=e`ksNUVUUQxKumP?Q z9QHd7Uzb-@OnHIwmdb282meNWGF3*AIgF3ogOlXA?vo1Cry0p@g>Zs}!!wI&l@FK`=8Oj(g|-9g3Y(9hF*YYlx!@;;f$u*sfR5Tc{VpE z$BLi-TI(nQ{GK~9K0gPJ#XMI5xG;Vx?{ zVEgKtn)ptn_X59^J8&cNYwG|-c7uKLHnEo=bNa^-Wb;9!#qGG!ta?Bbg;d=j4g+=h{!!aXYC(xdZ)qj$NwZ58cI3m7DB z%5?P&q}My7Pb?>c^aT#5J%D8nIXcc;#2|_TGjCbrqnn?nGDqR3nH7et_Y2SEmJW*+ zGYF$VBq#!oyP>P{g_}Vd*rcK|VUO3S*mxME#*FvDGuH914WHI6VUTD;)kQbqqX~%& zHUS2aj~VG@m8bL__R&X|GRO-_>-S&a*S9MSR|_(T>c9+R3SNwH!KD;~%(E$4%7yq> zpuQMjFbG{WbR7f!+cN#n5Z<8CIm+r^m|mtheh4!NXI^DL>wRQIDtE>B3I>@UO6IZp z7d_|WbeySiNB5XYjDn0bgVZ*76`q03)H{vK<&b`6yze~VKZswmJcFn>I(D3gF|MpEq`)9K-h$=^ z=)ZGF=dSpp#2`Dhl~wfNj^Dn{{e(fb2n0~9_l1AwoQos2FvyLX8u1PAACxcVRt9-& z9QmRb=PS52nn~AXkj0@SvzgYd(;KMP;y#B|l3t?f5docDgNcC(3*K0WA z<)owvT<9&x*##fNyiPY9IX>I_6&67J!{LOgv`_3fzY*ru*ew`n_h;C+VE^cmzg$)f zViZg5SqeA&oZS<6fI((HPv^7VM+_gO9QU?GdZ)X|u;Len=PzW(AQQ6f(scOxk>Uw6 zSdLdFOdjr^kZiMdV34);{Gw(sSDl#EibD*-)h@nsEzFH^lj)n~ zcpCL{-f5JlPUF{~;8i9CA}u&RRM=9y1MXgK*}DSgV{4tZX@HaXEYzBP8ARHiKjate zwD7*L9h{f$mLZ7z##vLd;~Q*NlDc~Zd>#4Yn;(O0>Z_Z-4nC`7Q`8>7AY=Ze|G5zN zdmgsZR+d#k_@$>JK~x}vH2XULb%YyHAHEA`5F6*>Ue^2V9re!lx=}b^k-?rva0tqm zF?_Qs?fFNT;Q5PPW{_<$BMpP_U)1jl;!q!O`hDt#cOyT&jYs`g=_xw^@3|*zS(?Zo zcMMfu-h-pVTn3gWp*}F}Nr{95k>33Y3}P*q9bbq0U7hZxrG)Sa|I*zr;TwqW&SVBT zqZ9r&6@G{O@dM#(LBorZ;8jNU{NmRb#FOIK=>?mjUQEOB%ed}eVU?flS(wK`xT!$E zpc9;RP@^*m;s0dYHCg5D=PS`1u?z-@L4S)MUMy_c+nR^-q5dC1epjoVGIfSEcxAX* z?{5=m@3o&Wh-jzryT@=N%9C*+o>%^O&@(tMBL4fS=PsE3a<;Q0w#O8UXbagFhj^ zp2G1aF(cw3=-)g*c@jW)V7Vy8^4^T(@;`8L%4q5tIC%q?bUS>1Qqr2$zxHiRcaw$B z>xBDQ!&Rv7qhKfJVsS(G$Fgkwf<^{;RXe4#8-Bc~Y4v0igN!$(-#87AqdW+IW{~Av z_kGU68$^PJo!c1Xw{-5O%kUM{pQ}1>K5b<^FF5t{v@d5b@~=niHr9OE4?J&XAA@vD zT0gXeXOSNj`xzwDBlb7z`VENBPxvq1w^;LI2T@-Q4={+7vW>!7_{dDwiLvjf4}xiD zPQeb|g4s7=6`uJzG4LfesfAjjh=01kNaewkZld246w?*8OD=FP8x+4_JWKvQyz7`X_0+p5gE)>W2(CS-(4%^}M=J zKdzc%5QT6TIoAB3t=G`)$azentClCpntyDIh<8<)&m^~z&aC-5-+H4jQtV8!NUoiS zH9vU6zjXU04kmeGsH(=g-q%ZIr??g{N%&}{#7X!h($5{XbBYmS{a$p$N1MUPWW{%p zF5GFy-yF%!#Csi=pbfmW(zAqfF_Vm~5AJ6@pK~Tye+942tJGt?ukG_JS$U3&iFw7o zE=hQ9X~1TIMNBf%;I(fVyjj27dlQc5mTSMo1%E|o&{f!kPjKBnB<>yu5tu?1NG~%s+n`dw2~=ES6vr zb)NY>8(>ve0rvZAnWQq^O=vOPi~9MAB+^IOMr;wBEuEXfE5#&C>nMLZym>UUVpRIS z@Gr|);mEI3GECA_Z{+?P@8?~Mn$jEOn55XVB=s*mivBRi1}53-=vdJK=izxx(0(mfM*QWudQZXbH8nM9D*s)t(ii6JtGn3; z&)gH{_JS`Xzl_2qX}Z@n;T?Fs?^T&32lXv${?dQi_v=?RCb`U%(^7-Q@O;;7Vv_p? zJV|sox!%a0Q=3U%iM1YK%|9u{yI!8qVv^TJ_CMaiU1;wP{!e)KBlr%+;kLr^$~OM2 z`A+=)%S$+5#Ao4U*h0ViPs3&=k?k~IkO?2e{e=)FNvbgHya{g`&D7J@VUpcN27kk0 zEsDcjY%7x}+x9h|g2Rj>>4myDU)d!8akwA#L8u;+=%IZ&1Ybq|%G-wL$=%eW3jgoA z@ZEiNKSf}S8!XP!XOc6+CL4z^AIcO6*qnm%N!k=W8iqewMQu5Z>(N@L_4;8=Tz>=N z^K)+Q=?EMs&grLw`^WipreWtv$+j2`Cb^=U|EwDRrV>h)ugCd9i5qLa@DtK!6!~w7 zrNhCk@T&!WLZ8<#iMXO-H7kCZjp;vjz;5WTY=nC-?$IdDBs+@?+IGO7m2A{`Rx-)1 zzPjxctl%mTkhFqHjtXW6v+kz|^<4m5V5oY84;C3VDY%I8WDzq`%niGsKf#Xjg#4E} zf%p|XbRSG&Fo^*AXRP_-zGU;rl|Na=M(1t(O)C2?k0!yzxc@R7 zkL$6mg}0-ATM3^bw&!@^81%9OMQC|SBH?UG}KQv0s*4Au$wq18!zfFQLg(F>tSi!Upams>?&}O z0iQyCng`c=3%Y*$i1!&R&m*{AsaWf(et2H7N9-c_1gf=4_#}?6$MtYO@6+KjlxG|K z{(r5PGP+h2;R{=8<0BBxjd8~;Tp#IW5(%s5=8vy~@24^so`MPL=Qh;0oGrEbu5cpi z!#-XnnY<8Zss?MIeJn%$yffgO+FOCdJe9(idJB*h! zp#HZg_E>%hwoKE_A3^(o_Q>uy+=uqO4(-k60+CNHusPnd?ckdje?0)Zq5b}~fJxpN zN4|G}Ji-I_QMmpDsWjnMlU1;x-|BN5NhtYqYhxY!*`ru2q z;577C+u8n0Por?ScVpf*8~CYbNz-1KQ!x9D1Nslv0s#rT;GO9AMWMg((#U?BBD@~; zzYzK--tn$UE8!HJZyk*OQ}`ly7X7nY^k+P1EqWZVJL3Q958ii73RI>);C&A5O)L68 z0XpG%Gq5-6TV?o&w(`|sI1caQZ+|lg>B(q)0t=%4UI+h1dz22Fpj~VF#UQ)*Ef~RY z9o`?;PB4gOWW35zI1Kqw6#cPpb94IJ;CRGuWQ;*p*%aAn!P*8q^V8r*qB&)X@Gr!- z1!m-?7)!%+)SqVP-yy!9QgH60l+oR=VUa=kYIweL@q`fig9n^qjJV)ycpuFhA03 z0O7dbM3%Q;9Oof^uaG~!rmYs^A$Z@v{f$9B&SbST!Rt|8We~o%*hA_zT!H%h1md%! zug*OM9>;i-)*yqt73Z8zh3{BJl@-FDB;@P7U}3a>SJA(2L9y}tzm7-$TRwmM-C0;t z*wP^w{ddAEQ=b8sJsCe2)x#hg?fDDt!5hYB_b7GZealVDJrkBees0G50M0kdy8gR^ z8V5%3zEXj9EFOOIC1ZIC-j_biWOc{D^U(k1$NN^nlxes-yw%7)nt}H*yuXQFgO8zq zcj_g^3m)iyaD{K+eP#k=6%gv7*L#J|96D4Pea z!1%ird;sGkoN(jOfwSeXG1|4SRak$B`u0R3>X)93vjecMY0sKej6cZm%(ohWS>qEu z@P5JU;~lUl%HctzAI2-bJ%{s=-whCs@d@4>*b3!k9O02;^+B$%1>Uy~!^d0(bcEn{ zSm(VUl|jxWCZ1Rf-^F;v0yg7IoLsRQM3Kkn}&en077TJHyc z`<|)Si0j=)J#`-5gZ|P&+`r|J1evJBcqp4xumIBQ6vfeT1*I-XMQS;t zSmP<5D$pN7e^UTP`d_;ZOQ8Q_1GDG2|Bi&E(0&%gG00J3JLv+);eBBO*F$`6I>Bw< ze6;5w{(_2%i%sE@=c!4D5PoY?^6xrUIL2e9@cZ8N!N0m+<^??6Tq`#SFR4mqyx_a(;jG5+3$@|ayyBlr_;{O0rGK{SK3V?3t=UWNXlXe6FL z=0EPjMHt_g!T8}z<4Dysc;;j*yxB@1w1}7w*9GOY&!sCexk;W^nO~s}UeK7VTBtDdcBY0n;lm)|q~Md=llaTy)-fcpK(*_1qa`NxS%M2Y4mYL+=E}r?t3` zuZ3Tu{2X^Ob7dfK6_b>f93%70K@n;@n5MhijDC2yG(4MhlJbP=g$H%R(D$@U=CEE7}FST`W zcXiEbZx!~u3v9-Sr)#F^!T|AzENA zH~8(U*6AB6$d4jH;qI^-#?N?_7$nzQkj6Sb?3h4+q&$AlCY3473csSW_=*gJw4$8! z;rgyubi%htq5LK$KKcZU;{B~y68T4*^U+6m1L_O4wdilChK7EI{W0EpV-3bjiwq)u zz%N&G`t1})eVEGZU+GOoPx~|pFBYZ>1nQA%eudecT*qlE@6CuJxKX=qu58x9kf{t#OrO0du3AqXP2NT;@<5-WtZhn!KpN?RD zLVkoIxtSFQ*TZix|EbbTkr!ykS^43_E%ethKYQI9!&9&x=BK4F-z%!o8Q%rxV}APO z2Z}VXoBKAv&8m5oBk!?3!$sF4N{jn+F#M}Hl{pW` z&tQL&Dcq=$dzBcd=gJ zD5|ZkaBJ!09ojwIFUqqvJc9L8yY689fpam(8d&q3vu4CCirmc_6BsPP_{uz~;DcD- zkc8{k!?L>yt~X$PgKf%a=W|y0U13Z442nb{{Q}?-tPfGb`F@7E96t+x$N5LIDAHsV zzjq5vNJWUby!Sk3!{LWy#oj%-%^%DXQDe^1KWhE2##rl!XY^>)&ef;-1 z-Z!wmfdNYkX3PDC&tm@n3j9vCeQPh=i1h=TuwFvbWgxZ|wm|%QalHfj-S&m>Hr!t! z!lR5MgTr8*4@O^P@cT?j>r`vFT!VXWDz4v!^>3QijyzOs;mjGNUog4QYzMU_!;4*BOm}rm>=VHCaTAcqhrbV8? zKd|270@il~h_z;&giEl#$vqG2m5^SW;L{v_aYeX(A>JdG!N;)g?GM(U#Lr~;{dr()g9fkZHrNF7$yvxB^$Yy8y5V}{ zCmDoa&Pe8|hb^(bVF2NO?f3_);3TXkdXMlM^+wz;;nC50qkgy;{j5Sb#HMdoGp@JW zO>1`vd<5%Hb|AkXf9l?b*-^f=5#QBLG4C$JL74A93|~xlI~5N1#wRA;!SM>ERnva3 z5awrhAUwrKd%q`q3hQko@Vs3ye<%$veVeAc4e1e*?)HQWPQdz|K%{TmMH-nX!g>Sb z$7k?XisRBdcogZ|i|4yJ-qk$~e(xA_EEwf&81Dtqa0|-2IM&PTb<-;HhO@B#;WWY* z6o{;GgfpYH^J>~;uQ&SRh;YP$~3H3+`tua1pZOsxoIA(pP2YT0S;CUefcF7<=wgX{%ZIi z)?=!rP=p`rp#tHDTFN$)i71~cp^3NPBCNmrlz{a_n6F@6ucyMZL=$dPP`sB1zrw!y zNLZ{SRlNwFGEfb*fc3H7?JZnR<1lx|`Cg#@9D$D^zXc^zr1x>9EFaRt0`*aF9LkT6 z_Mr{%TS{*KmMavgUErrH3)dh$v@TO*1?JaT=_~ecZtijv@~d&AoC(Z^_RS^&A%?zl@4%2HgI*@?R?4=Q(uyIh=v{k}GiNfW)I;aA$|{xgeMi z=YI-+>+%ltguS9he5T-2Vy$XUus7B-rNBP5Q{(oqE7sGk2txjlkRRLue;SvxUVD)u zBiN6i1#iXrDc@k!*9wY@)#0CFoPOi5VRHF~*4wLWBuK&^}*N8;AX6U4DzGMpN)Arx^RdMWSYdG0?U`7!4zsS+?`Z;(W`fKmu506sLpMZB@J>gE= z-`fR#`}N@BazoWExc_Da#gl8{YiOUmLeRe1@$E9GPMfD`Y$_vuVQ#3*85q8 z;r^bCKZ$`)Vf`Kr;YpI#O#yH;p5GCeH)iCo2W*e^iG?_RE9PyS;X34hF60k^fth_r zV1Lx-n=WDfB=&Rgz%Hmyt|LEf*UdjV^%&(B?Oz^@d5#yO@NT4!T_o0DYb*P{fWH~q z^WVnxgiBKYq{9zMxXW+28}EHb;I9bxhP{mJMWtB3M}5qW^uWALo)|oU^|~*Se&?rs zw=aax;(7TXy}i7KDu#2>exkj5?u+$kMFyHpaIcqOw&6LnUs(Th1D-&BW+Hs0w(|8r z_zBj}dimh~FrMuS`#51g!x@THU!)z`2e0Jt6OuoT`qR--LK&{8s@d_!6YKH3hJ5G2 z256twdZWG-33`_H2q@H~2P{`B?1o-Cio{Y=9eiHR|<;rnh*OFtuih3w}2`K;qnpH;v?bz)Kv;pxn= z`YpJBDVKqRQ7~=3`K7n82A0{bfva)rdDoe^J)@!6VEcyu~zEcZOhXYEw%1K7GdWBETgQPMg-4#r}Ho257&<-<7= z?!f*6HG~Iazg#%1j`f6#V5HCXKzNIyje0e%H;etT`{6}cKNkW!OiGFy!GC?6HQixR z=i(h|utj%9vOd!5#Xg6Vys)lKU!5L&&DS~aZ#KrCkRKaxeAz>Hw;osp>wh&7Zct$u zUju*f5|m{_IMQD-4t|32aR44(Jm2&ToC~udJ+@(gh(G)X>;11H{oFBca|%u@6V3Ss zvtd1`H9RI^&8LL)7eM{B1)gh2|6z9u_0@&Ash*Ee?XV_x7i0MFT56o(I>E8ZLZryNlJF-~0wYvBE)>>%1t>~G70CGk81?I}WcE*8vz zmv?##zQ_9S_aS8419%tuLw#_MN~pmN*arPWHd~Zu%%4QS9(W&6I)L@afx~L&U}>bE z`F^Yqo|_wRgME;`Ypl^9o-%!P0PfxE@J!zd`-cPqxLn}V=)VY9Qsg<-t2)7PhW62O z7FZAddD_z&e!o693Cfo>jP>R3wBh!>4jMvOZ(q29%SR0U^1yxY0et6y zewGmIi~Sr$=2%Z_$3JgA{C8o~YH@@c8Swm>y@&oh+9wWp;7i8Y@9-YvUu_)kg8of4 z{3c7-atyYssmaTQ)djNOWWkuni@pKZHP)W4G)4N0=B!VIyRcuVXE*8_IRWui6yZlcsC#3`h7l7wf`rurBBzynZCJ zVo;MJ`@M#KIluyfEwu@-!?f>i6V~zAU-MNR>$5M?{Ip?3>__O_i2k|(kEI?g>>|K^ z8Fs>a=q6ZgYT(WlwTkC^Fa+&M|c%g(5^c>hTmZL)!$Q zBm4xWVVYre)X(n_e&eBg#csK4Z6yb5~=9@;~E+LLaQ4x$U)QJtZ!shF9SA1KJ_2Ekc1{>io*#GSZ|NClk z;~hMR{i{WA_Wq*ohp++x@va-`$Uo|x5BI^wDF63p$nSG=$MxXj_QRu(B5O7v;ek8{x{-8`*1iWvI4Hr!$K!^iX=Zu(JzNZu>aX?9^Ut= z()MS=GN>Ql&*J+iUrnO#!J8CpiW0CN{Ie!^upOL>{qolEhv*S;U04PC>D;lOT1ePZ zSP|Zh`o$9asRhRB`($Bz@ZIEROy8A94Pz67qK(;EI3igJt0LVy!VoFgK3B){6bf6^4iRz>Ys=_w;UEWdG?a zdUZbdUuQ=0ENqPR#lsm0Uo9WPi|a{aS?Umc^>@|@S@_2>fwSH4&tR9su{i$)tEj4K zSQ^(K!|(t1JDH-I$~Lb);rj)TE6qP5Tm<{GIpJ4J18#hQV|Er?mu{ky{r7~|v%+0Z zmaKGv-yV*6-3I?u&Z~5;$NugvZ;oj=1K&4@!uK9@>y5-%_pglaN%(%m_f?iZ|JOfHGw0r z688HiRQ&h-h$D`$F7nq_81rEFS^4Y2ZeE#om|Y}j@fMg3?LjzxKk!P_mcW+yUczC7 zFUJ1p<#4|mchkXgI*~Mv%#?wR@x1}fS9Ie1(4E>2-^PCQrDb%&XQ(=43X38?7QMvx zCoqr1ieFJ^ylY)4zQ5Ea{!azA!S_A7Uf}yjnCFs$m*IO5XW>=Tz6wIH!|k#9m$1V= z2Xnu70;N&ex6n?gn2)dOpMVM1EfzeaP}H zeE%g7K7e^UFE|k24_WvO-=n$^*UEZcJj;WQb{C+0qQ961Cn<)$jKTLzVj|+rufbyY z{)oU+d@rHFYaJ^-Q)Pxv?;xCDeMkemdS&aGn+WeauEk`PKZm>ec3lWp#eSVRxTFso zqaLF?U5Gn74Ud)?s(yesHF%9JM0#9C`M3ca?^Sc)gWKW~6QAMxD*I&HduMRGwcoHw zat`w2(ScSDgzws;mUkZE)`7#T1Yk4Ve>Qv)-`il-U()yizocyh=}-K zq3}C=e`e?b%0qA6mMHk`kdO8roKJgwu< zGX4UNucLGD(%~Zh>^CzwA5)z3h#I^Q<)`Wi>Te~Ru*0wzp3e$ApCeXL0$1TmJdZ*= z9}Qn;&D${VPf6=M9FOnI1SP^E_`bwaSQ+0dcmr=odAp70b5p%jmDL_|;Cl_b;8$Nw z?)1T5@qM2d+~0Z3&rHM8XPq^5?xTD>PZi)p`%cc6ZvS!*$Tc z#P_TGuHk!FR#87YVEcT7h%>Ngy;0F5T$;>$*qlsf&C|wmBYy2wQ>N|k`m8YpG59g= z#}n@TIqR?iz7*?vIS6KA{nQqgOC}|m@a_eEEA-)Ve7`Ot3H9eaVFh*gnu}IgSOV%} zc5_!1_%psY_88t{6;;0*zF+QH@+F>5?qAViKfyYFr2gHxtElfWe#z>uO=k*QO2Kcx zXI^EcZ!^CCR(~1gcdyzWBiNchTi-t#-&?VY^4EsP=gcmJUqbtHLpOU3+)(Fr#24Rl z%ER}W{!dGH9?#YD?*TlLkR+dlkdUMzr0h$Rkew((k|ZG^`3lLBBncr2$(|NTk|ZGs z2}vYLl#nE{Cb_Tkd)z;tk2&j{IWu$4ne!fM`EkUzTN=erUcE51BCsmrGi|$o_$#VC zF(R-owr3QH_WD5`j~L90_HJ1?KjFvo*AloK@y|YoqCBmzUbP5D{3-RRFvK$x>xwHw zepX8rrF{%RyfBQzp~|l`?$5k4i2sBCJ5%AWa`vh}1Nq6lV|;E^a4q7Mm7l`>_NwtC zRempGdyD?#C%2FB&DFsrh~JfU0{MycsqLM|{!_jA$!h7MC0Vd7;=B2IqW^*QsqHPp z^+|cYc=o>bDlxeRfCt zwlTt)>fh&oFpXXb_r0Ee-V4uM_TXFZhImse!#D=uvQIfFrAHBO<&80G4;+U5*SjEo zOM6yuA6&OQtg`wr^6OXY;kU4pg-Wri6XK(+4v%^U%Zajw%pF3!!9mG5>iOZ<_q^J} z@D+Zx+`I6?j^00O;Ow0x0jcoq18N8S;6-hIUMFCuwx($@N5qc_PJFTt_K@bdBjdnN zj1?n0cfy8R5tsjVZj&l}> z?O?ZWl~t0o1g=haMHpA)-Ke~-@_ZH7yAl{la2 zAzmK(FZ}S)6$LNraK6=7=*Vhvwpl<6Y*hZf;LXT+b;>6 zrEBn$ve(mdzu=E=o2Fyb_(}K8vCvO2{h;%=f~|;`xJ6-8Kiq`)t@jkrUs+Rlc^Y1J zDDK$oX2kzI?V1pb{d*%mDUn9|y|W~10!}?$*&SY%0r$s`K-qsV zhq^<5yAByit@FU)T!qNG0JHyT5b?!SR+( zYHKCY9{$X`?gwu<9xt#Seq>hqk9wbw)**3jd@cIpE5iz@?X9QM;dhHRnTp|k#E=qK z$3-l^Xnz@ELZE(;k0iq|;<+xR-sd=;q!*0ic>INI&Q8MquZ{b(H==&HnDlKk-j}5Z zBx(~`QaedNbGOCH8Fd>8qbkM;9sg31=-ePssX z2|vW~;J@pJhcH`0@~S*>#9w=wu37+JWxbQi2CwSNxm^hJBA#!#80u@A7}r|(KU^<2 zQPlUAJZW7p^F_vswAE;jVn-65!D>dOBGW>+-Z#f?rNWK<=E|e1_{oMRJ`XO#gNVPJ zEP&^Wm0?$}!|r=Ao)xaf@s`3?Z=3%6$&dJP8zRn)!OrhygG!Np;Z@^S4ZI(w*7t+0 zpNlFxz@L*xADj z{%+x<){1!GS5Lc2C&5joJTgsx5TD#YDegGz%Cz|^IfHoWZUaw@;gYPe-OHw#WT%kL z4;R>eWWKFyoJsCmJ8d$6De^Syi@uYC`;T!}^TL3i#`Vk-xr(f9|zTzVHzo~^;h;<`g zJEQZ;D){Esp5{eJXTRdXwFG9Sd1@@`Vv+*8GIJK#RI+F_KfFNi{Pqj?Pu{Yy?aG}@ zvKiw>2H^SQ6>HoOAO2!TQxBEC2Jz2p+L3<&TE~9C*~;7OgAq^O+$8$mG`vdOZiNTp z%`YT+I8MN-xE@Pj=Czu-1=vVhK_R#m@!&%$`DWmrol2a}@DN|Yv!ytm9-*#TX~eJp zz#Ddzx}PHsmHRX|G0B1TcI!ou?sZXsZBrxS$M60!vJ(EVD>~^3;^WhGdvEE$R-alj zUm!kykWBZ^9q@za89HL{_Osqbxv5O02}j!7Ia4$1<)!m#-&4v!>y7`VY-vxRNc zUogp1#0{~9xe*UvtQuoml9Ds_!Z&Z!zDjw@BvN}aiXLm*O zUwX_Ws%E7>^OlsUrv<-Yd)$^$(mj6KS{B#5^60=)zpn^$`vF@D;gg4w5 zS@P{UlN{Yt6y6SZ%`7Z@u3?g8y1mssu;zZX1MHX|K(s#NG*$l2Tuxr~ua-$Jgfpww z!oh=ix?%9?u;DQY_~Q50*Fmt&%`tB|Sjv|7eFe5>_irId0dD!vRXq>;^Rsp`)PXlG zl_`pVjo%nopM;GsX)o)nLVjEF>`#FUC-S|fD-oaHtTZibf|nH9Jarscc1!x?v3&pi|v0)O72|&$K1epQ}}X^|DDY+#{p;Odbq)* zoNWhevxA%U6zm!{yviJYgyX&ckV$@cXxK!-n^FGO6*0-(GM}t0xTi?}V&8oxabXM5 zxdm4i{64+A5c5+w@R}9CyKsEV3UK|iQzoeK0-9b!x$JkDq&KbGa;N?ziU+%5n zK7F_^E;(5h7BMR|*#n1eQc&>CW0E)3q8twJlveK_7Nq;w_xt(5YOjp@4#DENwX`HS zQyzg}U@ryxhJ4t4x6_jptY1d&WWNdfy`2sEa})KON%V?Ou*{1_qeaMHE+faQKVadj zg0j)b->Y9*1eap`%fvul?QbmaqhP;f0qMrbFH1PSRKIZ&uIDb$6UX)in#G?}>F)o6 z6aOOrFiy)u1nbYc#|u;;zf3XCPa6I*kf$4k^fZhs*$IyfwZ3M77bY!U>A(k&e>T|O zagGk{AlMD}(^>4Vj>%RL4=3PyoW=FlKz#XRI8DZ0H4evXUEtl456_p2%E{q;dNJomu z%fhot+w3z?p1E%5w41fZ}JEOi?j{70LHz)o%EORXW z>PeLU^=73W8!;a0ey4u|FOEmjtaP&$?3g*$y7>;;Z;V?#0JA?cRPw<2{1qwOZ3~Cs zdR>AWm~6F2;e>Y*?9Dho+Ds7N1=#z~#)x6qw4*8M7R-nG+Zp+Hm#@II3^rLC!TgQ# zkW0mdgE#6r@-`qpkD@*8gm1FT6xqRnT&&MW;gzcjy~nWpb>6Vp5%~T#t`2uxKgOSY z`5Aa^y}0cQlxJ6t4%$0d@OsM5B9!Mxi5}NlU|rOAT^UTW0`qq~f@eG`(z|Xj$#g?w z`9t^?@>>?^CTt;Tui+LK4X!YxmowQ)+F*w}byKnFD4)5t!!9|ihK@H2VLRl%5zH5$wWkCwLVd6bPEg~@`vNaT`=^)6Byqf99PeRA8(!<+ z6tp+d)$5jFe49P$t8k>}4Vjm&gY`BkJn%uf3Fa4(h1F5NZ-MV6dUz|tayPvP%dVk5 zx8&)Ug46I;OcmA)8{S7PzrVXhoR-8S0bg1g*kG3^0k&<4n14t>Hjx_7XlC#1Y#)#N zU8XzG9Ij09)DVN|{}v9|!Y{{yTr**e!+Y!iTNeA!w!^+W*80?VzXd6dJ1nudKT7r4 z_QLy}2IgK|!hA`BHkJqAe5@}5$5u4l*MmPaWqF#w-=~AVQ{(+4?bLd%N25JK|8o=U zqt)y0e-ZN;-5eXI&i~)-x+z_FFBfZ=94v$VH$|bpRQ!A0R@j|x^Hm?_yCp0r0Vm-2 zk6yrhPlk?zo8izAsgLYP=h_hAOYQG`vQEiUq`UH1Z=lY%+?eO?wMfiw!&jhm7%t1v z>kT=F{;0p!q!S$BjUV`7AB@YkhxJ@EE?f^s`S+=aI0#n;4x78cwvKA)o^WxF-a#&S z9b1Som0#ByjQi5D{uAMF+ug9k@Vw<~IMk)w&JfPa61G{4k!o6BY6eCU`f>98Np2Q&^x~HGwh@nox}}SA?|5EToz0m{yW1YYh*blsC1hY&!<^% zONOTgH;(VyerM;6a9VPW3pE~e53Wy3Ao`zyu7BC#*!f_FascYvoLY-Tut4Hyo`ye@ zZ0a^WyacX&;6ppUuq_jj<>xYiffuc)qqx?j1gGjxJa zGRcE<9glBt-(kMRoUo^s!(pnvxVfdLdF}-EACzeO0uF39jgEqsgbjyK^~-(EuaFW@b|W?8++k{IR7{goWCrGFl9~LAI`^6-t5XY?0_#Eh&wjuhVl|! zy_y=2D=@n;g64|*)q-b_61>{K(x4yngIQ{9+q@mVc|_wvk_(=ngu~sW;Fg_^v1&)q zzi{BaDGr~!sJ-m%VJ4A|uHL2wUwdk(qyc9dI?4sWyU&jVHXp)#ZB61))cLwx)Q;K* zr%YOe9flvS>YDxH$RzSk&h3Zb^P0VX`W(<7^{IGy46ZTwvM$yh&wuv)SIyw;UqRnz z_hY`Y`Gsi{xZQU`;SyKT@7EjRX1gd=3 zJb(IBr02mdA?^cB1oiiH(C({nty;;6kMNVt924i^ae=N`3)lhUK*QldPkMp429qq0 z*B(9#Tgw*jdZC8-#4r!RY53z9p6gYaWCO;jQR}}S%O7)8LH`?Zb<^QvTm^b@u!uXK zS|NNsCV5qpGLzIl_?<)bPuv{`0=g8@Uu`k|@D6?}Vz*)$oMz>8`zsu;#m(xo4doBx z95>_q-itt*`md57_g}h>Nf-S3S%!`v z1O1_fMxQcR`S$PAoGUTEUg)s=71(b%0vD}dlAl81!@jV(6|Z#&FP=ZEL|YESH;)ZT z`g7y?lEK!b18dnjJL@iI;(KM_dI9*f`wZy*2Qn&?Jv>b|(4nLedox_}WY3J{Gw1h3}Lg?6<>_ckdF^hc7eIc;RpF z{OJyC=#Q-FT1A7UA5GrWgvDC@GB{y5iP8YKL!~WW0$A;*X`_KmElG`jqaLH5N8d<=&N1IcHtJ_gCTu4BI!4%SkNJobe_&i`zErw!*$@8L1+W{{4X z!XN0c9Rm4${Kz1}2Y6dVVS1DYp9)-RQu;{{zR-~M>tq*$NGKMYZG*q;bN=?{1A`pp zmz`9BUB=pGUUXvq(jR&344A1M&41txgXA?ER~y3*Kbb3Aw=jrzs^GLO>?CEcI?==+ zEDuHI_2FFQk`sXq$WH@D(R1*Wm#eyKJ%boNH(WzKpH&~NNPktwAe)X3Jc)q6{c4+8 z4)@yiFY<)Bnr4Ge)iTI|aVa)?SU9h4>e~wjc@s`{xxn0Ww}mTe7{u2odh`J7(wA2o zSIr>ise%#I_Nx#W=^T71z}4LwHaRdb_p*vXEXJj3{9!Z9-zr$aAf~&NR$0KOcSI+> zEoYEAyZ%CIe~w2h)@*@&n~iO(;hR%?cpjHANML}g6LoweGCii;ud#R-^UXsO8wt5)0XxX7=hV1EV+t8$Ykebk4=ne>xK9>V$2hTe__|C_ zbId&k=_*S%p!^AemDa&GFi%i7yl#~|#|#`T!%;i|(~)1x;U)aC+y252BebJN3K&Gu zz_FAK_tQlGeA`xRf44~~ld50V?1<*S2=5eQkEGI1onm&16)}iQ?%0L3@CCCneGVLN zfnC4AcKF=Q-}ByBUg+2SMGIIrfPCJ6i$TuFa5N^vb%~x&cjTfxI;f47z#DVxri|dP zu6)a=_NmxIYg^6@26Tr+$2Vcvno7$VeAWX9_BUFE; zV@ZKtZal94naZ*VSfGF2l1kqbP6ny|V;{En80jpTDcQ;JIdP6VKVhNVG4C5NmrCy+ zUwBbw%AMP=oR%YR0^ILiA^Q}z_fC91cp2rF+xkrr?AbUQ^dOEwR+xP;z5`2+#cx$pJeE4xyT?%6_bUf@P#c7 zhuzOJ$im!$Db;^9UL3Yv|15)4)-`^l`aA9je8myMASK=vN0z`Ik9{kK&mey$gNi0` zy;S!P%oPPOh=+#5$pzSQxy{#ar&0bbRDOtJd0zy+vkXLea*ESg1vBNgefk%G>+7fW zf=WNT%5FuEKZD%$1sl@s`QdzBHk2iTHc^frI&`_`^5aVrSI~?8sC+j;Z zGvIq0ig(%gFbHd5od?x_5m{O29SBR6=x-gv{+oMSjnh4FzuNZ84ZvI1bZ0L+#vmJ< z;zn9vhg7O^}b0|A?in-9onbKpvzle-55dH9C-Fn z+#c%uJ0^n}hYm7G{l2ou``CW84v)-jq)QIx?NxzIMB{zn{S)X_fD*hHxM@6MYXAssaaaYOz!!?yyGJUrm*D+>6j?SJbE)LIJH zU#U^1+UsPb7ppKxZI$6D)&6W|$e&k*E%ue=2g5=zQDP9|vm}^mzrH)h3sfsI$larS zZ>jdP&}JZ@dK>D~*|uP+y(#I=(+%B<{J1)*br|0MANl-!3xoVyYj?&G_Ppgo3y06g zYG)mVKUIi#ZIEY>?^F4!iePbj4K4`@1_`M$Z2kt@4g`IVgOAbJbTeUg1kO}|%WtHl zQtj8)ev3oD#27?mKW__ld`Hip2_u*ezDrnrXKp1IwEqE_Y&qi*iK5?coB0=oP<< zQQolr?ltJIJP^4%4<8op&gO&%&I})%hW|YD)qEtvAUq%aeHLMTALIU(WMKyRQ&4BW z5~jze)WpJ~pIgQS;DJY&pGpY*#V}I00cJ}U{vgQDAWwIzsB^#uvn;pI!d)RuuK{eo zWOhad1gqy5O~PI(f2R z?f7NbSlda>_z9gz=qQD_z)oYgg?(Xt!%|J^dyuBbu=$I}bmC*-wAc*(xHQ~Nx{OYO zH*%cSrj{3tB%6>vtR8h%9k!dbdVHybPJSiS2+-m32N^G(!wrYZ>C0i2Jp%#1?$Js0 zO15wBi|~J{72o1Dg~*@h8Oz_mX;<_P-n&C5%S7c%tKc7}M*ix+voEKk8e#iODLegd z(}}}b_vUKY_NuqbXbzq5wq$Ws!s8KwvU}k-zbu~A!MFb2eL0&=C+UNECDiie;iGxk z88E}fs2)B(W2LevlTJ3@tz$2R+e)V29=|~+2?;gI)c3exZ}%hnV(COnJ!<0JeQd8S zP%AN-PQJ0RZh8!R&c8Rg8c8R#6`dY8;3CCn{+0+j`C06fasf7O&(nQ#mQIf2yRjcU zV-tV%U;v$5VPpMr3Lff``j~c#PW}wf?>qymr~aPLI7ug0?VWwE!#nD8goNN~UN(;u zctGXLx&qRHpZ)crz zV39S&b;Gbvp@{KaIHg3~*3*+t!is%1-GMU^n2GXZKFpsByA)5qbv=giWv8Y@t#96K zamdk~PM*8R2VaJL5J-H~l}^6vm!6Arc0XBjRfcJz%5frqKhYbfPjmFR>Z^?Oi>2Ll^mN)z7;Y{<&F+ zbFC(w7`D!SlZ1t$$96|*(8=HrsqBq#K$-Lld3a@tNcbK_Iw^kUYeJb7f!=jR>4g81hd6b7yAep9SAR^jcgDv(rJK2IU}wZ^wEf?6|X3j zZm8LB*7KQ0CRVXO-d>3I^*Sa#>7)@MDFp@U`+XprJV(uY8hN&g{U8gjXPZDzvspWh zcw9;jp}f4g)!6wRjU2g@oUt9g=1^%c-a#WVmq+<`!so7tga?125guXrLT|YEhxC?R z-)Ka#&e(=3FN#(}xgKz`Tu)3AY+^Me$u&qLqeoosQ}^Ha!AgUrqcqZdZlvZ9?4RNj zzY*tuSg+JR1^4rIR)(-y_mnPW+^igT9GbtI?ix z3iOz|A-}@iDy*jAKf>GWIgy`sk3~7C=SS8P+EHq-;)8Tm893I?wfr*j^BRAb*jD)8 zu=JKExE|kLH<>!ZwUs$Ss@R^){b;@fXPf>#J8X#KTOl2paUE8!$`K0wNF&kTTK7=TYaCbgFJ8v>&Ls$H zQQu2S%T1$=aJ+Q6o-@_(6jAFD!TS1-CeJ^8jQ4T;#k&UJkEe#?W?=Sz_s0LW(8#vK z8V$?Ka6NGRC9O1)aWXML7v6{M#Wm50!sXEc3pm3A69r;^`~0+0N%}-1HP=!mX5pLaW%|nfG~&3qc%}w6 z+QxHt0_Ei%3+u8_I3rrGw`7J!PShFipyK)PKW_T(E$WB2IS6Z1 zQ^$AZ2g|07>~uWma82KZ#ck;Ydr-f~%J=*?2>)Ii^}}W<9dSs)x9e&xXO z?ADz9@M3rOBRV{&fB)Ss-%*a|k>@!nv&-mY58hiJgNLr^bGvcTNqtI+WeQC9)m}CY zi{Glty#ZgooHm+@?Z3i%abCo8dR;Gh|1ge+DHD0h86Gqmm|KK&{tkbm5IB1WueBD^ zTN|_9^HiWc`PAme!G`1E?quH!SK48IJ=Axj_w=Q$VW-ohc?Ew^{wsWS-C)gJL!~Fk zpSamQ&iQa`k+Gw|ERC4gOrIEs1y*x))WY?6Pb~Hf&(Bvy!W-vkglKWw7{K2h5}z;3 z(=cBSx8MO-`kCqSPycAdDpBx&C!GII>LU{_GIdh(g5zfvxA!dI{%}ORS$G^1kGR2y z-76L{;W%6m3l=)!1dL@i!#@h9EhOQ+@uTTK;Kof#k(+V-LQ_(V)>Pts5Np?|3>@FU z7Opj>@ZNV)cA_|+4$gVWU4Rl-Vr!9O4x=>(@0jEY4|yKXQ8<5KGa7c zflT=V`0_Bz?RwNl$MGHDD|};m@!llVFJ2q%$D3ir3dC<2p^>J;8hup!zZ}WlKTF_~ z$RC+1y#L)Copc6PGFEA;hn>-$)crvI1TtsE5O49Ck9HJ4>Ra{cjcYvN{*6kJZgAx0 z;_VmUs~**pE~sChJ!}|z4&!Ueh!GsH(LQq)J{sdaD2L-K=PWog4L7BwUz0+44{0+! zEb<)nkGV_S18mQ)-G8ektXn&mFZZ2B-0$fZhrqY)PFu7M(MZ~IwojSxwi-;ti1b67 zi%TovUn@AIHz9qkM0Y|xtS8vhJb?72B6iP~*Py;J=3Cs4_H7~C+d&rIx~F1I3Op=U z^l&|VHsSYazaARtTieZT0T2AU=k4E(`}w7@%|-a4ZrsQa?q|2BzRodl>8Y9Q+?9)mq+Hh2GkH!DZA1;BHaIVo#VKW*dZbzg4_i&dk4q7=n;9CrJ>=Th8L zl*g1>q4O|rkWNWR*xK76=ja@o;*nj-KS)_;ok z^sDReK3JmHU!nrb_n0d?!mUOc7wXGUetXP+-G%obL;R-_8d+kkmec|NEy8>u@Vaiv z$R7CJsnPZS9@B_xf2%QDJ=*L0en+{mzgr_g9~9vuk7oZd;rY4Sf!6Q`v62&NPq2Ni z&QDbQTC>=?si{&LvF4FwWWYvG{pq(Kp+8fUe(fo|1E#@#!xmiwu!$ADAQi{EG=Q1^ z4gUUJx=5#rM!G$T#5SAesi(kq9*iTknV}{pV?!+Xzn%cr|yjrta&st`Q3un zfb@@&N|Cp7X~ZSSeZ^aNPm7ct^E&F2mww3{&Dg(}$K}wgH1gQXRay|~Mn|hBmnPu& z5Axmqgzfz;^H10wOC#-Pl05Ffiq}QuQZJ#u@Q>yBEx0~TWXZ9MG?J5BcikH{S|raQ z8bu@PX@wvBV2zHpnRAgSKOCKs|G_~TYCZB1XkU~{!VbdAdx8`9hGF^fg^oa&&reX6 z=1;@>b?=r-u#0kki^_jA@}ElYcslHVOnaG~59%Y{@T`~c12Jya?J!?Q%Y|lm^@>Q+ z=7s(*dqKo7to-x6$+P3gzxQ*e#^6E+gm7`Ek(Ir9&YU>kONCAUiNjL;^G1B|mBjRG zsm{26(u7q_VBT=OUJoav3);y>!l42VhoxZ4>EM&k;MqN{>PKL)bhIPy%bVdF8>*QRCn4mcMk=(wbXUR~d3#K=aXfq9wR|6d&FI@c=@YaMr;`e1;K931)536* z%g{gCTeN>cW4qsI;reH$9VhV2qns2wP2_)h%$Y?$>u4V&Z{JO0D| zQ(WooNibKiu+1%;&jFVqk8JpgQ172#IQ}&b8m`Y^$ET9_Ct;Q@bC*_F^icKWoE)BC zw4(Fgz}W?}c;umx9~WwFeu6DuSsdb!!Tnm-6fpr`w<8XQn^0eFExEm@4gCXK;_z3L zModEme3am4OB58`L}(=JamHOOSo-(9aW!EYxjaM{Q9EQ0mV#Oi3ihwIM&KJ5+v z%B(XPf_IMYbE?AfnMdhAf5Cf=>6;&6|70oK6ze;b$NQ$si4cvXKlj^U0;`y6ZKDgK zzjlzX<%J-5&dge}^B_Z(5XMxW?G0`91DZdmJTwEXc(B(0%hKnEhC#1oPHx}Rg4U6e%aJlTm{@?hsxp&}soZq3p2kECZ9p7Js)w3Fn zoMBgWC6-?J*7>wi0W81V%K6g4_jum!ZC`7780|rmguNrIvB)ka4u06z`tA(8@hyHF zheJL{u8f7HWL1iz98tcj#9v*7dDlntuS9*A_sDRd3|_a+k(Y-0)gfObrwNvrI_q`^ z_1$R}>)G$H@RjsylBn;>?l&Ya>csQ1QM|xy)R$X@BScu?4!dDlxy*|E_V^&5{(>KRzLq1E_5v`1Phz2ek-aAnKw zRlDFBD`zG(|8TV`?|XOHp58@Pb>V+If1Q#Tte<1(w3xu#gKG^%PU88Y##qn}F4S~( zzUf0Fvb^DH9#lFfhx8e=UnP6g(y94wJy$vO@4)dk?jH!~g;#HnJ9Y^9@i|s-;Ww3T zsr9fQ`4@M;L4OA3U(@@?75V#Al{=G~Z~FE0y>T-KJb&bi+!gqU?>T5+QVybgTJR34 zz#F=Q6Xy@mNTRyZDJ{5G-zAP0>1Im`&N#u}BphSAvHp(5VJ*ku3kZxZj^$tcTDa#A z$4}q$K5d8k>gdqVbU51=^F{AR|Ma=B%?v!$n(vj2QiuGy7(K| zJuBnI4LD5DuHz;A$F|bI?KJY=r_$gr>_hKqmI$Vis6ed^SnPfI_e{=X$|dlCIHb(0vu1*9jx415+BgZ}24 zqVRo4clsR6;EzZ9*=_D}3hr21w0bIqMvMog0$Fma!Ph)lHxgxvMGk=Wv_bNML><+NfUru7iaZv4_}aq5p6(`SDNe-@4H6 zsA>-Kzs|Pwpds zjbXzNbF;0;FRQMFGojd?=pJ4NFW9m-m@%4(=jWN=ZYenRecOyRj(5IGlG7XcABN-q zhy0xFHun>ObpmxtJmC#1!=tGAU4v~CwF6)`FV~L`V9hN2Uv?Gkmts`08@!Y_e^bNu zIL~XRD8YX|2PZzm`8!?~d^v;i&csB#mN@^5ZbOP)@XfLJCiOU;WfuK~FX4+b`<#y5 zqv5-2uuKSyNFoP9D`;f*kknsYm_zkWM`I_UweXi($@`=M$J^L+oSILyz5jNq ze-n+colLx)0dqga_-#CoEqQ7Dotl688=gmGThX7)O?&hTF5f#O`5i8H8%Yh|MO zf5K}|Cffdjr4KVZ%i7St+V$la1N$?=`;hX_s4v$m95TfDap3*-$}cp+zN|CI5jJ5) zR>^&%5gSIKpckBt_dfxHxc`^4DTcwD@&0MYFxson=AP%_fBrQ$G=IkH!jeH5-wDl?LV!cLb*rxPgiDJW=< z(1?X{)Yq%9U6FC$E||-TH#QqKi5zP^jpd~tq<^o158(ajdhFli5Z~MjSkQV%GVnXv z!|P)M3`tiWI+G+frx@J({Kzb?h49q&TA_=EHh`mkHi!kHU5-wm7vJ+kn)x4_v2Y|o%CutOcrQj6J< z4&NGYYte&uvv$qO;CvQt{eDf|zv3o*VISZNRgLb1vO)R89UPzZ5^MRr@Eu&Ajbpez zR=h3L@@Mh>^7uH7_^gnfw}s<3aI^YO;Q4k<#3!o$_|cW`RWgnD>yjKh!(gLW??Hz@ z*q$T@cLaPL?~~L2;(6za&XpiI&CPw_#yp;vLz5Km!nfcn|Ipst({Idze@)!gySzXn zyn3aYWw4B&$K^J>?|$$}vg!tWJkRjab-dqBWMK`+g+Cumd``prNeLa$WuGd%mi*wGpu zxS%~e46k)?Re!@xM?8Ca(hIINuspkUl@MGPrlUxGue|9oq`3rkbt9h>@O_hS zcg!CNxaE`wU#%FOtg|c|QimsG9eD-U(8+EEt|N!w8W|-{ORPU7$+0yPzJQ6BGO_(d zmSvnT;HB8!hya~r3(Nl!`ilPDxYc7t9IrDy{Dcp@8~O2ok4}73QnK^m6C*5}tdXC0 z_w;{mh0FYtSH<9a#6RVz)UR+MCf@lE9{y~8ehLwToDX+gXn>Gx4Tp?nb0 zh#(u7&m-w)6233Qyw7=l0?s~PYZ$hePQpWzE``Gdhlk&s#{2mr?f!v^-_W1X8r;Gi z!AyrQ3d<|I!pV0sbi9!NN#0rycfl9dm;Anq@{y5No23T3ui@(0it8mJ-;<{Vf57tl zR^xgX>I+N5mY7IthXlq;IBR^!!}%?$lwgnAgz+a~NkOV`F($r>l|lY(vM-Z?OE)V; zGB;!VjRKdJ2;8!y>(mZeI?1t*>*j+`>#6myZo&5=C5JQ?xJZ=C%4jQ{?3ieq`HcMT zn_Jwjy^T(kQd53>g>TjP(O1it6*{2>(> z4y*qs!1fW}|4n~Lowa~vUgikx+>Y;2j~YVsVUv?1e~%D45nJ9_q5!Y>x^U*~PC6M4 zabIB!`|v9$B<-S;l8Lt95tNU+$B4sCBRbLB%B3fV^he{;TmBf(iS&JaHh);Wac;vc zb2?d^qn8l_UwUJmjig zwio&JHE=~JTo_y<8e&aHJiioo>UgB--4dJj;r{J2uhWBLv(g3c!kj)@$BbZhjMvy= zhwpv(uk92p5ncQ0qb;3G{pM?LMdg0w1m|w#Y<2`(|!nfdhG2fUg>tZ~{dSUi_$_ZTT zAwJG@qV7#+E{CUh>|&DK>4XuN>@|$_mv8R_#J%)cLx(|Q}{xH zUay-k#&b9gJh6etngP#U17Jv%OBUjP~`40c&i1*&%$E(uigQf?a}L%_shbK4#dwubi#aMk+C?I( z9%8(Y4Qt2SMtJ3)(8`V&j4v8$4X=k2N^w0gK1iuKORgNwP*CD5Ou+FE6){P$Osr;o34QY5nJ}IKftfYYzLj z6=8oogZ9P1nAdtQ_AjgvCEW}cewuHa>!y>sv+kq!VV`z$==G)<|m}vA7e9Wfbp$FDSx-K_^ydBE>`3o+( zFuLArC4=1Lvi4#{{-}s>NN=Yxi0%5KZOh@n)|SlebOz$B6usbpeKDT(0+T_Q$Kz*S zWBqAN%=%n_K`w?cdrM*W6upBvf()`PRY%elR>s8kR%;lDe z5^byCU0&J2bh<~Pb`{dq zpZnH6fLryPo)k+k$cdBm+-lfsTd)5*Nd|dz%Ugi58730`v7SK=3Ke=c!`DkO--Q%| zG=wm#D7(ly9NxYG<6}Eb8SSv(jkMz_8*#pC*#DP)u>k)Q%P@%I%1+<+NN2vt`ZW$8 zJm%8d2Aj{cuYJ3jLEgWcmF$9p{#iY~Bg-J+;}&0j!(z|twUlqJwJ&2=#{UJ+MBiV5U;ULX(o+g=G@-qHKr0``j4QOwt5knvn$M@?8bc;v6Z zcAVc)zQx;N%_W^CnQ+zWE`1GH{a%Au4g7mugvnMoj2f@LgMsf%T>RSbpioho$4&-m zp9oT=p1<7hPf9(3|1|sM8^gPA`_Q^{7)0ls`%+8zfiidK2R;11ktfV$4g1_pzoxp2 zL9{=Zo~Dk!=Bt$51z7dH#AYkFv~S+B89uhmI@t`qwx4hDd-%k~ks2F#mmlV{H(-#D zsX7IF;2USPm(h$c-ds%nsw12lD!{e?Z`(&!Y2aUj~sNv`QA-SItM?-{}C?mOsw`3cX(fwcvsj7V$ zOyC;{o*GG~8RTJ}@U4G1zQI?s|JK8fqx0^CFl&u*A32Br2d4AIe!;0$&ff+u;C~F3 zkP#uQAM3~L?1*KM52jz{?ct55-H*)NV2}j9PQ?;fl%G9h_zr`-V#;dJkv|7_@!Yj4 nWRR_I{DxFu@z~M4jw0lTr3&2${&*(oXLbqh_h#cVZ}|TJA3#q{ literal 0 HcmV?d00001 diff --git a/scenarios/metropole-ruhr-v1.0/area/area.shx b/scenarios/metropole-ruhr-v1.0/area/area.shx new file mode 100644 index 0000000000000000000000000000000000000000..597192651bcb2a678b5ec5f14dcb05062b025fa9 GIT binary patch literal 108 zcmZQzQ0HR64$NLKGcd3M<-T0}|Npdzu%mXx%eeJRLmk~_&XhFrlyc`G M+EGM}7#PA80PhYFZvX%Q literal 0 HcmV?d00001 diff --git a/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-10pct.config.xml b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-10pct.config.xml index 3efd39a..e4a30cb 100644 --- a/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-10pct.config.xml +++ b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-10pct.config.xml @@ -38,6 +38,17 @@ + + + + + + + + + + + @@ -57,8 +68,8 @@ - - + + diff --git a/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml index 56793c6..0c81517 100644 --- a/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml +++ b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.config.xml @@ -38,6 +38,17 @@ + + + + + + + + + + + @@ -57,8 +68,8 @@ - - + + diff --git a/src/main/java/org/matsim/prepare/CreateDemand.java b/src/main/java/org/matsim/prepare/CreateDemand.java index 246f010..08f987f 100644 --- a/src/main/java/org/matsim/prepare/CreateDemand.java +++ b/src/main/java/org/matsim/prepare/CreateDemand.java @@ -122,6 +122,7 @@ public static void main(String[] args) { //---------------------- new ExtractHomeCoordinates().execute(outputPlans, + "--output="+outputPlans, "--csv="+ outputPlans.replace(".xml.gz", "-homes.csv") ); diff --git a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java index 561643a..2319c16 100644 --- a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java +++ b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java @@ -21,14 +21,11 @@ import ch.sbb.matsim.config.SwissRailRaptorConfigGroup; import ch.sbb.matsim.routing.pt.raptor.RaptorIntermodalAccessEgress; -import ch.sbb.matsim.routing.pt.raptor.SwissRailRaptorModule; import com.google.inject.Singleton; -import com.google.inject.multibindings.Multibinder; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.analysis.ModeChoiceCoverageControlerListener; import org.matsim.analysis.TripMatrix; -import org.matsim.analysis.linkpaxvolumes.LinkPaxVolumesAnalysisModule; import org.matsim.analysis.personMoney.PersonMoneyEventsAnalysisModule; import org.matsim.analysis.pt.stop2stop.PtStop2StopAnalysisModule; import org.matsim.api.core.v01.Id; @@ -39,18 +36,15 @@ import org.matsim.application.options.SampleOptions; import org.matsim.contrib.bicycle.BicycleConfigGroup; import org.matsim.contrib.bicycle.BicycleModule; -import org.matsim.contrib.bicycle.Bicycles; import org.matsim.contrib.vsp.scenario.SnzActivities; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.config.groups.ChangeModeConfigGroup; import org.matsim.core.config.groups.FacilitiesConfigGroup; -import org.matsim.core.config.groups.PlanCalcScoreConfigGroup; import org.matsim.core.config.groups.SubtourModeChoiceConfigGroup; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryLogging; -import org.matsim.core.replanning.strategies.DefaultPlanStrategiesModule; import org.matsim.core.router.AnalysisMainModeIdentifier; import org.matsim.core.scoring.functions.ScoringParametersForPerson; import org.matsim.extensions.pt.PtExtensionsConfigGroup; @@ -61,7 +55,6 @@ import org.matsim.extensions.pt.routing.ptRoutingModes.PtIntermodalRoutingModesConfigGroup; import org.matsim.extensions.pt.routing.ptRoutingModes.PtIntermodalRoutingModesModule; import org.matsim.prepare.AdjustDemand; -import org.matsim.prepare.CreateSupply; import org.matsim.prepare.RuhrUtils; import org.matsim.simwrapper.SimWrapperConfigGroup; import org.matsim.simwrapper.SimWrapperModule; @@ -71,13 +64,10 @@ import playground.vsp.simpleParkingCostHandler.ParkingCostConfigGroup; import playground.vsp.simpleParkingCostHandler.ParkingCostModule; -import java.io.File; import java.util.Arrays; import java.util.List; -import java.util.function.Consumer; -import java.util.function.Supplier; -import static org.matsim.core.config.groups.PlansCalcRouteConfigGroup.AccessEgressType.accessEgressModeToLinkPlusTimeConstant; +import static org.matsim.core.config.groups.RoutingConfigGroup.AccessEgressType.accessEgressModeToLinkPlusTimeConstant; @CommandLine.Command(header = ":: Open Metropole Ruhr Scenario ::", version = RunMetropoleRuhrScenario.VERSION, showDefaultValues = true) @@ -204,7 +194,7 @@ protected Config prepareConfig(Config config) { log.info("using accessEgressModeToLinkPlusTimeConstant"); // we do this to model parking search traffic, as on some links car agents have additional travel time - config.plansCalcRoute().setAccessEgressType(accessEgressModeToLinkPlusTimeConstant); + config.routing().setAccessEgressType(accessEgressModeToLinkPlusTimeConstant); config.qsim().setUsingTravelTimeCheckInTeleportation(true); config.qsim().setUsePersonIdForMissingVehicleId(false); @@ -212,17 +202,17 @@ protected Config prepareConfig(Config config) { // adjust if sample size specific parameters if (sample.isSet()) { - config.controler().setRunId(sample.adjustName(config.controler().getRunId())); - config.controler().setOutputDirectory(sample.adjustName(config.controler().getOutputDirectory())); + config.controller().setRunId(sample.adjustName(config.controller().getRunId())); + config.controller().setOutputDirectory(sample.adjustName(config.controller().getOutputDirectory())); config.plans().setInputFile(sample.adjustName(config.plans().getInputFile())); - config.qsim().setFlowCapFactor(sample.getSize() / 100.0); - config.qsim().setStorageCapFactor(sample.getSize() / 100.0); + config.qsim().setFlowCapFactor(sample.getSample()); + config.qsim().setStorageCapFactor(sample.getSample()); - simWrapperConfigGroup.defaultParams().sampleSize = Double.valueOf(String.valueOf(sample.getSample())); + simWrapperConfigGroup.defaultParams().sampleSize = sample.getSample(); } - // snz activtiy types that are always the same, Differentiated by typical duration + // snz activity types that are always the same, Differentiated by typical duration SnzActivities.addScoringParams(config); return config; diff --git a/src/test/java/org/matsim/run/TestBicycleRouting.java b/src/test/java/org/matsim/run/TestBicycleRouting.java index 13b844c..bd54810 100644 --- a/src/test/java/org/matsim/run/TestBicycleRouting.java +++ b/src/test/java/org/matsim/run/TestBicycleRouting.java @@ -88,8 +88,8 @@ public Config prepareConfig(Config config) { preparedConfig.global().setNumberOfThreads(1); preparedConfig.qsim().setNumberOfThreads(1); preparedConfig.plans().setInputFile(null); - preparedConfig.controler().setLastIteration(0); - preparedConfig.controler().setRunId(RUN_ID); + preparedConfig.controller().setLastIteration(0); + preparedConfig.controller().setRunId(RUN_ID); // Disable PT preparedConfig.transit().setVehiclesFile(null); diff --git a/src/test/java/org/matsim/run/TestParking.java b/src/test/java/org/matsim/run/TestParking.java index 567767b..8997cf2 100644 --- a/src/test/java/org/matsim/run/TestParking.java +++ b/src/test/java/org/matsim/run/TestParking.java @@ -7,14 +7,17 @@ import org.locationtech.jts.geom.prep.PreparedGeometry; import org.locationtech.jts.geom.prep.PreparedGeometryFactory; import org.matsim.analysis.personMoney.PersonMoneyEventsAnalysisModule; -import org.matsim.api.core.v01.*; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Identifiable; +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.network.Network; import org.matsim.api.core.v01.population.Person; import org.matsim.application.MATSimApplication; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.PlansCalcRouteConfigGroup; +import org.matsim.core.config.groups.RoutingConfigGroup; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Controler; import org.matsim.core.population.io.PopulationReader; @@ -26,9 +29,7 @@ import java.util.stream.Collectors; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; -import static org.matsim.core.config.groups.PlansCalcRouteConfigGroup.AccessEgressType.accessEgressModeToLinkPlusTimeConstant; public class TestParking { @@ -74,14 +75,14 @@ public Config prepareConfig(Config config) { preparedConfig.global().setNumberOfThreads(1); preparedConfig.qsim().setNumberOfThreads(1); preparedConfig.plans().setInputFile(null); - preparedConfig.controler().setLastIteration(0); - preparedConfig.controler().setRunId(RUN_ID); + preparedConfig.controller().setLastIteration(0); + preparedConfig.controller().setRunId(RUN_ID); // Disable PT preparedConfig.transit().setUseTransit(false); if (useParking== false) { - config.plansCalcRoute().setAccessEgressType(PlansCalcRouteConfigGroup.AccessEgressType.accessEgressModeToLink); + config.routing().setAccessEgressType(RoutingConfigGroup.AccessEgressType.accessEgressModeToLink); } return preparedConfig; From 136d8aa1b0b348e7d3f140d28f4e59b752df15ad Mon Sep 17 00:00:00 2001 From: rakow Date: Wed, 29 Nov 2023 16:29:19 +0100 Subject: [PATCH 12/28] update pom structure --- pom.xml | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index a1459a2..50d853e 100644 --- a/pom.xml +++ b/pom.xml @@ -168,16 +168,36 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M5 + 3.0.0-M9 - once + 1 + false - -Xmx6500m -Djava.awt.headless=true -Dmatsim.preferLocalDtds=true + @{argLine} -Xmx6500m -Djava.awt.headless=true -Dmatsim.preferLocalDtds=true + + + io.github.git-commit-id + git-commit-id-maven-plugin + 5.0.0 + + + get-the-git-infos + + revision + + validate + + + + false + + + org.apache.maven.plugins maven-shade-plugin @@ -190,6 +210,7 @@ ${project.basedir}/${project.build.finalName}.jar + @@ -198,6 +219,7 @@ org.matsim org.matsim ${project.version} + ${git.commit.id.describe-short} true From 2380807eab22b88747e31961a82ab5d6a6c2d9d0 Mon Sep 17 00:00:00 2001 From: rakow Date: Wed, 29 Nov 2023 17:37:33 +0100 Subject: [PATCH 13/28] update pom and calibrate script --- pom.xml | 2 +- src/main/java/org/matsim/prepare/CreateDemand.java | 3 ++- src/main/python/calibrate.py | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 50d853e..d3d405b 100644 --- a/pom.xml +++ b/pom.xml @@ -209,7 +209,7 @@ shade - ${project.basedir}/${project.build.finalName}.jar + ${project.basedir}/${project.build.finalName}-${git.commit.id.describe-short}.jar diff --git a/src/main/java/org/matsim/prepare/CreateDemand.java b/src/main/java/org/matsim/prepare/CreateDemand.java index 08f987f..e2b0081 100644 --- a/src/main/java/org/matsim/prepare/CreateDemand.java +++ b/src/main/java/org/matsim/prepare/CreateDemand.java @@ -27,7 +27,8 @@ public static void main(String[] args) { // If true is given as argument, this class will build the open population boolean openModel = args.length > 0 && args[0].equalsIgnoreCase("True"); - String outputPlans = outputFolder.resolve("metropole-ruhr-" + RunMetropoleRuhrScenario.VERSION + "-25pct.plans.xml.gz").toString(); + String name = openModel ? "open-plans" : "plans"; + String outputPlans = outputFolder.resolve("metropole-ruhr-" + RunMetropoleRuhrScenario.VERSION + "-25pct." + name + ".xml.gz").toString(); if (openModel) outputPlans = outputPlans.replace(".plans", ".open-plans"); diff --git a/src/main/python/calibrate.py b/src/main/python/calibrate.py index f440201..fc65979 100644 --- a/src/main/python/calibrate.py +++ b/src/main/python/calibrate.py @@ -36,10 +36,10 @@ # Initial ASCs initial = { - "bike": -2.3, + "bike": -0.15, "pt": 0, - "car": 0, - "ride": -4.12 + "car": 0.8, + "ride": -2.3 } # Modal split target @@ -68,7 +68,7 @@ def adjust_trips(df): return df -study, obj = calibration.create_mode_share_study("calib", "matsim-metropole-ruhr-1.0-SNAPSHOT.jar", +study, obj = calibration.create_mode_share_study("calib", "matsim-metropole-ruhr-1.4.1-136d8aa.jar", "../scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.0-10pct.config.xml", modes, target, initial_asc=initial, From 27b77f9182ccf064fd14eb3db06758bb565b011e Mon Sep 17 00:00:00 2001 From: rakow Date: Wed, 29 Nov 2023 17:40:37 +0100 Subject: [PATCH 14/28] update person filter --- src/main/python/calibrate.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/python/calibrate.py b/src/main/python/calibrate.py index fc65979..3653f05 100644 --- a/src/main/python/calibrate.py +++ b/src/main/python/calibrate.py @@ -55,6 +55,8 @@ def f(persons): + persons = gpd.GeoDataFrame(persons, geometry=gpd.points_from_xy(persons.home_x, persons.home_y)) + df = gpd.sjoin(persons.set_crs("EPSG:25832"), region, how="inner", op="intersects") return df From 2d5f87f1fed00af51f8adb53d9b9d4cdd3a4dbf9 Mon Sep 17 00:00:00 2001 From: rakow Date: Wed, 29 Nov 2023 17:46:21 +0100 Subject: [PATCH 15/28] update maven and fix test error --- .mvn/wrapper/MavenWrapperDownloader.java | 117 ------------ .mvn/wrapper/maven-wrapper.properties | 20 +- mvnw | 224 +++++++++++------------ mvnw.cmd | 57 ++++-- pom.xml | 2 +- 5 files changed, 170 insertions(+), 250 deletions(-) delete mode 100644 .mvn/wrapper/MavenWrapperDownloader.java diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index b901097..0000000 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2007-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import java.net.*; -import java.io.*; -import java.nio.channels.*; -import java.util.Properties; - -public class MavenWrapperDownloader { - - private static final String WRAPPER_VERSION = "0.5.6"; - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { - String username = System.getenv("MVNW_USERNAME"); - char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); - } - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 642d572..eacdc9e 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,18 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/mvnw b/mvnw index 41c0f0c..8d937f4 100755 --- a/mvnw +++ b/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven Start Up Batch script +# Apache Maven Wrapper startup batch script, version 3.2.0 # # Required ENV vars: # ------------------ @@ -27,7 +27,6 @@ # # Optional ENV vars # ----------------- -# M2_HOME - location of maven2's installed home dir # MAVEN_OPTS - parameters passed to the Java VM when running Maven # e.g. to debug Maven itself, use # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @@ -36,6 +35,10 @@ if [ -z "$MAVEN_SKIP_RC" ] ; then + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + if [ -f /etc/mavenrc ] ; then . /etc/mavenrc fi @@ -50,7 +53,7 @@ fi cygwin=false; darwin=false; mingw=false -case "`uname`" in +case "$(uname)" in CYGWIN*) cygwin=true ;; MINGW*) mingw=true;; Darwin*) darwin=true @@ -58,9 +61,9 @@ case "`uname`" in # See https://developer.apple.com/library/mac/qa/qa1170/_index.html if [ -z "$JAVA_HOME" ]; then if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" + JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME else - export JAVA_HOME="/Library/Java/Home" + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME fi fi ;; @@ -68,68 +71,38 @@ esac if [ -z "$JAVA_HOME" ] ; then if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` + JAVA_HOME=$(java-config --jre-home) fi fi -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - # For Cygwin, ensure paths are in UNIX format before anything is touched if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + JAVA_HOME=$(cygpath --unix "$JAVA_HOME") [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` + CLASSPATH=$(cygpath --path --unix "$CLASSPATH") fi # For Mingw, ensure paths are in UNIX format before anything is touched if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && + JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" fi if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + javaExecutable="$(which javac)" + if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + readLink=$(which readlink) + if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + javaHome="$(dirname "\"$javaExecutable\"")" + javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" else - javaExecutable="`readlink -f \"$javaExecutable\"`" + javaExecutable="$(readlink -f "\"$javaExecutable\"")" fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` + javaHome="$(dirname "\"$javaExecutable\"")" + javaHome=$(expr "$javaHome" : '\(.*\)/bin') JAVA_HOME="$javaHome" export JAVA_HOME fi @@ -145,7 +118,7 @@ if [ -z "$JAVACMD" ] ; then JAVACMD="$JAVA_HOME/bin/java" fi else - JAVACMD="`which java`" + JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" fi fi @@ -159,12 +132,9 @@ if [ -z "$JAVA_HOME" ] ; then echo "Warning: JAVA_HOME environment variable is not set." fi -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - # traverses directory structure from process work directory to filesystem root # first directory with .mvn subdirectory is considered project base directory find_maven_basedir() { - if [ -z "$1" ] then echo "Path not specified to find_maven_basedir" @@ -180,96 +150,99 @@ find_maven_basedir() { fi # workaround for JBEAP-8937 (on Solaris 10/Sparc) if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` + wdir=$(cd "$wdir/.." || exit 1; pwd) fi # end of workaround done - echo "${basedir}" + printf '%s' "$(cd "$basedir" || exit 1; pwd)" } # concatenates all lines of a file concat_lines() { if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" + # Remove \r in case we run on Windows within Git Bash + # and check out the repository with auto CRLF management + # enabled. Otherwise, we may read lines that are delimited with + # \r\n and produce $'-Xarg\r' rather than -Xarg due to word + # splitting rules. + tr -s '\r\n' ' ' < "$1" + fi +} + +log() { + if [ "$MVNW_VERBOSE" = true ]; then + printf '%s\n' "$1" fi } -BASE_DIR=`find_maven_basedir "$(pwd)"` +BASE_DIR=$(find_maven_basedir "$(dirname "$0")") if [ -z "$BASE_DIR" ]; then exit 1; fi +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +log "$MAVEN_PROJECTBASEDIR" + ########################################################################################## # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central # This allows using the maven wrapper in projects that prohibit checking in binary data. ########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi +wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" +if [ -r "$wrapperJarPath" ]; then + log "Found $wrapperJarPath" else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi + log "Couldn't find $wrapperJarPath, downloading it ..." + if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + while IFS="=" read -r key value; do + # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) + safeValue=$(echo "$value" | tr -d '\r') + case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" + log "Downloading from: $wrapperUrl" + if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") fi if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi + log "Found wget ... using wget" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" fi elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi + log "Found curl ... using curl" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" fi - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + log "Falling back to using Java to download" + javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" # For Cygwin, switch paths to Windows format before running javac if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` + javaSource=$(cygpath --path --windows "$javaSource") + javaClass=$(cygpath --path --windows "$javaClass") fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + log " - Compiling MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/javac" "$javaSource") fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + if [ -e "$javaClass" ]; then + log " - Running MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" fi fi fi @@ -278,33 +251,58 @@ fi # End of extension ########################################################################################## -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR +# If specified, validate the SHA-256 sum of the Maven wrapper jar file +wrapperSha256Sum="" +while IFS="=" read -r key value; do + case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; + esac +done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" +if [ -n "$wrapperSha256Sum" ]; then + wrapperSha256Result=false + if command -v sha256sum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + elif command -v shasum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." + echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." + exit 1 + fi + if [ $wrapperSha256Result = false ]; then + echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 + echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 + echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 + exit 1 + fi fi + MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" # For Cygwin, switch paths to Windows format before running java if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + CLASSPATH=$(cygpath --path --windows "$CLASSPATH") [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` + MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") fi # Provide a "standardized" way to retrieve the CLI args that will # work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" export MAVEN_CMD_LINE_ARGS WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain +# shellcheck disable=SC2086 # safe args exec "$JAVACMD" \ $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd index 8611571..c4586b5 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -18,13 +18,12 @@ @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script +@REM Apache Maven Wrapper startup batch script, version 3.2.0 @REM @REM Required ENV vars: @REM JAVA_HOME - location of a JDK home dir @REM @REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven @@ -46,8 +45,8 @@ if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") @REM Execute a user defined script before this one if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre @REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* :skipRcPre @setlocal @@ -120,10 +119,10 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B ) @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central @@ -134,11 +133,11 @@ if exist %WRAPPER_JAR% ( ) ) else ( if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" ) if "%MVNW_VERBOSE%" == "true" ( echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% + echo Downloading from: %WRAPPER_URL% ) powershell -Command "&{"^ @@ -146,7 +145,7 @@ if exist %WRAPPER_JAR% ( "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ "}" if "%MVNW_VERBOSE%" == "true" ( echo Finished downloading %WRAPPER_JAR% @@ -154,11 +153,35 @@ if exist %WRAPPER_JAR% ( ) @REM End of extension +@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file +SET WRAPPER_SHA_256_SUM="" +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B +) +IF NOT %WRAPPER_SHA_256_SUM%=="" ( + powershell -Command "&{"^ + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ + "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ + " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ + " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ + " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ + " exit 1;"^ + "}"^ + "}" + if ERRORLEVEL 1 goto error +) + @REM Provide a "standardized" way to retrieve the CLI args that will @REM work with both Windows and non-Windows executions. set MAVEN_CMD_LINE_ARGS=%* -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* if ERRORLEVEL 1 goto error goto end @@ -168,15 +191,15 @@ set ERROR_CODE=1 :end @endlocal & set ERROR_CODE=%ERROR_CODE% -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost @REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" :skipRcPost @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause +if "%MAVEN_BATCH_PAUSE%"=="on" pause -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% -exit /B %ERROR_CODE% +cmd /C exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml index d3d405b..ef58369 100644 --- a/pom.xml +++ b/pom.xml @@ -173,7 +173,7 @@ 1 false - @{argLine} -Xmx6500m -Djava.awt.headless=true -Dmatsim.preferLocalDtds=true + -Xmx6500m -Djava.awt.headless=true -Dmatsim.preferLocalDtds=true From 8684f93903d9a5d69c2bfedfb9fcdd1c2d595ec3 Mon Sep 17 00:00:00 2001 From: GregorRyb Date: Fri, 22 Dec 2023 20:56:34 +0100 Subject: [PATCH 16/28] quick analysis to extract home locations --- .../java/org/matsim/analysis/Person2Home.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/main/java/org/matsim/analysis/Person2Home.java diff --git a/src/main/java/org/matsim/analysis/Person2Home.java b/src/main/java/org/matsim/analysis/Person2Home.java new file mode 100644 index 0000000..559b235 --- /dev/null +++ b/src/main/java/org/matsim/analysis/Person2Home.java @@ -0,0 +1,61 @@ +package org.matsim.analysis; + + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; +import org.locationtech.jts.geom.Geometry; +import org.matsim.api.core.v01.Coord; +import org.matsim.api.core.v01.population.Activity; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.api.core.v01.population.Population; +import org.matsim.core.population.PopulationUtils; +import org.matsim.core.utils.geometry.geotools.MGC; +import org.matsim.core.utils.gis.ShapeFileReader; +import org.opengis.feature.simple.SimpleFeature; +import picocli.CommandLine; + +import java.io.FileWriter; +import java.io.IOException; +import java.util.Collection; + +@CommandLine.Command( + name = "analyze-population", + description = "Extract the home location of the persons in the population file and write it into a csv" +) + + +public class Person2Home { + + public static void main(String[] args) throws IOException { + String shapeFileZones = "../../shared-svn/projects/rvr-metropole-ruhr/data/shapeFiles/dvg2krs_ruhrgebiet-rvr/dvg2krs_ruhrgebiet-rvr.shp"; + Collection features = ShapeFileReader.getAllFeatures(shapeFileZones); + analyzeHomeLocation(PopulationUtils.readPopulation("../../respos/shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.plans.xml.gz"), features); + } + + + private static void analyzeHomeLocation(Population population, Collection analyzedArea) throws IOException { + CSVPrinter csvWriter = new CSVPrinter(new FileWriter("persons-home-locations.csv"), CSVFormat.TDF); + csvWriter.printRecord("person", "home_x", "home_y", "home_location"); + for (SimpleFeature feature : analyzedArea) { + Geometry defaultGeometry = (Geometry) feature.getDefaultGeometry(); + + for (Person p : population.getPersons().values()) { + for (PlanElement planElement : p.getSelectedPlan().getPlanElements()) { + if (planElement instanceof Activity) { + String actType = ((Activity) planElement).getType(); + if (actType.startsWith("home")) { + Coord homeCoord = ((Activity) planElement).getCoord(); + if (MGC.coord2Point(homeCoord).within(defaultGeometry)) { + csvWriter.printRecord(p.getId().toString(), + Double.toString(homeCoord.getX()), Double.toString(homeCoord.getY()), feature.getAttribute("GN").toString()); + } + } + } + } + } + } + } + +} + From d33bacf3e640195f994a2dc8ec78948494cd5b2a Mon Sep 17 00:00:00 2001 From: rakow Date: Tue, 2 Jan 2024 10:24:51 +0100 Subject: [PATCH 17/28] add todo for already implemented functionality --- src/main/java/org/matsim/analysis/Person2Home.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/matsim/analysis/Person2Home.java b/src/main/java/org/matsim/analysis/Person2Home.java index 559b235..4003d6e 100644 --- a/src/main/java/org/matsim/analysis/Person2Home.java +++ b/src/main/java/org/matsim/analysis/Person2Home.java @@ -23,8 +23,6 @@ name = "analyze-population", description = "Extract the home location of the persons in the population file and write it into a csv" ) - - public class Person2Home { public static void main(String[] args) throws IOException { @@ -37,6 +35,10 @@ public static void main(String[] args) throws IOException { private static void analyzeHomeLocation(Population population, Collection analyzedArea) throws IOException { CSVPrinter csvWriter = new CSVPrinter(new FileWriter("persons-home-locations.csv"), CSVFormat.TDF); csvWriter.printRecord("person", "home_x", "home_y", "home_location"); + + // TODO: a similar functionality is already implemented in ExtractHomeCoordinates + // this class will become obsolete, but a newer MATSim version is needed + for (SimpleFeature feature : analyzedArea) { Geometry defaultGeometry = (Geometry) feature.getDefaultGeometry(); From 7ca533c1ef80e8b6f701b166e7189111672b12f4 Mon Sep 17 00:00:00 2001 From: GregorRyb Date: Thu, 22 Feb 2024 18:27:51 +0100 Subject: [PATCH 18/28] add option to remove unselected plans --- src/main/java/org/matsim/prepare/DeleteRoutesFromPlans.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/matsim/prepare/DeleteRoutesFromPlans.java b/src/main/java/org/matsim/prepare/DeleteRoutesFromPlans.java index 73018ee..810cba5 100644 --- a/src/main/java/org/matsim/prepare/DeleteRoutesFromPlans.java +++ b/src/main/java/org/matsim/prepare/DeleteRoutesFromPlans.java @@ -11,6 +11,7 @@ public static void main(String[] args) throws Exception { "--plans=../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.plans.xml.gz", "--output=../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.plans-withoutRoutes.xml.gz", "--remove-routes=true", + "--remove-unselected-plans=true", "--remove-activity-location=true" }; new CleanPopulation().execute(argsForRemoveRoutesFromPlans); From e864a4e4488d21f3924bc9db094316908d2da2c2 Mon Sep 17 00:00:00 2001 From: rakow Date: Mon, 18 Mar 2024 16:54:56 +0100 Subject: [PATCH 19/28] update project setup --- .editorconfig | 21 +++ .github/workflows/build.yaml | 90 ++++++++++-- .github/workflows/publish.yaml | 6 +- checkstyle.xml | 250 +++++++++++++++++++++++++++++++++ pom.xml | 120 ++++++++++++++-- 5 files changed, 458 insertions(+), 29 deletions(-) create mode 100644 .editorconfig create mode 100644 checkstyle.xml diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1e55599 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ + +root = true + +[*] +charset = utf-8 +end_of_line = lf + + +[*.java] +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true +max_line_length = 150 + + +[*.{xml, xsd, dtd}] +max_line_length = off +indent_style = tab +trim_trailing_whitespace = true +insert_final_newline = true +indent_size = 4 diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 60aa666..fec225e 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,11 +1,49 @@ name: build -on: [ push, pull_request ] +on: push jobs: - build: + + checkstyle: + #run if push or pull_requests from fork + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + name: Checkstyle + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 + with: + java-version: 17 + architecture: x64 + distribution: adopt + cache: maven + + - name: Checkstyle + run: mvn --batch-mode --update-snapshots checkstyle:checkstyle + + enforce: #run if push or pull_requests from fork if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + name: Maven Dependencies + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 + with: + java-version: 17 + architecture: x64 + distribution: adopt + cache: maven + + - name: Package + run: mvn --batch-mode --update-snapshots enforcer:enforce + + test: + #run if push or pull_requests from fork + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + name: Tests runs-on: ubuntu-latest timeout-minutes: 45 @@ -13,26 +51,56 @@ jobs: strategy: fail-fast: false matrix: - java: [ 17 ] + java: [17] steps: - uses: actions/checkout@v3 - - name: Set up JDK - uses: actions/setup-java@v3 + with: + fetch-depth: 0 + - uses: actions/setup-java@v3 with: java-version: ${{ matrix.java }} architecture: x64 - distribution: zulu + distribution: adopt + cache: maven - - name: Cache Maven packages + - name: Cache SonarCloud packages uses: actions/cache@v3 with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + + - name: Build and analyze + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: mvn -B verify -Dcheckstyle.skip org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=matsim-scenarios_matsim-metropole-ruhr --update-snapshots -Dmatsim.preferLocalDtds=true -Dmaven.javadoc.skip -e + + + package: + #run if push or pull_requests from fork + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + needs: [checkstyle, enforce, test] + name: Package + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 + with: + java-version: 17 + architecture: x64 + distribution: adopt + cache: maven - name: Package - run: mvn -B package --file pom.xml -Dmatsim.preferLocalDtds=true -Dmaven.javadoc.skip -e + run: mvn --batch-mode --update-snapshots package -DskipTests -Dmatsim.preferLocalDtds=true -Dmaven.javadoc.skip -e + - run: mkdir staging && cp *.jar staging + - uses: actions/upload-artifact@v3 + with: + name: Package + path: staging env: MAVEN_OPTS: -Xmx512m \ No newline at end of file diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index bee26af..89df06a 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -1,7 +1,7 @@ -name: Publish package to GitHub Packages +name: Publish package on: release: - types: [ created ] + types: [created] jobs: publish: runs-on: ubuntu-latest @@ -11,7 +11,7 @@ jobs: with: java-version: 17 architecture: x64 - distribution: zulu + distribution: adopt - name: Publish package run: mvn --batch-mode deploy diff --git a/checkstyle.xml b/checkstyle.xml new file mode 100644 index 0000000..c08a39e --- /dev/null +++ b/checkstyle.xml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index ef58369..a06d51c 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,13 @@ + + org.matsim + matsim-all + 16.0-PR2895 + + + 4.0.0 com.github.matsim-scenarios matsim-metropole-ruhr @@ -10,18 +17,9 @@ MATSim Metropole Ruhr project - - - - - + + ${project.parent.version} - - - - - 16.0-PR2895 - UTF-8 UTF-8 17 @@ -46,8 +44,8 @@ ojo-snapshots https://oss.jfrog.org/libs-snapshot - - + + topobyte @@ -57,7 +55,7 @@ slimjars https://mvn.slimjars.com - + jitpack.io https://jitpack.io @@ -152,7 +150,7 @@ org.apache.poi poi-ooxml - 4.1.1 + 5.2.4 @@ -165,6 +163,31 @@ + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + 17 + false + false + UTF-8 + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + org.apache.maven.plugins maven-surefire-plugin @@ -179,6 +202,26 @@ + + org.jacoco + jacoco-maven-plugin + 0.8.8 + + + + prepare-agent + + + + report + test + + report + + + + + io.github.git-commit-id @@ -241,6 +284,53 @@ + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.2.0 + + + com.puppycrawl.tools + checkstyle + 10.6.0 + + + + checkstyle.xml + true + true + true + false + + + + checkstyle + package + + check + + + + + + + + + org.jacoco + jacoco-maven-plugin + + + + + report + + + + + + + From 990c129dd52ce1cdb55b49c734fc570184d3dac2 Mon Sep 17 00:00:00 2001 From: rakow Date: Mon, 18 Mar 2024 16:56:37 +0100 Subject: [PATCH 20/28] disable failing checkstyle for now --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a06d51c..120c758 100644 --- a/pom.xml +++ b/pom.xml @@ -299,8 +299,8 @@ checkstyle.xml true - true - true + false + false false From 2847404a94a407d996d2faa6bf9e963e4eb39bf5 Mon Sep 17 00:00:00 2001 From: rakow Date: Mon, 18 Mar 2024 17:07:34 +0100 Subject: [PATCH 21/28] add 3pct open config and run class --- .../metropole-ruhr-v1.4-3pct.open-config.xml | 257 ++++++++++++++++++ .../run/KNRunMetropoleRuhrScenario.java | 19 -- .../run/RunOpenMetropoleRuhrScenario.java | 13 + 3 files changed, 270 insertions(+), 19 deletions(-) create mode 100644 scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.open-config.xml delete mode 100644 src/main/java/org/matsim/run/KNRunMetropoleRuhrScenario.java create mode 100644 src/main/java/org/matsim/run/RunOpenMetropoleRuhrScenario.java diff --git a/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.open-config.xml b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.open-config.xml new file mode 100644 index 0000000..6ffd96c --- /dev/null +++ b/scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.open-config.xml @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/org/matsim/run/KNRunMetropoleRuhrScenario.java b/src/main/java/org/matsim/run/KNRunMetropoleRuhrScenario.java deleted file mode 100644 index 3b7ff4b..0000000 --- a/src/main/java/org/matsim/run/KNRunMetropoleRuhrScenario.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.matsim.run; - -class KNRunMetropoleRuhrScenario{ - - public static void main( String[] args ){ - args = new String[]{ - "--config:controler.lastIteration", "0" -// , "--download-input" - , "--config:plans.inputPlansFile=../../../../../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.plans.xml.gz" -// ,"--config:network.inputNetworkFile=../../../../../../public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4.network_resolutionHigh-with-pt.xml.gz" - , "--1pct" - , "run" - }; - - RunMetropoleRuhrScenario.main( args ); - - } - -} diff --git a/src/main/java/org/matsim/run/RunOpenMetropoleRuhrScenario.java b/src/main/java/org/matsim/run/RunOpenMetropoleRuhrScenario.java new file mode 100644 index 0000000..9851d89 --- /dev/null +++ b/src/main/java/org/matsim/run/RunOpenMetropoleRuhrScenario.java @@ -0,0 +1,13 @@ +package org.matsim.run; + +class RunOpenMetropoleRuhrScenario { + + public static void main(String[] args) { + args = new String[]{ + "--config", "scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.open-config.xml" + }; + + RunMetropoleRuhrScenario.main(args); + } + +} From e07ee6bbb7018a02d0901c42430adc8250872aec Mon Sep 17 00:00:00 2001 From: rakow Date: Mon, 18 Mar 2024 17:11:33 +0100 Subject: [PATCH 22/28] set sonar config --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 120c758..d06cf41 100644 --- a/pom.xml +++ b/pom.xml @@ -22,8 +22,8 @@ UTF-8 UTF-8 - 17 - 17 + matsim-scenarios + https://sonarcloud.io From 85ba4f94c6523b057a66ea9706b20fd49d9a7b1f Mon Sep 17 00:00:00 2001 From: rakow Date: Mon, 18 Mar 2024 17:20:03 +0100 Subject: [PATCH 23/28] fix small code issues --- src/main/java/org/matsim/analysis/AttributeAnalysis.java | 4 +--- .../java/org/matsim/run/RunOpenMetropoleRuhrScenario.java | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/matsim/analysis/AttributeAnalysis.java b/src/main/java/org/matsim/analysis/AttributeAnalysis.java index b2d6ffd..323595a 100644 --- a/src/main/java/org/matsim/analysis/AttributeAnalysis.java +++ b/src/main/java/org/matsim/analysis/AttributeAnalysis.java @@ -23,15 +23,13 @@ public class AttributeAnalysis { - public static void main (String args []) throws IOException { + public static void main (String[] args) throws IOException { String openPopulationPath = "../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20230918_OpenData_Ruhr_300m/populaton.xml.gz"; String oldPopulationPath = "../../shared-svn/projects/rvr-metropole-ruhr/matsim-input-files/20210520_regionalverband_ruhr/population.xml.gz"; - String processedPopulationPath = "../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.plans.xml.gz"; Population closedPopulation = PopulationUtils.readPopulation(oldPopulationPath); Population openPopulation = PopulationUtils.readPopulation(openPopulationPath); - //PopulationUtils.readPopulation(processedPopulationPath); List differenceAttributes = new ArrayList<>(); List differenceActivities = new ArrayList<>(); diff --git a/src/main/java/org/matsim/run/RunOpenMetropoleRuhrScenario.java b/src/main/java/org/matsim/run/RunOpenMetropoleRuhrScenario.java index 9851d89..f68585b 100644 --- a/src/main/java/org/matsim/run/RunOpenMetropoleRuhrScenario.java +++ b/src/main/java/org/matsim/run/RunOpenMetropoleRuhrScenario.java @@ -3,11 +3,9 @@ class RunOpenMetropoleRuhrScenario { public static void main(String[] args) { - args = new String[]{ + RunMetropoleRuhrScenario.main(new String[]{ "--config", "scenarios/metropole-ruhr-v1.0/input/metropole-ruhr-v1.4-3pct.open-config.xml" - }; - - RunMetropoleRuhrScenario.main(args); + }); } } From 2ad1007f778ab0df88d72531244157437bc67400 Mon Sep 17 00:00:00 2001 From: rakow Date: Mon, 18 Mar 2024 17:28:41 +0100 Subject: [PATCH 24/28] fix few more issues --- .../matsim/analysis/AttributeAnalysis.java | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/main/java/org/matsim/analysis/AttributeAnalysis.java b/src/main/java/org/matsim/analysis/AttributeAnalysis.java index 323595a..c52a970 100644 --- a/src/main/java/org/matsim/analysis/AttributeAnalysis.java +++ b/src/main/java/org/matsim/analysis/AttributeAnalysis.java @@ -2,22 +2,11 @@ import com.google.common.collect.MapDifference; import com.google.common.collect.Maps; -import org.apache.commons.collections.CollectionUtils; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Person; -import org.matsim.api.core.v01.population.PlanElement; import org.matsim.api.core.v01.population.Population; import org.matsim.core.population.PopulationUtils; -import org.matsim.core.router.TripStructureUtils; -import org.matsim.utils.objectattributes.attributable.Attributes; -import java.io.BufferedWriter; -import java.io.FileWriter; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; import java.util.Map; public class AttributeAnalysis { @@ -31,9 +20,6 @@ public static void main (String[] args) throws IOException { Population closedPopulation = PopulationUtils.readPopulation(oldPopulationPath); Population openPopulation = PopulationUtils.readPopulation(openPopulationPath); - List differenceAttributes = new ArrayList<>(); - List differenceActivities = new ArrayList<>(); - for (Person personClosed: closedPopulation.getPersons().values()) { for(Person personOpen: openPopulation.getPersons().values()) { if (personClosed.getId().equals(personOpen.getId())) { @@ -41,10 +27,7 @@ public static void main (String[] args) throws IOException { Map personClosedAttributes = personClosed.getAttributes().getAsMap(); Map personOpenAttributes = personOpen.getAttributes().getAsMap(); MapDifference diff = Maps.difference(personClosedAttributes, personOpenAttributes); - System.out.println(diff.toString()); - if (diff.equals(false)) { - System.out.println("This is not supposed to happen"); - } + System.out.println(diff); /* //second activities List openActivities = PopulationUtils.getActivities(personClosed.getSelectedPlan(), TripStructureUtils.StageActivityHandling.ExcludeStageActivities); From c71bd9f3e26fc6f3092c85360b35f808cd8399ad Mon Sep 17 00:00:00 2001 From: rakow Date: Mon, 18 Mar 2024 17:41:55 +0100 Subject: [PATCH 25/28] code cleanup --- .../matsim/analysis/PopulationComparison.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/matsim/analysis/PopulationComparison.java b/src/main/java/org/matsim/analysis/PopulationComparison.java index a33cba5..4791259 100644 --- a/src/main/java/org/matsim/analysis/PopulationComparison.java +++ b/src/main/java/org/matsim/analysis/PopulationComparison.java @@ -1,20 +1,14 @@ package org.matsim.analysis; -import org.matsim.application.MATSimAppCommand; -import org.matsim.application.MATSimApplication; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.matsim.application.analysis.CheckPopulation; import org.matsim.application.analysis.population.PopulationAttributeAnalysis; import org.matsim.application.analysis.population.SubTourAnalysis; -import org.matsim.application.options.CrsOptions; -import org.matsim.application.options.ShpOptions; -import picocli.CommandLine; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; public class PopulationComparison { - private static final Logger log = LogManager.getLogger(PopulationComparison.class); public static void main(String [] args) { @@ -33,7 +27,7 @@ public static void main(String [] args) { "--shp-crs", "EPSG:25832" }; - //checkPopulation.execute(argsNewPopulation); + checkPopulation.execute(argsNewPopulation); log.info("---------------"); log.info("start check population analysis of old population"); log.info("---------------"); @@ -44,7 +38,7 @@ public static void main(String [] args) { "--input-crs", "EPSG:25832", "--shp-crs", "EPSG:25832" }; - //checkPopulation.execute(argsOldPopulation); + checkPopulation.execute(argsOldPopulation); log.info("---------------"); log.info("start check population analysis of processed population"); @@ -58,9 +52,9 @@ public static void main(String [] args) { }; checkPopulation.execute(argsProcessedPopulation); - //new PopulationAttributeAnalysis().execute("--population", openPopulation); + new PopulationAttributeAnalysis().execute("--population", openPopulation); - //new SubTourAnalysis().execute("--population", openPopulation); + new SubTourAnalysis().execute("--population", openPopulation); } From 76cd6cda10895eff403b6ee7de0e2252d8aadcf0 Mon Sep 17 00:00:00 2001 From: rakow Date: Mon, 18 Mar 2024 18:20:06 +0100 Subject: [PATCH 26/28] use sonar cloud automatic setup --- .github/workflows/build.yaml | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index fec225e..acf4301 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -55,8 +55,6 @@ jobs: steps: - uses: actions/checkout@v3 - with: - fetch-depth: 0 - uses: actions/setup-java@v3 with: java-version: ${{ matrix.java }} @@ -64,19 +62,12 @@ jobs: distribution: adopt cache: maven - - name: Cache SonarCloud packages - uses: actions/cache@v3 + - name: Test + run: mvn --batch-mode --update-snapshots test -Dmatsim.preferLocalDtds=true -Dmaven.javadoc.skip -e + - uses: actions/upload-artifact@v3 with: - path: ~/.sonar/cache - key: ${{ runner.os }}-sonar - restore-keys: ${{ runner.os }}-sonar - - - name: Build and analyze - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: mvn -B verify -Dcheckstyle.skip org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=matsim-scenarios_matsim-metropole-ruhr --update-snapshots -Dmatsim.preferLocalDtds=true -Dmaven.javadoc.skip -e - + name: test-coverage + path: target/site/jacoco/ package: #run if push or pull_requests from fork From 0260984df3d4a5e3573dde8c52d4195262b3cd46 Mon Sep 17 00:00:00 2001 From: rakow Date: Mon, 13 May 2024 10:43:31 +0200 Subject: [PATCH 27/28] set freespeed factor --- src/main/java/org/matsim/prepare/CreateDemand.java | 3 +++ src/main/java/org/matsim/prepare/CreateSupply.java | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/org/matsim/prepare/CreateDemand.java b/src/main/java/org/matsim/prepare/CreateDemand.java index e2b0081..523ecbf 100644 --- a/src/main/java/org/matsim/prepare/CreateDemand.java +++ b/src/main/java/org/matsim/prepare/CreateDemand.java @@ -15,6 +15,9 @@ import java.nio.file.Paths; import java.util.List; +/** + * Create population (input plans) for the scenario. + */ public class CreateDemand { private static final Path rootFolder = Paths.get("../../shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0"); diff --git a/src/main/java/org/matsim/prepare/CreateSupply.java b/src/main/java/org/matsim/prepare/CreateSupply.java index 1a19000..750ee08 100644 --- a/src/main/java/org/matsim/prepare/CreateSupply.java +++ b/src/main/java/org/matsim/prepare/CreateSupply.java @@ -43,6 +43,9 @@ import static org.matsim.prepare.RuhrUtils.*; +/** + * Create supply (network, pt, counts) for the scenario. + */ public class CreateSupply { public enum NetworkResolution {Low, Medium, High} @@ -129,7 +132,11 @@ private void run(Path rootDirectory) { // ----------------------------------------- Create Network ---------------------------------------------------- + // ruhr area is rather large, with a mixture of urban and more rural areas + // based on the paper "Road network free flow speed estimation using microscopic simulation and point-to-point travel times" + // the free speed factor was set to a mean of urban, metropolitan and rural areas var networkBuilder = new OsmBicycleReader.Builder() + .setFreeSpeedFactor(0.75) .setCoordinateTransformation(transformation) .setIncludeLinkAtCoordWithHierarchy((coord, level) -> isIncludeLink(coord, level, ruhrGeometries, nrwGeometries)) .setPreserveNodeWithId(nodeIdsToKeep::contains) From 2908979806ec482f98e2fe6af8b06163955ea513 Mon Sep 17 00:00:00 2001 From: rakow Date: Mon, 13 May 2024 15:53:33 +0200 Subject: [PATCH 28/28] update version and use java 21, create bast counts data --- .github/workflows/build.yaml | 8 ++--- .github/workflows/publish.yaml | 2 +- pom.xml | 6 ++-- .../java/org/matsim/prepare/CreateSupply.java | 32 ++++++++++++++----- .../prepare/counts/CombinedCountsWriter.java | 3 +- .../matsim/run/RunMetropoleRuhrScenario.java | 2 +- 6 files changed, 35 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index acf4301..3f6005d 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-java@v3 with: - java-version: 17 + java-version: 21 architecture: x64 distribution: adopt cache: maven @@ -32,7 +32,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-java@v3 with: - java-version: 17 + java-version: 21 architecture: x64 distribution: adopt cache: maven @@ -51,7 +51,7 @@ jobs: strategy: fail-fast: false matrix: - java: [17] + java: [21] steps: - uses: actions/checkout@v3 @@ -80,7 +80,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-java@v3 with: - java-version: 17 + java-version: 21 architecture: x64 distribution: adopt cache: maven diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 89df06a..a7c6fe7 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -9,7 +9,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-java@v3 with: - java-version: 17 + java-version: 21 architecture: x64 distribution: adopt diff --git a/pom.xml b/pom.xml index d06cf41..35dda27 100644 --- a/pom.xml +++ b/pom.xml @@ -4,14 +4,14 @@ org.matsim matsim-all - 16.0-PR2895 + 2025.0-PR3257 4.0.0 com.github.matsim-scenarios matsim-metropole-ruhr - 1.4.1 + 2.0 MATSim Metropole Ruhr project MATSim Metropole Ruhr project @@ -168,7 +168,7 @@ maven-compiler-plugin 3.11.0 - 17 + 21 false false UTF-8 diff --git a/src/main/java/org/matsim/prepare/CreateSupply.java b/src/main/java/org/matsim/prepare/CreateSupply.java index 750ee08..2d60b43 100644 --- a/src/main/java/org/matsim/prepare/CreateSupply.java +++ b/src/main/java/org/matsim/prepare/CreateSupply.java @@ -12,6 +12,7 @@ import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.network.NetworkWriter; import org.matsim.api.core.v01.network.Node; +import org.matsim.application.prepare.counts.CreateCountsFromBAStData; import org.matsim.application.prepare.pt.CreateTransitScheduleFromGtfs; import org.matsim.contrib.bicycle.BicycleUtils; import org.matsim.contrib.osm.networkReader.LinkProperties; @@ -76,9 +77,11 @@ public enum NetworkResolution {Low, Medium, High} // for now, we will focus on the 'Bestandsnetz'. Once, we are done with calibration, we will also generate the network for the 'Zielnetz' by replacing the previous line with the following. // private static final Path inputShapeNetwork3 = Paths.get("shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/original-data/2021-08-19_radwegeverbindungen_RRWN_Bestandsnetz_Zielnetz/2021-08-19_RRWN_Bestandsnetz_Zielnetz.shp"); - private static final Path outputDirPublic = Paths.get("public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v1.0/input/"); + private static final Path outputDirPublic = Paths.get("public-svn/matsim/scenarios/countries/de/metropole-ruhr/metropole-ruhr-v2.0/input/"); - private static final Path outputDirCounts = Paths.get("shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v1.0/input/"); + private static final Path outputDirCounts = Paths.get("shared-svn/projects/matsim-metropole-ruhr/metropole-ruhr-v2.0/input/"); + + private static final Path bastCountsRoot = Paths.get("shared-svn/projects/rvr-metropole-ruhr/data/BASt"); private static final Path longTermCountsRoot = Paths.get("shared-svn/projects/matsim-ruhrgebiet/original_data/counts/long_term_counts"); private static final Path longTermCountsIdMapping = Paths.get("shared-svn/projects/matsim-ruhrgebiet/original_data/counts/mapmatching/countId-to-nodeId-long-term-counts.csv"); private static final Path shortTermCountsRoot = Paths.get("shared-svn/projects/matsim-ruhrgebiet/original_data/counts/short_term_counts"); @@ -166,15 +169,15 @@ private void run(Path rootDirectory) { // ----------------------------- Add bicycles and write network ------------------------------------------------ Network network1 = new ShpToNetwork().run(rootDirectory.resolve(inputShapeNetwork1)); - new NetworkWriter(network1).write(outputDir.resolve("metropole-ruhr-v1.4.network-onlyBikeNetwork1.xml.gz").toString()); + new NetworkWriter(network1).write(outputDir.resolve("metropole-ruhr-v2.0.network-onlyBikeNetwork1.xml.gz").toString()); new BikeNetworkMerger(network).mergeBikeHighways(network1); Network network2 = new ShpToNetwork().run(rootDirectory.resolve(inputShapeNetwork2)); - new NetworkWriter(network2).write(outputDir.resolve("metropole-ruhr-v1.4.network-onlyBikeNetwork2.xml.gz").toString()); + new NetworkWriter(network2).write(outputDir.resolve("metropole-ruhr-v2.0.network-onlyBikeNetwork2.xml.gz").toString()); new BikeNetworkMerger(network).mergeBikeHighways(network2); Network network3 = new ShpToNetwork().run(rootDirectory.resolve(inputShapeNetwork3)); - new NetworkWriter(network3).write(outputDir.resolve("metropole-ruhr-v1.4.network-onlyBikeNetwork3.xml.gz").toString()); + new NetworkWriter(network3).write(outputDir.resolve("metropole-ruhr-v2.0.network-onlyBikeNetwork3.xml.gz").toString()); new BikeNetworkMerger(network).mergeBikeHighways(network3); var cleaner = new MultimodalNetworkCleaner(network); @@ -273,7 +276,7 @@ private void run(Path rootDirectory) { } } - String networkOut = outputDir.resolve("metropole-ruhr-v1.4.network_resolution" + networkResolution + ".xml.gz").toString(); + String networkOut = outputDir.resolve("metropole-ruhr-v2.0.network_resolution" + networkResolution + ".xml.gz").toString(); new NetworkWriter(network).write(networkOut); // --------------------------------------- Create Pt ----------------------------------------------------------- @@ -285,7 +288,7 @@ private void run(Path rootDirectory) { "--target-crs", "EPSG:25832", "--network", networkOut, "--output", outputDir.toString(), - "--name", "metropole-ruhr-v1.4" + "--name", "metropole-ruhr-v2.0" ); // --------------------------------------- Create Counts ------------------------------------------------------- @@ -310,7 +313,20 @@ private void run(Path rootDirectory) { .build() .run(); - CombinedCountsWriter.writeCounts(outputDirForCounts.resolve("metropole-ruhr-v1.4.counts.xml.gz"), + + new CreateCountsFromBAStData().execute( + "--network", networkOut, + "--year", "2022", + "--counts-mapping", rootDirectory.resolve(bastCountsRoot).resolve("bast-mapping.csv").toString(), + "--motorway-data", rootDirectory.resolve(bastCountsRoot).resolve("2022_A_S.zip").toString(), + "--primary-data", rootDirectory.resolve(bastCountsRoot).resolve("2022_B_S.zip").toString(), + "--station-data", rootDirectory.resolve(bastCountsRoot).resolve("Jawe2022.csv").toString(), + "--output", rootDirectory.resolve(outputDirPublic).resolve("metropole-ruhr-v2.0.counts.xml.gz").toString() + ); + + + // Based on 2015 count data, won't be used in the new model + CombinedCountsWriter.writeCounts(outputDirForCounts.resolve("metropole-ruhr-v2.0.counts-old.xml.gz"), longTermCounts.get(RawDataVehicleTypes.Pkw.toString()), shortTermCounts.get(RawDataVehicleTypes.Pkw.toString())); } diff --git a/src/main/java/org/matsim/prepare/counts/CombinedCountsWriter.java b/src/main/java/org/matsim/prepare/counts/CombinedCountsWriter.java index 85fb04d..84ebe45 100644 --- a/src/main/java/org/matsim/prepare/counts/CombinedCountsWriter.java +++ b/src/main/java/org/matsim/prepare/counts/CombinedCountsWriter.java @@ -4,11 +4,12 @@ import java.util.ArrayList; import java.util.List; +import org.matsim.api.core.v01.Identifiable; import org.matsim.api.core.v01.network.Link; import org.matsim.counts.Counts; import org.matsim.counts.CountsWriter; -public class CombinedCountsWriter { +public class CombinedCountsWriter> { private List> countsList = new ArrayList<>(); diff --git a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java index e11ebaf..bcbe593 100644 --- a/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java +++ b/src/main/java/org/matsim/run/RunMetropoleRuhrScenario.java @@ -206,7 +206,7 @@ protected Config prepareConfig(Config config) { config.qsim().setFlowCapFactor(sample.getSample()); config.qsim().setStorageCapFactor(sample.getSample()); - simWrapperConfigGroup.defaultParams().sampleSize = sample.getSample(); + simWrapperConfigGroup.sampleSize = sample.getSample(); } // snz activity types that are always the same, Differentiated by typical duration