diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 1150725..005f03a 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/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000..cb28b0e
Binary files /dev/null and b/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..eacdc9e
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,18 @@
+# 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/Makefile b/Makefile
index 25b9b64..d1adee5 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,13 @@
N := lausitz
-V := v1.0
+V := v1.1
CRS := EPSG:25832
JAR := matsim-$(N)-*.jar
osmosis := osmosis/bin/osmosis
germany := ../shared-svn/projects/matsim-germany
shared := ../shared-svn/projects/DiTriMo
-lausitz := ../public-svn/matsim/scenarios/countries/de/lausitz/lausitz-$V
+lausitz := ../public-svn/matsim/scenarios/countries/de/lausitz/input/$V
MEMORY ?= 20G
SUMO_HOME ?= $(abspath ../../sumo-1.18.0/)
@@ -18,33 +18,27 @@ sc := java -Xmx$(MEMORY) -XX:+UseParallelGC -jar $(JAR)
.PHONY: prepare
-# Bast count data
-input/2019_A_S.zip:
- curl https://www.bast.de/videos/2019_A_S.zip -o $@
-
-input/2019_B_S.zip:
- curl https://www.bast.de/videos/2019_B_S.zip -o $@
-
-input/Jawe2019.csv:
- curl "https://www.bast.de/DE/Verkehrstechnik/Fachthemen/v2-verkehrszaehlung/Daten/2019_1/Jawe2019.csv?view=renderTcDataExportCSV&cms_strTyp=A" -o $@
-
input/network.osm: $(NETWORK)
+# retrieve detailed network (see param highway) from OSM
$(osmosis) --rb file=$<\
--tf accept-ways bicycle=yes highway=motorway,motorway_link,trunk,trunk_link,primary,primary_link,secondary_link,secondary,tertiary,motorway_junction,residential,unclassified,living_street\
--bounding-polygon file="$(shared)/data/cottbus.poly"\
--used-node --wb input/network-detailed.osm.pbf
# This includes residential as well, since multiple cities are covered by the study area
+ # retrieve coarse network (see param highway) from OSM
$(osmosis) --rb file=$<\
--tf accept-ways highway=motorway,motorway_link,trunk,trunk_link,primary,primary_link,secondary_link,secondary,tertiary,motorway_junction,residential\
--bounding-polygon file="$(shared)/data/lausitz.poly"\
--used-node --wb input/network-coarse.osm.pbf
+ # retrieve germany wide network (see param highway) from OSM
$(osmosis) --rb file=$<\
--tf accept-ways highway=motorway,motorway_link,motorway_junction,trunk,trunk_link,primary,primary_link\
--used-node --wb input/network-germany.osm.pbf
+# put the 3 above networks together and remove railway
$(osmosis) --rb file=input/network-germany.osm.pbf --rb file=input/network-coarse.osm.pbf --rb file=input/network-detailed.osm.pbf\
--merge --merge\
--tag-transform file=input/remove-railway.xml\
@@ -57,7 +51,9 @@ input/network.osm: $(NETWORK)
input/sumo.net.xml: input/network.osm
+# create sumo network from osm network
$(SUMO_HOME)/bin/netconvert --geometry.remove --ramps.guess --ramps.no-split\
+# roadTypes are taken either from the general file "osmNetconvert.typ.xml" or from the german one "osmNetconvertUrbanDe.ty.xml"
--type-files $(SUMO_HOME)/data/typemap/osmNetconvert.typ.xml,$(SUMO_HOME)/data/typemap/osmNetconvertUrbanDe.typ.xml\
--tls.guess-signals true --tls.discard-simple --tls.join --tls.default-type actuated\
--junctions.join --junctions.corner-detail 5\
@@ -69,12 +65,21 @@ input/sumo.net.xml: input/network.osm
--osm-files $< -o=$@
+# transform sumo network to matsim network and clean it afterwards
+# free-speed-factor 0.75 (standard is 0.9): see VSP WP 24-08. lausitz is mix between rural and city (~0.7 - 0.8)
input/$V/$N-$V-network.xml.gz: input/sumo.net.xml
$(sc) prepare network-from-sumo $< --output $@ --free-speed-factor 0.75
$(sc) prepare clean-network $@ --output $@ --modes car --modes bike
+# add freight modes as allowed modes
+# add hbefa attributes as link attributes
+input/$V/$N-$V-network-freight-hbefa.xml.gz: input/$V/$N-$V-network.xml.gz
+ $(sc) prepare network\
+ --network $<\
+ --output $@
-input/$V/$N-$V-network-with-pt.xml.gz: input/$V/$N-$V-network.xml.gz
+#add pt to network from german wide gtfs, but only for area of shp file
+input/$V/$N-$V-network-with-pt.xml.gz: input/$V/$N-$V-network-freight-hbefa.xml.gz
$(sc) prepare transit-from-gtfs --network $<\
--output=input/$V\
--name $N-$V --date "2023-01-11" --target-crs $(CRS) \
@@ -86,22 +91,64 @@ input/$V/$N-$V-network-with-pt.xml.gz: input/$V/$N-$V-network.xml.gz
--shp $(shared)/data/network-area/network-area.shp\
--shp $(shared)/data/germany-area/germany-area.shp\
+# extract lausitz long haul freight traffic trips from german wide file
input/plans-longHaulFreight.xml.gz: input/$V/$N-$V-network.xml.gz
- $(sc) prepare extract-freight-trips ../public-svn/matsim/scenarios/countries/de/german-wide-freight/v2/german_freight.25pct.plans.xml.gz\
+ $(sc) prepare extract-freight-trips ../public-svn/matsim/scenarios/countries/de/german-wide-freight/v2/german_freight.100pct.plans.xml.gz\
--network ../public-svn/matsim/scenarios/countries/de/german-wide-freight/v2/germany-europe-network.xml.gz\
--input-crs $(CRS)\
--target-crs $(CRS)\
--shp input/shp/lausitz.shp --shp-crs $(CRS)\
--cut-on-boundary\
+ --LegMode "longDistanceFreight"\
--output $@
-
+# create facilities for commercial traffic
+input/commercialFacilities.xml.gz:
+ $(sc) prepare create-data-distribution-of-structure-data\
+ --outputFacilityFile $@\
+ --outputDataDistributionFile $(shared)/data/commercial_traffic/input/commercialTraffic/dataDistributionPerZone.csv\
+ --landuseConfiguration useOSMBuildingsAndLanduse\
+ --regionsShapeFileName $(shared)/data/commercial_traffic/input/commercialTraffic/lausitz_regions_25832.shp\
+ --regionsShapeRegionColumn "GEN"\
+ --zoneShapeFileName $(shared)/data/commercial_traffic/input/commercialTraffic/lausitz_zones_25832.shp\
+ --zoneShapeFileNameColumn "GEN"\
+ --buildingsShapeFileName $(shared)/data/commercial_traffic/input/commercialTraffic/lausitz_buildings_25832.shp\
+ --shapeFileBuildingTypeColumn "building"\
+ --landuseShapeFileName $(shared)/data/commercial_traffic/input/commercialTraffic/lausitz_landuse_25832.shp\
+ --shapeFileLanduseTypeColumn "landuse"\
+ --shapeCRS "EPSG:25832"\
+ --pathToInvestigationAreaData $(shared)/data/commercial_traffic/input/commercialTraffic/commercialTrafficAreaData.csv
+# generate small scale commercial traffic
+input/lausitz-small-scale-commercialTraffic-$V-100pct.plans.xml.gz: input/$V/$N-$V-network.xml.gz input/commercialFacilities.xml.gz
+ $(sc) prepare generate-small-scale-commercial-traffic\
+ input/$V/lausitz-$V-100pct.config.xml\
+ --pathToDataDistributionToZones $(shared)/data/commercial_traffic/input/commercialTraffic/dataDistributionPerZone.csv\
+ --pathToCommercialFacilities $(word 2,$^)\
+ --sample 1.0\
+ --jspritIterations 10\
+ --creationOption createNewCarrierFile\
+ --network $<\
+ --smallScaleCommercialTrafficType completeSmallScaleCommercialTraffic\
+ --zoneShapeFileName $(shared)/data/commercial_traffic/input/commercialTraffic/lausitz_zones_25832.shp\
+ --zoneShapeFileNameColumn "GEN"\
+ --shapeCRS "EPSG:25832"\
+ --numberOfPlanVariantsPerAgent 5\
+ --nameOutputPopulation $@\
+ --pathOutput output/commercialPersonTraffic
+
+ mv output/commercialPersonTraffic/$@ $@
+
+
+# trajectory-to-plans formerly was a collection of methods to prepare a given population
+# now, most of the functions of this class do have their own class (downsample, splitduration types...)
+# it basically only transforms the old attribute format to the new one
input/$V/prepare-100pct.plans.xml.gz:
$(sc) prepare trajectory-to-plans\
--name prepare --sample-size 1 --output input/$V\
--max-typical-duration 0\
- --population $(shared)/matsim-input-files/senozon/20230111_teilmodell_lausitz/population.xml.gz\
- --attributes $(shared)/matsim-input-files/senozon/20230111_teilmodell_lausitz/additionalPersonAttributes.xml.gz
+ --population $(shared)/data/matsim-input-files/senozon/20230111_teilmodell_lausitz/population.xml.gz\
+ --attributes $(shared)/data/matsim-input-files/senozon/20230111_teilmodell_lausitz/additionalPersonAttributes.xml.gz
+ # resolve senozon aggregated grid coords (activities): distribute them based on landuse.shp
$(sc) prepare resolve-grid-coords\
input/$V/prepare-100pct.plans.xml.gz\
--input-crs $(CRS)\
@@ -109,8 +156,12 @@ input/$V/prepare-100pct.plans.xml.gz:
--landuse $(germany)/landuse/landuse.shp\
--output $@
-input/$V/$N-$V-100pct.plans-initial.xml.gz: input/plans-longHaulFreight.xml.gz input/$V/prepare-100pct.plans.xml.gz
+input/$V/$N-$V-100pct.plans-initial.xml.gz: input/plans-longHaulFreight.xml.gz input/$V/prepare-100pct.plans.xml.gz input/lausitz-small-scale-commercialTraffic-$V-100pct.plans.xml.gz
+# generate some short distance trips, which in senozon data generally are missing
+# trip range 700m because:
+# when adding 1km trips (default value), too many trips of bin 1km-2km were also added.
+#the range value is beeline, so the trip distance (routed) often is higher than 1km
$(sc) prepare generate-short-distance-trips\
--population input/$V/prepare-100pct.plans.xml.gz\
--input-crs $(CRS)\
@@ -118,6 +169,8 @@ input/$V/$N-$V-100pct.plans-initial.xml.gz: input/plans-longHaulFreight.xml.gz i
--range 700\
--num-trips 324430
+# adapt coords of activities in the wider network such that they are closer to a link
+# such that agents do not have to walk as far as before
$(sc) prepare adjust-activity-to-link-distances input/$V/prepare-100pct.plans-with-trips.xml.gz\
--shp input/shp/lausitz.shp --shp-crs $(CRS)\
--scale 1.15\
@@ -125,34 +178,39 @@ input/$V/$N-$V-100pct.plans-initial.xml.gz: input/plans-longHaulFreight.xml.gz i
--network input/$V/$N-$V-network.xml.gz\
--output input/$V/prepare-100pct.plans-adj.xml.gz
+# change modes in subtours with chain based AND non-chain based by choosing mode for subtour randomly
$(sc) prepare fix-subtour-modes --coord-dist 100 --input input/$V/prepare-100pct.plans-adj.xml.gz --output $@
+# set car availability for agents below 18 to false, standardize some person attrs, set home coords, set income
$(sc) prepare population $@ --output $@
+# split activity types to type_duration for the scoring to take into account the typical duration
$(sc) prepare split-activity-types-duration\
--input $@\
- --exclude commercial_start,commercial_end,freight_start,freight_end\
+ --exclude commercial_start,commercial_end,freight_start,freight_end,service\
--output $@
- $(sc) prepare merge-populations $@ $< --output $@
+# merge person and freight pops
+ $(sc) prepare merge-populations $@ $< $(word 3,$^) --output $@
$(sc) prepare downsample-population $@\
--sample-size 1\
--samples 0.25 0.1 0.01\
-input/$V/$N-$V-counts-car-bast.xml.gz: input/2019_A_S.zip input/2019_B_S.zip input/Jawe2019.csv input/$V/$N-$V-network-with-pt.xml.gz
+# create matsim counts file
+input/$V/$N-$V-counts-bast.xml.gz: input/$V/$N-$V-network-with-pt.xml.gz
$(sc) prepare counts-from-bast\
--network input/$V/$N-$V-network-with-pt.xml.gz\
- --motorway-data input/2019_A_S.zip\
- --primary-data input/2019_B_S.zip\
- --station-data input/Jawe2019.csv\
+ --motorway-data $(germany)/bast-counts/2019/2019_A_S.zip\
+ --primary-data $(germany)/bast-counts/2019/2019_B_S.zip\
+ --station-data $(germany)/bast-counts/2019/Jawe2019.csv\
--year 2019\
--shp input/shp/lausitz.shp --shp-crs $(CRS)\
- --car-output $@\
- --freight-output $(subst car,freight,$@)
+ --output $@
check: input/$V/$N-$V-100pct.plans-initial.xml.gz
+ #commuter analysis, still TODO
$(sc) analysis commuter\
--population $<\
--input-crs $(CRS)\
diff --git a/README.md b/README.md
index 4d32a8b..99d7819 100644
--- a/README.md
+++ b/README.md
@@ -123,4 +123,4 @@ For more information about MATSim, see here: https://www.matsim.org/
### Internal Documentation
Internal documentation can be found here:
-https://docs.google.com/document/d/1igBcrRTFklb7THSU1bNNIyG-pwiYgXBg6WeI-Pf7zj8/edit
\ No newline at end of file
+https://docs.google.com/document/d/1igBcrRTFklb7THSU1bNNIyG-pwiYgXBg6WeI-Pf7zj8/edit?usp=sharing
\ No newline at end of file
diff --git a/checkstyle.xml b/checkstyle.xml
index eb8b431..ea489e2 100644
--- a/checkstyle.xml
+++ b/checkstyle.xml
@@ -10,7 +10,7 @@
-
+
diff --git a/input/v1.0/lausitz-v1.0-25pct.config.xml b/input/v1.0/lausitz-v1.0-25pct.config.xml
index f9000d3..7ebbe7e 100644
--- a/input/v1.0/lausitz-v1.0-25pct.config.xml
+++ b/input/v1.0/lausitz-v1.0-25pct.config.xml
@@ -4,6 +4,7 @@
+
@@ -73,6 +74,9 @@
+
@@ -90,9 +94,12 @@
+
+
+
@@ -101,6 +108,7 @@
+
@@ -138,9 +146,14 @@
+
+
+
@@ -149,6 +162,9 @@
+
@@ -171,6 +187,7 @@
+
@@ -201,6 +218,7 @@
+
diff --git a/input/v1.1/lausitz-v1.1-10pct.config.xml b/input/v1.1/lausitz-v1.1-10pct.config.xml
new file mode 100644
index 0000000..e8d5b20
--- /dev/null
+++ b/input/v1.1/lausitz-v1.1-10pct.config.xml
@@ -0,0 +1,229 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/input/v1.1/vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.dbf b/input/v1.1/vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.dbf
new file mode 100644
index 0000000..2264ba1
Binary files /dev/null and b/input/v1.1/vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.dbf differ
diff --git a/input/v1.1/vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.prj b/input/v1.1/vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.prj
new file mode 100644
index 0000000..bd846ae
--- /dev/null
+++ b/input/v1.1/vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.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/input/v1.1/vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.shp b/input/v1.1/vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.shp
new file mode 100644
index 0000000..462f27b
Binary files /dev/null and b/input/v1.1/vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.shp differ
diff --git a/input/v1.1/vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.shx b/input/v1.1/vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.shx
new file mode 100644
index 0000000..bb41c7e
Binary files /dev/null and b/input/v1.1/vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.shx differ
diff --git a/mvnw b/mvnw
old mode 100644
new mode 100755
index 41c0f0c..8d937f4
--- 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 18a09f0..4db5185 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,13 +12,14 @@
- 16.0-PR3172
+ 2025.0-PR3444
+
4.0.0
com.github.matsim-scenarios
matsim-lausitz
- 1.0
+ 1.1
MATSim Lausitz Model
A transport model of the Lausitz region and its surroundings
@@ -31,7 +32,7 @@
UTF-8
UTF-8
- 17
+ 21
@@ -152,7 +153,7 @@
org.jacoco
jacoco-maven-plugin
- 0.8.8
+ 0.8.12
diff --git a/src/main/R/analysis/deutschlandtarifPricesAnalysis.R b/src/main/R/analysis/deutschlandtarifPricesAnalysis.R
new file mode 100644
index 0000000..88cd168
--- /dev/null
+++ b/src/main/R/analysis/deutschlandtarifPricesAnalysis.R
@@ -0,0 +1,54 @@
+library(tidyverse)
+
+prices <- read.csv(file="../../shared-svn/projects/DiTriMo/data/deutschlandtarif_prices/deutschlandtarif_prices.csv")
+
+prices20 <- prices %>%
+ filter(km <= 20)
+
+prices100 <- prices %>%
+ filter(km <= 100)
+
+prices1000 <- prices %>%
+ filter(km <= 1000)
+
+pricesAbove100 <- prices %>%
+ filter(km >= 100)
+
+linear20 <- lm(price ~ km, data = prices20)
+linear100 <- lm(price ~ km, data = prices100)
+linear1000 <- lm(price ~ km, data = prices1000)
+linear <- lm(price ~ km, data = prices)
+linearAbove100 <- lm(price ~ km, data = pricesAbove100)
+
+# Create a dataframe for the lines
+lines_df <- data.frame(
+ intercept = c(coef(linear)[1], coef(linear20)[1], coef(linear100)[1], coef(linear1000)[1], coef(linearAbove100)[1]),
+ slope = c(coef(linear)[2], coef(linear20)[2], coef(linear100)[2], coef(linear1000)[2], coef(linearAbove100)[2]),
+ label = c("1-2000km", "1-20km", "1-100km", "1-1000km", "100-2000km")
+)
+
+ggplot(prices, aes(x = km, y = price)) +
+ geom_point() + # Scatter plot of the data points
+ geom_abline(data = lines_df, aes(intercept = intercept, slope = slope, color = label), linewidth=.75) +
+ scale_color_manual(values = c("red", "lightblue", "orange3", "purple4", "pink")) + # Manually setting colors
+ labs(title = "Deutschlandtarif linear functions",
+ x = "km",
+ y = "price [€]",
+ color = "Model") + # Legend title
+ theme_minimal()
+
+lines_df_relevant <- data.frame(
+ intercept = c(coef(linear100)[1], coef(linearAbove100)[1]),
+ slope = c(coef(linear100)[2], coef(linearAbove100)[2]),
+ label = c("1-100km", "100-2000km")
+)
+
+ggplot(prices, aes(x = km, y = price)) +
+ geom_point() + # Scatter plot of the data points
+ geom_abline(data = lines_df_relevant, aes(intercept = intercept, slope = slope, color = label), linewidth=.75) +
+ scale_color_manual(values = c("red", "blue"), labels = c("1-100km y = 0.272x + 1.67", "100-2000km y = 0.11x + 26.89")) + # Manually setting colors
+ labs(title = "Deutschlandtarif linear functions",
+ x = "km",
+ y = "price [€]",
+ color = "Model") + # Legend title
+ theme_minimal()
diff --git a/src/main/R/commuter-analysis.R b/src/main/R/commuter-analysis.R
new file mode 100644
index 0000000..08405ff
--- /dev/null
+++ b/src/main/R/commuter-analysis.R
@@ -0,0 +1,52 @@
+library(matsim)
+library(tidyverse)
+library(readr)
+library(sf)
+
+#FILES
+FILE_DIR = "../../shared-svn/projects/DiTriMo/data/commuters-by-town"
+SIM <- paste0(FILE_DIR, "lausitz-v1.0-commuter.csv")
+GEMEINDE <- paste0(FILE_DIR, "pgemeinden.csv")
+COMMUTER <- paste0(FILE_DIR, "commuter.csv")
+SHP <- paste0(FILE_DIR, "VG5000_GEM/VG5000_GEM.shp")
+LAUSITZ.SHP <- paste0(FILE_DIR, "network-area/network-area.shp")
+
+shp <- st_read(SHP)
+lausitz.shp <- st_read(LAUSITZ.SHP)
+
+sim <- read_csv(file = SIM)
+gemeinden <- read_csv( file = GEMEINDE) %>%
+ mutate(code = str_remove(string = code, pattern = "P"))
+
+commuter <- read_csv(file = COMMUTER) %>%
+ mutate(key = paste0(from, "-", to))
+
+sim.1 <- sim %>%
+ filter(!is.na(from) & !is.na(to)) %>%
+ left_join(gemeinden, by = c("from" = "code")) %>%
+ left_join(gemeinden, by = c("from" = "code"), suffix = c("_from", "_to")) %>%
+ mutate(key = paste0(from, "-", to)) %>%
+ select(-c(from, to)) %>%
+ left_join(commuter, by = "key", suffix = c("_sim", "_real")) %>%
+ filter(!is.na(from)) %>%
+# pivot_longer(cols = starts_with("n_"), names_to = "src", values_to = "n", names_prefix = "n_") %>%
+ arrange(desc(n_real))
+
+breaks <- c(-Inf, 0.8, 1.2, Inf)
+labels <- c("less", "exakt", "more")
+
+sim.2 <- sim.1 %>%
+ filter(n_sim > 10) %>%
+ select(from, to, starts_with("n_"), starts_with("name_")) %>%
+ mutate(n_rel = n_sim / n_real,
+ quality = cut(n_rel, breaks = breaks, labels = labels))
+
+ggplot(sim.2, aes(x = n_real, y = n_sim, col = quality)) +
+
+ geom_point() +
+
+ scale_x_log10() +
+
+ scale_y_log10() +
+
+ theme_bw()
diff --git a/src/main/R/counts.R b/src/main/R/counts.R
index 46adb56..82a1354 100644
--- a/src/main/R/counts.R
+++ b/src/main/R/counts.R
@@ -4,10 +4,10 @@ devtools::install_github("matsim-vsp/matsim-r",ref="counts")
library(matsim)
library(tidyverse)
-COUNTS <- "Y:/matsim-lausitz/input/v1.0/lausitz-v1.0-counts-car-bast.xml.gz"
-NETWORK <- "Y:/matsim-lausitz/input/v1.0/lausitz-v1.0-network-with-pt.xml.gz"
+COUNTS <- "../../public-svn/matsim/scenarios/countries/de/lausitz/input/v1.0/lausitz-v1.0-counts-car-bast.xml.gz"
+NETWORK <- "../../public-svn/matsim/scenarios/countries/de/lausitz/input/v1.0/lausitz-v1.0-network-with-pt.xml.gz"
-linkstats <- readLinkStats(runId = "v1.0-uncalibrated", file = "Y:/matsim-lausitz/qa/output/lausitz-25pct.output_linkstats.csv.gz")
+linkstats <- readLinkStats(runId = "v1.0-uncalibrated", file = "Y:/matsim-lausitz/qa/output/lausitz-25pct.output_linkstats.csv.gz", sampleSize = 1)
counts <- readCounts(COUNTS)
network <- loadNetwork(NETWORK)
@@ -17,7 +17,7 @@ join <- mergeCountsAndLinks(counts = counts, linkStats = list(linkstats), netwo
#### VIA-styled scatterplot ####
-FILE_DIR = "C:/Users/ACER/Desktop/Uni/VSP/Lausitz-Plots/"
+FILE_DIR = "../../shared-svn/projects/DiTriMo/data/commuters-by-town"
createCountScatterPlot(joinedFrame = join)
ggsave(filename = paste0(FILE_DIR, "Traffic_Count_Scatterplot_with_freight.jpg"))
@@ -43,7 +43,7 @@ rm(join.dtv.distribution)
#### Analysis of Estimation Quality ####
-join.est.quality <- processDtvEstimationQuality(joinedFrame = join, aggr = T) %>%
+join.est.quality <- processDtvEstimationQuality(joinedFrame = join, aggr = F) %>%
filter(!type %in% c("residential", "unclassified", NA))
ggplot(join.est.quality, aes(estimation, share, fill = type)) +
@@ -59,4 +59,26 @@ ggplot(join.est.quality, aes(estimation, share, fill = type)) +
theme(legend.position = "none", axis.text.x = element_text(angle = 90))
rm(join.est.quality)
-ggsave(filename = paste0(FILE_DIR, "Estimation_quality_by_road_type_with_freight.jpg"))
\ No newline at end of file
+ggsave(filename = paste0(FILE_DIR, "Estimation_quality_by_road_type_with_freight.jpg"))
+
+
+#### network plot ####
+
+library(tmap)
+library(tmaptools)
+library(OpenStreetMap)
+library(sf)
+
+link.geom <- join %>%
+ left_join(network$links, by = c("loc_id" = "id")) %>%
+ mutate(geom = sprintf("LINESTRING(%s %s, %s %s)", x.from, y.from, x.to, y.to)) %>%
+ st_as_sf(crs = 25832, wkt = "geom") %>%
+ transmute(loc_id, type.x, rel_vol = volume / count, geom)
+
+tmap_mode("view")
+
+tm_shape(shp = link.geom) +
+ tm_lines(col = "estimation", style = "cont", lwd = 3.5, palette = c("red", "green", "blue"))
+
+tm_shape(shp = link.geom) +
+ tm_lines(col = "rel_vol", style = "cont", lwd = 5, palette = c("red", "yellow", "green"), breaks = c(0, 0.05, 0.8, 2))
diff --git a/src/main/java/org/matsim/dashboards/LausitzDashboardProvider.java b/src/main/java/org/matsim/dashboards/LausitzDashboardProvider.java
index 02b3f9c..7c2589c 100644
--- a/src/main/java/org/matsim/dashboards/LausitzDashboardProvider.java
+++ b/src/main/java/org/matsim/dashboards/LausitzDashboardProvider.java
@@ -4,6 +4,7 @@
import org.matsim.simwrapper.Dashboard;
import org.matsim.simwrapper.DashboardProvider;
import org.matsim.simwrapper.SimWrapper;
+import org.matsim.simwrapper.dashboard.EmissionsDashboard;
import org.matsim.simwrapper.dashboard.TripDashboard;
import java.util.List;
@@ -14,10 +15,18 @@
public class LausitzDashboardProvider implements DashboardProvider {
@Override
public List getDashboards(Config config, SimWrapper simWrapper) {
- return List.of(new TripDashboard(
+
+ TripDashboard trips = new TripDashboard(
"lausitz_mode_share.csv",
"lausitz_mode_share_per_dist.csv",
"lausitz_mode_users.csv")
+ .withGroupedRefData("lausitz_mode_share_per_group_dist_ref.csv", "age", "economic_status")
+ .withDistanceDistribution("lausitz_mode_share_distance_distribution.csv");
+
+ return List.of(trips,
+ new EmissionsDashboard()
+// the NoiseAnalysis is not run here because it needs more RAM than the entire simulation,
+// which leads to VM crashes and prevents other analysis to run. We have to run it separately (e.g. with LausitzSimWrapperRunner)
);
}
}
diff --git a/src/main/java/org/matsim/dashboards/LausitzSimWrapperRunner.java b/src/main/java/org/matsim/dashboards/LausitzSimWrapperRunner.java
new file mode 100644
index 0000000..bb61bda
--- /dev/null
+++ b/src/main/java/org/matsim/dashboards/LausitzSimWrapperRunner.java
@@ -0,0 +1,104 @@
+/* *********************************************************************** *
+ * 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.dashboards;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.matsim.application.ApplicationUtils;
+import org.matsim.application.MATSimAppCommand;
+import org.matsim.application.options.ShpOptions;
+import org.matsim.core.config.Config;
+import org.matsim.core.config.ConfigUtils;
+import org.matsim.simwrapper.Dashboard;
+import org.matsim.simwrapper.SimWrapper;
+import org.matsim.simwrapper.SimWrapperConfigGroup;
+import org.matsim.simwrapper.dashboard.NoiseDashboard;
+import picocli.CommandLine;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.nio.file.Path;
+import java.util.List;
+
+@CommandLine.Command(
+ name = "simwrapper",
+ description = "Run additional analysis and create SimWrapper dashboard for existing run output."
+)
+final class LausitzSimWrapperRunner implements MATSimAppCommand {
+
+ private static final Logger log = LogManager.getLogger(LausitzSimWrapperRunner.class);
+
+ @CommandLine.Parameters(arity = "1..*", description = "Path to run output directories for which dashboards are to be generated.")
+ private List inputPaths;
+
+ @CommandLine.Mixin
+ private final ShpOptions shp = new ShpOptions();
+
+ @CommandLine.Option(names = "--noise", defaultValue = "false", description = "create noise dashboard")
+ private boolean noise;
+
+
+ private LausitzSimWrapperRunner(){
+ }
+
+ @Override
+ public Integer call() throws Exception {
+
+ if (!noise){
+ throw new IllegalArgumentException("you have not configured any dashboard to be created! Please use command line parameters!");
+ }
+
+ for (Path runDirectory : inputPaths) {
+ log.info("Running on {}", runDirectory);
+
+ Path configPath = ApplicationUtils.matchInput("config.xml", runDirectory);
+ Config config = ConfigUtils.loadConfig(configPath.toString());
+ SimWrapper sw = SimWrapper.create(config);
+
+ SimWrapperConfigGroup simwrapperCfg = ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class);
+ if (shp.isDefined()){
+ simwrapperCfg.defaultParams().shp = shp.getShapeFile();
+ }
+ //skip default dashboards
+ simwrapperCfg.defaultDashboards = SimWrapperConfigGroup.Mode.disabled;
+
+ //add dashboards according to command line parameters
+// TODO: if more dashboards are to be added here, we need to check if noise==true before adding noise dashboard here
+ sw.addDashboard(Dashboard.customize(new NoiseDashboard()).context("noise"));
+
+
+ try {
+ sw.generate(runDirectory, true);
+ sw.run(runDirectory);
+ } catch (IOException e) {
+ throw new InterruptedIOException();
+ }
+ }
+
+ return 0;
+ }
+
+ public static void main(String[] args) {
+ new LausitzSimWrapperRunner().execute(args);
+
+ }
+
+}
diff --git a/src/main/java/org/matsim/run/LausitzScenario.java b/src/main/java/org/matsim/run/LausitzScenario.java
index 48a4e64..4a16f7c 100644
--- a/src/main/java/org/matsim/run/LausitzScenario.java
+++ b/src/main/java/org/matsim/run/LausitzScenario.java
@@ -1,10 +1,11 @@
package org.matsim.run;
import com.google.common.collect.Sets;
-import org.matsim.analysis.ModeChoiceCoverageControlerListener;
+import org.matsim.analysis.personMoney.PersonMoneyEventsAnalysisModule;
+import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.TransportMode;
-import org.matsim.api.core.v01.network.Link;
+import org.matsim.api.core.v01.population.Person;
import org.matsim.application.MATSimApplication;
import org.matsim.application.analysis.CheckPopulation;
import org.matsim.application.analysis.traffic.LinkStats;
@@ -16,21 +17,40 @@
import org.matsim.application.prepare.network.CreateNetworkFromSumo;
import org.matsim.application.prepare.population.*;
import org.matsim.application.prepare.pt.CreateTransitScheduleFromGtfs;
+import org.matsim.contrib.emissions.HbefaVehicleCategory;
+import org.matsim.contrib.emissions.utils.EmissionsConfigGroup;
+import org.matsim.contrib.vsp.pt.fare.DistanceBasedPtFareParams;
+import org.matsim.contrib.vsp.pt.fare.FareZoneBasedPtFareParams;
+import org.matsim.contrib.vsp.pt.fare.PtFareConfigGroup;
+import org.matsim.contrib.vsp.pt.fare.PtFareModule;
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.ReplanningConfigGroup;
import org.matsim.core.config.groups.RoutingConfigGroup;
+import org.matsim.core.config.groups.ScoringConfigGroup;
import org.matsim.core.controler.AbstractModule;
import org.matsim.core.controler.Controler;
+import org.matsim.core.population.PopulationUtils;
+import org.matsim.core.replanning.strategies.DefaultPlanStrategiesModule;
import org.matsim.core.scoring.functions.ScoringParametersForPerson;
+import org.matsim.run.analysis.CommunityFilter;
import org.matsim.run.analysis.CommuterAnalysis;
+import org.matsim.run.analysis.DistanceMatrix;
+import org.matsim.run.prepare.PrepareNetwork;
import org.matsim.run.prepare.PreparePopulation;
import org.matsim.simwrapper.SimWrapperConfigGroup;
import org.matsim.simwrapper.SimWrapperModule;
+import org.matsim.vehicles.EngineInformation;
+import org.matsim.vehicles.VehicleType;
+import org.matsim.vehicles.VehicleUtils;
import picocli.CommandLine;
import playground.vsp.scoring.IncomeDependentUtilityOfMoneyPersonScoringParameters;
import javax.annotation.Nullable;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
@CommandLine.Command(header = ":: Open Lausitz Scenario ::", version = LausitzScenario.VERSION, mixinStandardHelpOptions = true)
@@ -38,25 +58,44 @@
CreateNetworkFromSumo.class, CreateTransitScheduleFromGtfs.class, TrajectoryToPlans.class, GenerateShortDistanceTrips.class,
MergePopulations.class, ExtractRelevantFreightTrips.class, DownSamplePopulation.class, ExtractHomeCoordinates.class, CleanNetwork.class,
CreateLandUseShp.class, ResolveGridCoordinates.class, FixSubtourModes.class, AdjustActivityToLinkDistances.class, XYToLinks.class,
- SplitActivityTypesDuration.class, CreateCountsFromBAStData.class, PreparePopulation.class, CleanPopulation.class
+ SplitActivityTypesDuration.class, CreateCountsFromBAStData.class, PreparePopulation.class, CleanPopulation.class, PrepareNetwork.class
})
@MATSimApplication.Analysis({
- LinkStats.class, CheckPopulation.class, CommuterAnalysis.class,
+ LinkStats.class, CheckPopulation.class, CommuterAnalysis.class, CommunityFilter.class, DistanceMatrix.class
})
public class LausitzScenario extends MATSimApplication {
- public static final String VERSION = "1.0";
+ public static final String VERSION = "1.1";
+ public static final String FREIGHT = "longDistanceFreight";
+ private static final String AVERAGE = "average";
+ public static final String HEAVY_MODE = "truck40t";
+ public static final String MEDIUM_MODE = "truck18t";
+ public static final String LIGHT_MODE = "truck8t";
+
+// To decrypt hbefa input files set MATSIM_DECRYPTION_PASSWORD as environment variable. ask VSP for access.
+ private static final String HBEFA_2020_PATH = "https://svn.vsp.tu-berlin.de/repos/public-svn/3507bb3997e5657ab9da76dbedbb13c9b5991d3e/0e73947443d68f95202b71a156b337f7f71604ae/";
+ private static final String HBEFA_FILE_COLD_DETAILED = HBEFA_2020_PATH + "82t7b02rc0rji2kmsahfwp933u2rfjlkhfpi2u9r20.enc";
+ private static final String HBEFA_FILE_WARM_DETAILED = HBEFA_2020_PATH + "944637571c833ddcf1d0dfcccb59838509f397e6.enc";
+ private static final String HBEFA_FILE_COLD_AVERAGE = HBEFA_2020_PATH + "r9230ru2n209r30u2fn0c9rn20n2rujkhkjhoewt84202.enc" ;
+ private static final String HBEFA_FILE_WARM_AVERAGE = HBEFA_2020_PATH + "7eff8f308633df1b8ac4d06d05180dd0c5fdf577.enc";
@CommandLine.Mixin
- private final SampleOptions sample = new SampleOptions( 25, 10, 1);
+ private final SampleOptions sample = new SampleOptions( 100, 25, 10, 1);
+
+ @CommandLine.Option(names = "--emissions", defaultValue = "PERFORM_EMISSIONS_ANALYSIS", description = "Define if emission analysis should be performed or not.")
+ private EmissionAnalysisHandling emissions;
public LausitzScenario(@Nullable Config config) {
super(config);
}
+ public LausitzScenario(String configPath) {
+ super(configPath);
+ }
+
public LausitzScenario() {
- super(String.format("input/v%s/lausitz-v%s-25pct.config.xml", VERSION, VERSION));
+ super(String.format("input/v1.1/lausitz-v1.1-10pct.config.xml", VERSION, VERSION));
}
public static void main(String[] args) {
@@ -70,6 +109,7 @@ protected Config prepareConfig(Config config) {
// Add all activity types with time bins
SnzActivities.addScoringParams(config);
+// add simwrapper config module
SimWrapperConfigGroup simWrapper = ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class);
if (sample.isSet()) {
@@ -79,54 +119,211 @@ protected Config prepareConfig(Config config) {
config.qsim().setFlowCapFactor(sample.getSample());
config.qsim().setStorageCapFactor(sample.getSample());
- config.counts().setCountsScaleFactor(100d / sample.getSample());
+ config.counts().setCountsScaleFactor(sample.getSample());
simWrapper.sampleSize = sample.getSample();
}
+// performing set to 6.0 after calibration task force july 24
+ double performing = 6.0;
+ ScoringConfigGroup scoringConfigGroup = config.scoring();
+ scoringConfigGroup.setPerforming_utils_hr(performing);
+
+// set ride scoring params dependent from car params
+ ScoringConfigGroup.ModeParams rideParams = scoringConfigGroup.getOrCreateModeParams(TransportMode.ride);
+ ScoringConfigGroup.ModeParams carParams = scoringConfigGroup.getModes().get(TransportMode.car);
+// 2.0 + 1.0 = alpha + 1
+// ride cost = alpha * car cost
+// ride marg utility of traveling = (alpha + 1) * marg utility travelling car + alpha * beta perf
+ double alpha = 2;
+ rideParams.setMarginalUtilityOfTraveling((alpha + 1) * carParams.getMarginalUtilityOfTraveling() - alpha * config.scoring().getPerforming_utils_hr());
+ rideParams.setDailyMonetaryConstant(0.);
+ rideParams.setMonetaryDistanceRate(carParams.getMonetaryDistanceRate() * 2);
+
config.qsim().setUsingTravelTimeCheckInTeleportation(true);
config.qsim().setUsePersonIdForMissingVehicleId(false);
config.routing().setAccessEgressType(RoutingConfigGroup.AccessEgressType.accessEgressModeToLink);
- // TODO: Config options
+ prepareCommercialTrafficConfig(config);
+
+// set pt fare calc model to fareZoneBased = fare of vvo tarifzone 20 is paid for trips within fare zone
+// every other trip: Deutschlandtarif
+// for more info see PTFareModule / ChainedPtFareCalculator classes in vsp contrib
+ PtFareConfigGroup ptFareConfigGroup = ConfigUtils.addOrGetModule(config, PtFareConfigGroup.class);
+
+ FareZoneBasedPtFareParams vvo20 = new FareZoneBasedPtFareParams();
+ vvo20.setTransactionPartner("VVO Tarifzone 20");
+ vvo20.setDescription("VVO Tarifzone 20");
+ vvo20.setOrder(1);
+ vvo20.setFareZoneShp("./vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.shp");
+
+ DistanceBasedPtFareParams germany = DistanceBasedPtFareParams.GERMAN_WIDE_FARE_2024;
+ germany.setTransactionPartner("Deutschlandtarif");
+ germany.setDescription("Deutschlandtarif");
+ germany.setOrder(2);
+
+ ptFareConfigGroup.addParameterSet(vvo20);
+ ptFareConfigGroup.addParameterSet(germany);
+ if (emissions == EmissionAnalysisHandling.PERFORM_EMISSIONS_ANALYSIS) {
+// set hbefa input files for emission analysis
+ EmissionsConfigGroup eConfig = ConfigUtils.addOrGetModule(config, EmissionsConfigGroup.class);
+ eConfig.setDetailedColdEmissionFactorsFile(HBEFA_FILE_COLD_DETAILED);
+ eConfig.setDetailedWarmEmissionFactorsFile(HBEFA_FILE_WARM_DETAILED);
+ eConfig.setAverageColdEmissionFactorsFile(HBEFA_FILE_COLD_AVERAGE);
+ eConfig.setAverageWarmEmissionFactorsFile(HBEFA_FILE_WARM_AVERAGE);
+ eConfig.setHbefaTableConsistencyCheckingLevel(EmissionsConfigGroup.HbefaTableConsistencyCheckingLevel.consistent);
+ eConfig.setDetailedVsAverageLookupBehavior(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable);
+ }
return config;
}
@Override
protected void prepareScenario(Scenario scenario) {
- for (Link link : scenario.getNetwork().getLinks().values()) {
- Set modes = link.getAllowedModes();
- // allow freight traffic together with cars
- if (modes.contains("car")) {
- Set newModes = Sets.newHashSet(modes);
- newModes.add("freight");
+ for (Person person : scenario.getPopulation().getPersons().values()) {
+
+ if (PopulationUtils.getSubpopulation(person).contains("commercialPersonTraffic") ||
+ PopulationUtils.getSubpopulation(person).contains("goodsTraffic")) {
+
+ Map> types = VehicleUtils.getVehicleTypes(person);
- link.setAllowedModes(newModes);
+ for (Map.Entry> entry : types.entrySet()) {
+ if (Set.of(HEAVY_MODE, MEDIUM_MODE, LIGHT_MODE).contains(entry.getKey())) {
+ types.put(entry.getKey(), Id.create(entry.getKey(), VehicleType.class));
+ }
+ }
}
+
+ }
+
+
+
+// add freight and truck as allowed modes together with car
+ PrepareNetwork.prepareFreightNetwork(scenario.getNetwork());
+
+ if (emissions == EmissionAnalysisHandling.PERFORM_EMISSIONS_ANALYSIS) {
+// prepare hbefa link attributes + make link.getType() handable for OsmHbefaMapping
+ PrepareNetwork.prepareEmissionsAttributes(scenario.getNetwork());
+// prepare vehicle types for emission analysis
+ prepareVehicleTypesForEmissionAnalysis(scenario);
}
}
@Override
protected void prepareControler(Controler controler) {
+ //analyse PersonMoneyEvents
+ controler.addOverridingModule(new PersonMoneyEventsAnalysisModule());
+
controler.addOverridingModule(new SimWrapperModule());
controler.addOverridingModule(new AbstractModule() {
@Override
public void install() {
-
+ install(new PtFareModule());
bind(ScoringParametersForPerson.class).to(IncomeDependentUtilityOfMoneyPersonScoringParameters.class).asEagerSingleton();
- addControlerListenerBinding().to(ModeChoiceCoverageControlerListener.class);
-
addTravelTimeBinding(TransportMode.ride).to(networkTravelTime());
addTravelDisutilityFactoryBinding(TransportMode.ride).to(carTravelDisutilityFactoryKey());
+// we do not need to add SwissRailRaptor explicitely! this is done in core
}
});
}
+
+ /**
+ * Prepare the config for commercial traffic.
+ */
+ public static void prepareCommercialTrafficConfig(Config config) {
+
+ Set modes = Set.of(HEAVY_MODE, MEDIUM_MODE, LIGHT_MODE);
+
+ modes.forEach(mode -> {
+ ScoringConfigGroup.ModeParams thisModeParams = new ScoringConfigGroup.ModeParams(mode);
+ config.scoring().addModeParams(thisModeParams);
+ });
+
+ Set qsimModes = new HashSet<>(config.qsim().getMainModes());
+ config.qsim().setMainModes(Sets.union(qsimModes, modes));
+
+ Set networkModes = new HashSet<>(config.routing().getNetworkModes());
+ config.routing().setNetworkModes(Sets.union(networkModes, modes));
+
+ config.scoring().addActivityParams(new ScoringConfigGroup.ActivityParams("commercial_start").setTypicalDuration(30 * 60.));
+ config.scoring().addActivityParams(new ScoringConfigGroup.ActivityParams("commercial_end").setTypicalDuration(30 * 60.));
+ config.scoring().addActivityParams(new ScoringConfigGroup.ActivityParams("service").setTypicalDuration(30 * 60.));
+ config.scoring().addActivityParams(new ScoringConfigGroup.ActivityParams("start").setTypicalDuration(30 * 60.));
+ config.scoring().addActivityParams(new ScoringConfigGroup.ActivityParams("end").setTypicalDuration(30 * 60.));
+ config.scoring().addActivityParams(new ScoringConfigGroup.ActivityParams("freight_start").setTypicalDuration(30 * 60.));
+ config.scoring().addActivityParams(new ScoringConfigGroup.ActivityParams("freight_end").setTypicalDuration(30 * 60.));
+
+ for (String subpopulation : List.of("commercialPersonTraffic", "commercialPersonTraffic_service", "goodsTraffic")) {
+ config.replanning().addStrategySettings(
+ new ReplanningConfigGroup.StrategySettings()
+ .setStrategyName(DefaultPlanStrategiesModule.DefaultSelector.ChangeExpBeta)
+ .setWeight(0.85)
+ .setSubpopulation(subpopulation)
+ );
+
+ config.replanning().addStrategySettings(
+ new ReplanningConfigGroup.StrategySettings()
+ .setStrategyName(DefaultPlanStrategiesModule.DefaultStrategy.ReRoute)
+ .setWeight(0.1)
+ .setSubpopulation(subpopulation)
+ );
+ }
+ }
+
+ private static void prepareVehicleTypesForEmissionAnalysis(Scenario scenario) {
+ for (VehicleType type : scenario.getVehicles().getVehicleTypes().values()) {
+ EngineInformation engineInformation = type.getEngineInformation();
+
+// only set engine information if none are present
+ if (engineInformation.getAttributes().isEmpty()) {
+ switch (type.getId().toString()) {
+ case TransportMode.car -> {
+ VehicleUtils.setHbefaVehicleCategory(engineInformation, HbefaVehicleCategory.PASSENGER_CAR.toString());
+ VehicleUtils.setHbefaTechnology(engineInformation, AVERAGE);
+ VehicleUtils.setHbefaSizeClass(engineInformation, AVERAGE);
+ VehicleUtils.setHbefaEmissionsConcept(engineInformation, AVERAGE);
+ }
+ case TransportMode.ride -> {
+// ignore ride, the mode routed on network, but then teleported
+ VehicleUtils.setHbefaVehicleCategory(engineInformation, HbefaVehicleCategory.NON_HBEFA_VEHICLE.toString());
+ VehicleUtils.setHbefaTechnology(engineInformation, AVERAGE);
+ VehicleUtils.setHbefaSizeClass(engineInformation, AVERAGE);
+ VehicleUtils.setHbefaEmissionsConcept(engineInformation, AVERAGE);
+ }
+ case FREIGHT -> {
+ VehicleUtils.setHbefaVehicleCategory(engineInformation, HbefaVehicleCategory.HEAVY_GOODS_VEHICLE.toString());
+ VehicleUtils.setHbefaTechnology(engineInformation, AVERAGE);
+ VehicleUtils.setHbefaSizeClass(engineInformation, AVERAGE);
+ VehicleUtils.setHbefaEmissionsConcept(engineInformation, AVERAGE);
+ }
+ case TransportMode.bike -> {
+// ignore bikes
+ VehicleUtils.setHbefaVehicleCategory(engineInformation, HbefaVehicleCategory.NON_HBEFA_VEHICLE.toString());
+ VehicleUtils.setHbefaTechnology(engineInformation, AVERAGE);
+ VehicleUtils.setHbefaSizeClass(engineInformation, AVERAGE);
+ VehicleUtils.setHbefaEmissionsConcept(engineInformation, AVERAGE);
+ }
+ default -> throw new IllegalArgumentException("does not know how to handle vehicleType " + type.getId().toString());
+ }
+ }
+ }
+
+// ignore all pt veh types
+ scenario.getTransitVehicles()
+ .getVehicleTypes()
+ .values().forEach(type -> VehicleUtils.setHbefaVehicleCategory(type.getEngineInformation(), HbefaVehicleCategory.NON_HBEFA_VEHICLE.toString()));
+ }
+
+ /**
+ * Defines if all necessary configs for emissions analysis should be made
+ * and hence if emissions analysis is performed or not (will fail without configs).
+ */
+ enum EmissionAnalysisHandling {PERFORM_EMISSIONS_ANALYSIS, DO_NOT_PERFORM_EMISSIONS_ANALYSIS}
}
diff --git a/src/main/java/org/matsim/run/RunLausitzDrtScenario.java b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java
new file mode 100644
index 0000000..fbec143
--- /dev/null
+++ b/src/main/java/org/matsim/run/RunLausitzDrtScenario.java
@@ -0,0 +1,212 @@
+package org.matsim.run;
+
+import org.locationtech.jts.geom.Geometry;
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.Scenario;
+import org.matsim.api.core.v01.TransportMode;
+import org.matsim.api.core.v01.network.Link;
+import org.matsim.application.MATSimApplication;
+import org.matsim.application.options.ShpOptions;
+import org.matsim.contrib.drt.optimizer.constraints.DefaultDrtOptimizationConstraintsSet;
+import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsParams;
+import org.matsim.contrib.drt.optimizer.insertion.extensive.ExtensiveInsertionSearchParams;
+import org.matsim.contrib.drt.routing.DrtRoute;
+import org.matsim.contrib.drt.routing.DrtRouteFactory;
+import org.matsim.contrib.drt.run.DrtConfigGroup;
+import org.matsim.contrib.drt.run.DrtConfigs;
+import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup;
+import org.matsim.contrib.drt.run.MultiModeDrtModule;
+import org.matsim.contrib.dvrp.run.DvrpConfigGroup;
+import org.matsim.contrib.dvrp.run.DvrpModule;
+import org.matsim.contrib.dvrp.run.DvrpQSimComponents;
+import org.matsim.core.config.Config;
+import org.matsim.core.config.ConfigUtils;
+import org.matsim.core.config.groups.QSimConfigGroup;
+import org.matsim.core.config.groups.ScoringConfigGroup;
+import org.matsim.core.config.groups.SubtourModeChoiceConfigGroup;
+import org.matsim.core.controler.Controler;
+import org.matsim.core.network.algorithms.MultimodalNetworkCleaner;
+import org.matsim.core.utils.geometry.geotools.MGC;
+import org.matsim.vehicles.Vehicle;
+import org.matsim.vehicles.VehicleCapacity;
+import org.matsim.vehicles.VehicleType;
+import org.matsim.vehicles.VehicleUtils;
+import picocli.CommandLine;
+
+import javax.annotation.Nullable;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Run the Lausitz scenario including a regional DRT service.
+ * All necessary configs will be made in this class.
+ */
+public final class RunLausitzDrtScenario extends MATSimApplication {
+ @CommandLine.Option(names = "--drt-shp", description = "Path to shp file for adding drt not network links as an allowed mode.", defaultValue = "./input/shp/lausitz.shp")
+ private String drtAreaShp;
+
+ private final LausitzScenario baseScenario = new LausitzScenario();
+
+ public RunLausitzDrtScenario() {
+// TODO: change this back to "automagic" version loading of config
+// super(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION));
+ super("input/v1.1/lausitz-v1.1-10pct.config.xml");
+ }
+
+ public static void main(String[] args) {
+ MATSimApplication.run(RunLausitzDrtScenario.class, args);
+ }
+
+ @Nullable
+ @Override
+ protected Config prepareConfig(Config config) {
+// TODO: have a look in config.xml if there is more configs to be adapted to make it "ready" for drt -> do this here
+// TODO: add drt stops / shp file here?! OR create stops / shp in code?!
+// TODO: add drt to mdoeparams, add as network mode, add as main mode? add to SMC, add to scoring params?!
+// TODO: add drt speedup params, add drt fare params?!
+
+// TODO: talk to CL about whether to use new drt approach (see kelheim) or not.. and how to implement it
+
+// apply all config changes from base scenario class
+ baseScenario.prepareConfig(config);
+
+ DvrpConfigGroup dvrpConfigGroup = ConfigUtils.addOrGetModule(config, DvrpConfigGroup.class);
+ dvrpConfigGroup.networkModes = Set.of(TransportMode.drt);
+
+ MultiModeDrtConfigGroup multiModeDrtConfigGroup = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class);
+
+ if (multiModeDrtConfigGroup.getModalElements().isEmpty()) {
+ DrtConfigGroup drtConfigGroup = new DrtConfigGroup();
+ drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.stopbased;
+ drtConfigGroup.stopDuration = 60.;
+// TODO: shp files have been created and are located on sjhared svn
+ drtConfigGroup.transitStopFile = "";
+
+// optimization params now are in its own paramSet, hence the below lines
+ DrtOptimizationConstraintsParams optimizationConstraints = new DrtOptimizationConstraintsParams();
+ DefaultDrtOptimizationConstraintsSet optimizationConstraintsSet = new DefaultDrtOptimizationConstraintsSet();
+ optimizationConstraintsSet.maxWaitTime = 1200.;
+ optimizationConstraintsSet.maxTravelTimeBeta = 1200.;
+ optimizationConstraintsSet.maxTravelTimeAlpha = 1.5;
+ optimizationConstraints.addParameterSet(optimizationConstraintsSet);
+ drtConfigGroup.addParameterSet(optimizationConstraints);
+ drtConfigGroup.addParameterSet(new ExtensiveInsertionSearchParams());
+// TODO: talk to KN whether to put in fare params here.. logic could be: we assume that everybody has a Deutschlandticket so no fare at all is charged?!
+// this may draw more than the costumer, who want to take the train in Ruhland?! So maybe it makes sense to apply a baseFare and give it back to the agents after the sim via person money event?
+// OR just put in drt fare via scoring mode params
+ multiModeDrtConfigGroup.addParameterSet(drtConfigGroup);
+ }
+
+// this is needed for DynAgents for DVRP
+ config.qsim().setSimStarttimeInterpretation(QSimConfigGroup.StarttimeInterpretation.onlyUseStarttime);
+
+ ScoringConfigGroup scoringConfigGroup = ConfigUtils.addOrGetModule(config, ScoringConfigGroup.class);
+
+ if (!scoringConfigGroup.getModes().containsKey(TransportMode.drt)) {
+// TODO: talk to KN about this ASC value. Either set it equal to PT or 0??
+// add mode params for drt if missing and set ASC + marg utility of traveling = 0
+ scoringConfigGroup.addModeParams(new ScoringConfigGroup.ModeParams(TransportMode.drt)
+ .setConstant(scoringConfigGroup.getModes().get(TransportMode.pt).getConstant())
+ .setMarginalUtilityOfTraveling(-0.));
+ }
+
+ SubtourModeChoiceConfigGroup smc = ConfigUtils.addOrGetModule(config, SubtourModeChoiceConfigGroup.class);
+
+ if (String.join(",", smc.getModes()).contains(TransportMode.drt)) {
+ String[] modes = Arrays.copyOf(smc.getModes(), smc.getModes().length + 1);
+ modes[modes.length - 1] = TransportMode.drt;
+
+ smc.setModes(modes);
+ }
+
+// creates a drt staging activity and adds it to the scoring params
+ DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfigGroup, config.scoring(), config.routing());
+
+ return config;
+ }
+
+ @Override
+ protected void prepareScenario(Scenario scenario) {
+// TODO
+
+// apply all scenario changes from base scenario class
+ baseScenario.prepareScenario(scenario);
+
+// drt route factory has to be added as factory for drt routes, as there were no drt routes before.
+ scenario.getPopulation()
+ .getFactory()
+ .getRouteFactories()
+ .setRouteFactory(DrtRoute.class, new DrtRouteFactory());
+
+// add drt as allowed mode for whole Lausitz region
+ Geometry geometry = new ShpOptions(drtAreaShp, null, null).getGeometry();
+
+ for (Link link : scenario.getNetwork().getLinks().values()) {
+ if (link.getAllowedModes().contains(TransportMode.car)) {
+ boolean isInside = MGC.coord2Point(link.getFromNode().getCoord()).within(geometry) ||
+ MGC.coord2Point(link.getToNode().getCoord()).within(geometry);
+
+ if (isInside) {
+ Set modes = new HashSet<>();
+ modes.add(TransportMode.drt);
+ modes.addAll(link.getAllowedModes());
+ link.setAllowedModes(modes);
+ }
+ }
+ }
+ new MultimodalNetworkCleaner(scenario.getNetwork()).run(Set.of(TransportMode.drt));
+
+ Id drtTypeId = Id.create(TransportMode.drt, VehicleType.class);
+
+// add drt veh type if not already existing
+ if (!scenario.getVehicles().getVehicleTypes().containsKey(drtTypeId)) {
+// drt veh type = car veh type, but capacity 1 passenger
+ VehicleType drtType = VehicleUtils.createVehicleType(drtTypeId);
+
+ VehicleUtils.copyFromTo(scenario.getVehicles().getVehicleTypes().get(Id.create(TransportMode.car, VehicleType.class)), drtType);
+ drtType.setDescription("drt vehicle copied from car vehicle type");
+ VehicleCapacity capacity = drtType.getCapacity();
+ capacity.setSeats(1);
+
+ scenario.getVehicles().addVehicleType(drtType);
+ }
+
+//TODO: is the following if clause needed when using the DRT Estimator?!
+// TODO: @CL where does the estimator draw its vehicles from? Are vehicle types even needed?
+ // if there are no vehicles of above type: add some
+ if (scenario.getVehicles().getVehicles().values().stream().filter(v -> v.getType().getId().equals(drtTypeId)).toList().isEmpty()) {
+
+ for (int i = 1; i <= 10; i++) {
+ Vehicle vehicle = VehicleUtils.createVehicle(Id.createVehicleId(TransportMode.drt + "_" + i), scenario.getVehicles().getVehicleTypes().get(drtTypeId));
+ vehicle.getAttributes().putAttribute("dvrpMode", TransportMode.drt);
+// TODO: put linkId
+ vehicle.getAttributes().putAttribute("startLink", "ABC");
+ vehicle.getAttributes().putAttribute("serviceBeginTime", 0.);
+ vehicle.getAttributes().putAttribute("serviceEndTime", 86400.);
+ scenario.getVehicles().addVehicle(vehicle);
+ }
+
+
+ }
+ }
+
+ @Override
+ protected void prepareControler(Controler controler) {
+// TODO
+
+// apply all controller changes from base scenario class
+ baseScenario.prepareControler(controler);
+
+ controler.addOverridingModule(new DvrpModule());
+ controler.addOverridingModule(new MultiModeDrtModule());
+
+// the following cannot be "experts only" (like requested from KN) because without it DRT would not work
+// here, the DynActivityEngine, PreplanningEngine + DvrpModule for each drt mode are added to the qsim components
+// this is necessary for drt / dvrp to work!
+ controler.configureQSimComponents(DvrpQSimComponents.activateAllModes(ConfigUtils.addOrGetModule(controler.getConfig(), MultiModeDrtConfigGroup.class)));
+
+
+
+ }
+}
diff --git a/src/main/java/org/matsim/run/RunLausitzPtScenario.java b/src/main/java/org/matsim/run/RunLausitzPtScenario.java
new file mode 100644
index 0000000..f38b3cf
--- /dev/null
+++ b/src/main/java/org/matsim/run/RunLausitzPtScenario.java
@@ -0,0 +1,212 @@
+package org.matsim.run;
+
+import org.matsim.api.core.v01.Coord;
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.Scenario;
+import org.matsim.api.core.v01.TransportMode;
+import org.matsim.api.core.v01.network.Link;
+import org.matsim.api.core.v01.network.Network;
+import org.matsim.api.core.v01.network.Node;
+import org.matsim.application.MATSimApplication;
+import org.matsim.core.config.Config;
+import org.matsim.core.controler.Controler;
+import org.matsim.core.network.NetworkUtils;
+import org.matsim.core.population.routes.RouteUtils;
+import org.matsim.pt.transitSchedule.api.*;
+import org.matsim.vehicles.Vehicle;
+import org.matsim.vehicles.VehicleType;
+import org.matsim.vehicles.Vehicles;
+
+import javax.annotation.Nullable;
+import java.util.*;
+
+/**
+ * Run the Lausitz scenario including a new regional rail transit line between hoyerswerda and cottbus.
+ * All necessary configs will be made in this class.
+ */
+public class RunLausitzPtScenario extends MATSimApplication {
+
+ private final LausitzScenario baseScenario = new LausitzScenario();
+
+ public RunLausitzPtScenario(@Nullable Config config) {
+ super(config);
+ }
+
+ public RunLausitzPtScenario() {
+ super(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION));
+ }
+
+ public static void main(String[] args) {
+ MATSimApplication.run(RunLausitzPtScenario.class, args);
+ }
+
+ @Nullable
+ @Override
+ protected Config prepareConfig(Config config) {
+ // apply all config changes from base scenario class
+ baseScenario.prepareConfig(config);
+
+ return config;
+ }
+
+ @Override
+ protected void prepareScenario(Scenario scenario) {
+ // apply all scenario changes from base scenario class
+ baseScenario.prepareScenario(scenario);
+
+// pt stops are basically nodes, BUT are assigned to links
+// each pt stop is assigned a circle link to and from the same node.
+// the first "real" link has the to and from node from the circle link as fromNode
+
+// create pt network nodes
+ Node hoyerswerda = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_regio_159285.8"), new Coord(863538.8869276098, 5711014.921688189));
+ Node hoyerswerdaNeustadt = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_regio_135278.2"), new Coord(865993.0603089998, 5710758.211643816));
+ Node spremberg = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_regio_315415.7"), new Coord(873850.5174500551,5727598.197541567));
+ Node bagenz = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_short_2726.2"), new Coord(875299.1792959593,5736556.872374279));
+ Node neuhausen = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_short_2476.2"), new Coord(874002.1110680653, 5740162.957866353));
+ Node cottbus = NetworkUtils.createAndAddNode(scenario.getNetwork(), Id.createNodeId("pt_short_5453.5"), new Coord(867315.8562388942, 5746748.406057102));
+
+// create links first direction
+// for speed and length deduction see internal documentation on drive
+ Link startLink1 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_0"), hoyerswerda, hoyerswerda, scenario.getNetwork(), 50., 0.1, 100000.0, 1.0);
+ Link link1 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_1"), hoyerswerda, hoyerswerdaNeustadt, scenario.getNetwork(), 2600., 2600./3*60, 100000.0, 1.0);
+ Link link2 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_2"), hoyerswerdaNeustadt, spremberg, scenario.getNetwork(), 30000., 20., 100000.0, 1.0);
+ Link link3 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_3"), spremberg, bagenz, scenario.getNetwork(), 10000., 10000./7*60, 100000.0, 1.0);
+ Link link4 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_4"), bagenz, neuhausen, scenario.getNetwork(), 4000., 4000./4*60, 100000.0, 1.0);
+ Link link5 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_5"), neuhausen, cottbus, scenario.getNetwork(), 10000., 10000./7*60, 100000.0, 1.0);
+
+// create links second direction
+ Link startLink2 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_6"), cottbus, cottbus, scenario.getNetwork(), 50., 0.1, 100000.0, 1.0);
+ Link link6 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_7"), cottbus, neuhausen, scenario.getNetwork(), 10000., 10000./7*60, 100000.0, 1.0);
+ Link link7 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_8"), neuhausen, bagenz, scenario.getNetwork(), 4000., 4000./4*60, 100000.0, 1.0);
+ Link link8 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_9"), bagenz, spremberg, scenario.getNetwork(), 10000., 10000./7*60, 100000.0, 1.0);
+ Link link9 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_10"), spremberg, hoyerswerdaNeustadt, scenario.getNetwork(), 30000., 20., 100000.0, 1.0);
+ Link link10 = NetworkUtils.createLink(Id.createLinkId("pt_vsp_11"), hoyerswerdaNeustadt, hoyerswerda, scenario.getNetwork(), 2600., 2600./3*60, 100000.0, 1.0);
+
+ TransitSchedule schedule = scenario.getTransitSchedule();
+ TransitScheduleFactory fac = schedule.getFactory();
+ TransitLine line = fac.createTransitLine(Id.create("RE-VSP1", TransitLine.class));
+
+ List transitInfoList = new ArrayList<>();
+
+// map with all new pt links and their respective travel time
+ Map travelTimes = new HashMap<>();
+ travelTimes.put(startLink1, startLink1.getLength() / startLink1.getFreespeed());
+ travelTimes.put(startLink2, startLink2.getLength() / startLink2.getFreespeed());
+ travelTimes.put(link1, link1.getLength() / link1.getFreespeed());
+ travelTimes.put(link2, link2.getLength() / link2.getFreespeed());
+ travelTimes.put(link3, link3.getLength() / link3.getFreespeed());
+ travelTimes.put(link4, link4.getLength() / link4.getFreespeed());
+ travelTimes.put(link5, link5.getLength() / link5.getFreespeed());
+ travelTimes.put(link6, link6.getLength() / link6.getFreespeed());
+ travelTimes.put(link7, link7.getLength() / link7.getFreespeed());
+ travelTimes.put(link8, link8.getLength() / link8.getFreespeed());
+ travelTimes.put(link9, link9.getLength() / link9.getFreespeed());
+ travelTimes.put(link10, link10.getLength() / link10.getFreespeed());
+
+ int i = 0;
+ for (List linkList : List.of(List.of(startLink1, link1, link2, link3, link4, link5), List.of(startLink2, link6, link7, link8, link9, link10))) {
+ transitInfoList.add(configureTransitStops(linkList, scenario.getNetwork(), schedule, fac, i, travelTimes));
+ i++;
+ }
+
+ int j = 0;
+ for (TransitInfo info : transitInfoList) {
+ TransitRoute route = fac.createTransitRoute(Id.create(line.getId() + "_" + j, TransitRoute.class), RouteUtils.createNetworkRoute(info.links), info.transitStops, "rail");
+
+// transit line should depart every hour to and from hoyerswerda
+// transit lines cottbus - spremberg / - ruhland operate 4/5am - 11pm -> pick similar frequency, start and end of operation interval
+
+// create departures for each route
+ List departures;
+ if (j == 0) {
+// hoyerswerda -> cottbus possible connection to re10/43 frankfurt(oder) (every hour at :02), to re2 berlin (every hour at :04)
+ departures = createDepartures(fac, info.travelTime, route, 2);
+ } else {
+// cottbus -> hoyerswerda possible connection to re15 dresden (every hour at :33) and with 1 connection to Leipzig
+ departures = createDepartures(fac, info.travelTime, route, 33);
+ }
+ // create transit vehicle for each departure and add to transit vehicles
+ departures.forEach(d -> {
+ Vehicles vehicles = scenario.getTransitVehicles();
+ VehicleType regio = vehicles.getVehicleTypes().get(Id.create("RE_RB_veh_type", VehicleType.class));
+ Vehicle vehicle = vehicles.getFactory().createVehicle(Id.createVehicleId(d.getId().toString()), regio);
+ vehicles.addVehicle(vehicle);
+ d.setVehicleId(vehicle.getId());
+ route.addDeparture(d);
+ });
+ line.addRoute(route);
+
+ j++;
+ }
+ schedule.addTransitLine(line);
+ }
+
+ @Override
+ protected void prepareControler(Controler controler) {
+ // apply all controller changes from base scenario class
+ baseScenario.prepareControler(controler);
+// TODO: add potential new Listeners here
+// maybe a special controler for the new pt line would be handy?!
+ }
+ private TransitInfo configureTransitStops(List linkList, Network network, TransitSchedule schedule, TransitScheduleFactory fac, int count, Map travelTimes) {
+ List> links = new ArrayList<>();
+ List stops = new ArrayList<>();
+
+ double travelTime = 0.;
+
+ for (Link l : linkList) {
+ l.setAllowedModes(Set.of(TransportMode.pt));
+ network.addLink(l);
+
+ Node toNode = l.getToNode();
+
+// create stop with to node id minus prefix pt_
+ TransitStopFacility stopFac = fac.createTransitStopFacility(Id.create(toNode.getId().toString().substring(toNode.getId().toString().indexOf("pt_")
+ + "pt_".length()) + "_" + count, TransitStopFacility.class), toNode.getCoord(), false);
+ stopFac.setLinkId(l.getId());
+ schedule.addStopFacility(stopFac);
+
+ double arrivalDelay = 0.;
+ double departureDelay = 0.;
+
+ if (!l.getId().toString().equals("pt_vsp_0") && !l.getId().toString().equals("pt_vsp_6")) {
+// delay for fictive start links = 0, else see below
+ travelTime += travelTimes.get(l);
+ arrivalDelay = travelTime;
+ departureDelay = arrivalDelay + 60;
+ }
+
+ TransitRouteStop stop = fac.createTransitRouteStop(stopFac, arrivalDelay, departureDelay);
+ stop.setAwaitDepartureTime(true);
+ stops.add(stop);
+ links.add(l.getId());
+ }
+ return new TransitInfo(links, stops, travelTime);
+ }
+
+ private List createDepartures(TransitScheduleFactory fac, double travelTime, TransitRoute route, int connectionTrainDeparture) {
+ List departures = new ArrayList<>();
+
+ for (int k = 0; k <= 24; k++) {
+ int arrival = (k * 60 + connectionTrainDeparture - 10) * 60;
+
+// no connection before 4am
+ if (arrival < 4 * 3600 || arrival > 24 * 3600) {
+ continue;
+ }
+
+// departure time = arrival - (travelTime - 1min per intermediate stop for entering / leaving passengers)
+// departure id = route id + prefix pt_ and suffix consecutive number
+ double departureTime = arrival - (travelTime + (route.getStops().size() - 2) * 60.);
+ Departure departure = fac.createDeparture(Id.create("pt_" + route.getId() + "_" + k, Departure.class), departureTime);
+ departures.add(departure);
+ }
+
+ return departures;
+ }
+
+ private record TransitInfo(List> links, List transitStops, Double travelTime) {
+
+ }
+}
diff --git a/src/main/java/org/matsim/run/analysis/CommunityFilter.java b/src/main/java/org/matsim/run/analysis/CommunityFilter.java
new file mode 100644
index 0000000..1bd1b90
--- /dev/null
+++ b/src/main/java/org/matsim/run/analysis/CommunityFilter.java
@@ -0,0 +1,80 @@
+package org.matsim.run.analysis;
+
+import org.apache.commons.csv.CSVPrinter;
+import org.geotools.api.feature.simple.SimpleFeature;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.Point;
+import org.matsim.application.MATSimAppCommand;
+import org.matsim.application.options.CsvOptions;
+import org.matsim.core.utils.collections.Tuple;
+import org.matsim.core.utils.gis.GeoFileReader;
+import picocli.CommandLine;
+
+import java.nio.file.Path;
+import java.util.*;
+
+@CommandLine.Command(name = "community-filter", description = "creates a csv with commuity keys within shape")
+public class CommunityFilter implements MATSimAppCommand {
+
+ @CommandLine.Option(names = "--community-shp", description = "path to VG5000_GEM.shp", required = true)
+ private static Path communityShapePath;
+
+ @CommandLine.Option(names = "--dilution-area", description = "path to area-of-interest-shape file", required = true)
+ private static Path dilutionAreaShapePath;
+
+ @CommandLine.Option(names = "--output", description = "output csv filepath", required = true)
+ private static Path output;
+
+ @CommandLine.Mixin
+ CsvOptions csvOptions = new CsvOptions();
+ private final Map> filtered = new HashMap<>();
+
+ public static void main(String[] args) {
+ new CommunityFilter().execute(args);
+ }
+
+ @Override
+ public Integer call() throws Exception {
+
+ Collection communities = readShapeFile(communityShapePath);
+ Collection dilutionArea = readShapeFile(dilutionAreaShapePath);
+
+ List geometries = dilutionArea.stream().map(feature -> (Geometry) feature.getDefaultGeometry()).toList();
+
+ for(var community: communities){
+
+ String attribute = (String) community.getAttribute("ARS");
+
+ if(geometries.stream()
+ .anyMatch(geometry -> geometry.covers((Geometry) community.getDefaultGeometry()))){
+
+ Point centroid = ((Geometry) community.getDefaultGeometry()).getCentroid();
+ Tuple coordinates = Tuple.of(centroid.getX(), centroid.getY());
+
+ filtered.put(attribute, coordinates);
+ }
+
+ }
+
+ try (CSVPrinter printer = csvOptions.createPrinter(output)) {
+ printer.print("ars");
+ printer.print("x");
+ printer.print("y");
+ printer.println();
+
+ for (Map.Entry> entry : filtered.entrySet()) {
+ printer.print(entry.getKey());
+ printer.print(entry.getValue().getFirst());
+ printer.print(entry.getValue().getSecond());
+ printer.println();
+ }
+ }
+
+ return 0;
+ }
+
+ private static Collection readShapeFile(Path filepath){
+
+ return GeoFileReader.getAllFeatures(filepath.toString());
+ }
+}
diff --git a/src/main/java/org/matsim/run/analysis/DistanceMatrix.java b/src/main/java/org/matsim/run/analysis/DistanceMatrix.java
new file mode 100644
index 0000000..3be4a0d
--- /dev/null
+++ b/src/main/java/org/matsim/run/analysis/DistanceMatrix.java
@@ -0,0 +1,108 @@
+package org.matsim.run.analysis;
+
+import org.apache.commons.csv.CSVPrinter;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.geotools.api.feature.simple.SimpleFeature;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.Point;
+import org.matsim.api.core.v01.Coord;
+import org.matsim.application.MATSimAppCommand;
+import org.matsim.application.options.CsvOptions;
+import org.matsim.application.options.ShpOptions;
+import org.matsim.core.utils.geometry.CoordUtils;
+import org.matsim.core.utils.geometry.geotools.MGC;
+import org.matsim.core.utils.gis.GeoFileReader;
+import picocli.CommandLine;
+
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Predicate;
+
+@CommandLine.Command(name = "distance-matrix", description = "creates a csv with commuity keys within shape")
+public class DistanceMatrix implements MATSimAppCommand{
+
+ @CommandLine.Option(names = "--output", description = "output csv filepath", required = true)
+ private static Path output;
+
+ @CommandLine.Option(names = "--dilution-area", description = "shape to filter zones", required = false)
+ private static Path dilutionArea;
+
+ @CommandLine.Mixin
+ CsvOptions csvOptions = new CsvOptions();
+
+ @CommandLine.Mixin
+ ShpOptions shp = new ShpOptions();
+
+ private final List distances = new ArrayList<>();
+ private static final Logger logger = LogManager.getLogger(DistanceMatrix.class);
+
+ public static void main(String[] args) {
+ new DistanceMatrix().execute(args);
+ }
+
+ @Override
+ public Integer call() throws Exception {
+
+ logger.info("Read features.");
+ List communities = shp.readFeatures();
+
+ //to prevent RuntimeExceptions
+ ArrayList copy = new ArrayList<>(communities);
+
+ Predicate filter = getFilter(dilutionArea);
+
+ logger.info("Calculate distance matrix.");
+ String delimiter = csvOptions.getFormat().getDelimiterString();
+ for(var community: communities){
+
+ if(!filter.test((Geometry) community.getDefaultGeometry()))
+ continue;
+ String nameFrom = (String) community.getAttribute("ARS");
+ Point centroid = ((Geometry) community.getDefaultGeometry()).getCentroid();
+ Coord from = MGC.point2Coord(centroid);
+ for(var target: copy){
+
+ String nameTo = (String) target.getAttribute("ARS");
+
+ Point centroid2 = ((Geometry) target.getDefaultGeometry()).getCentroid();
+ Coord to = MGC.point2Coord(centroid2);
+ double distance = CoordUtils.calcEuclideanDistance(from, to);
+
+ String distanceString = String.valueOf(distance).replace('.', ',');
+
+ distances.add(nameFrom + delimiter + nameTo + delimiter + distanceString);
+ }
+ }
+
+ logger.info("Print results to {}", output);
+ try (CSVPrinter printer = csvOptions.createPrinter(output)) {
+ printer.print("from");
+ printer.print("to");
+ printer.print("distance");
+ printer.println();
+
+ for (String entry : distances) {
+ for (String col : entry.split(csvOptions.getFormat().getDelimiterString()))
+ printer.print(col);
+ printer.println();
+ }
+ }
+
+ logger.info("Done!");
+ return 0;
+ }
+
+ private Predicate getFilter(Path path){
+
+ if(path == null)
+ return community -> true;
+
+ List geometries = GeoFileReader.getAllFeatures(path.toString()).stream()
+ .map(feature -> (Geometry) feature.getDefaultGeometry())
+ .toList();
+
+ return community -> geometries.stream().anyMatch(geometry -> geometry.covers(community));
+ }
+}
diff --git a/src/main/java/org/matsim/run/prepare/AdaptFreightTrafficToDetailedModes.java b/src/main/java/org/matsim/run/prepare/AdaptFreightTrafficToDetailedModes.java
new file mode 100644
index 0000000..259add6
--- /dev/null
+++ b/src/main/java/org/matsim/run/prepare/AdaptFreightTrafficToDetailedModes.java
@@ -0,0 +1,131 @@
+package org.matsim.run.prepare;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.jetbrains.annotations.NotNull;
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.TransportMode;
+import org.matsim.api.core.v01.population.Leg;
+import org.matsim.api.core.v01.population.Person;
+import org.matsim.api.core.v01.population.Plan;
+import org.matsim.api.core.v01.population.Population;
+import org.matsim.application.MATSimAppCommand;
+import org.matsim.core.config.ConfigUtils;
+import org.matsim.core.population.PopulationUtils;
+import org.matsim.core.router.TripStructureUtils;
+import org.matsim.vehicles.VehicleType;
+import org.matsim.vehicles.VehicleUtils;
+import picocli.CommandLine;
+
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.Set;
+
+import static org.matsim.run.LausitzScenario.*;
+
+@CommandLine.Command(
+ name = "adapt-freight-plans",
+ description = "Adapt all freight plans (including small scall commercial traffic) to new standards."
+)
+public class AdaptFreightTrafficToDetailedModes implements MATSimAppCommand {
+
+ Logger log = LogManager.getLogger(AdaptFreightTrafficToDetailedModes.class);
+
+ @CommandLine.Parameters(arity = "1", paramLabel = "INPUT", description = "Path to input population")
+ private Path input;
+
+ @CommandLine.Option(names = "--output", description = "Path to output population", required = true)
+ private Path output;
+
+ public static void main(String[] args) {
+ new AdaptFreightTrafficToDetailedModes().execute(args);
+ }
+
+ @Override
+ public Integer call() throws Exception {
+
+ Population population = PopulationUtils.readPopulation(input.toString());
+
+ for (Person person : population.getPersons().values()) {
+ if (PopulationUtils.getSubpopulation(person).equals("freight")) {
+ adaptFreightPerson(person);
+ } else if (PopulationUtils.getSubpopulation(person).equals(FREIGHT)) {
+ for (Plan plan : person.getPlans()) {
+ for (Leg leg : TripStructureUtils.getLegs(plan)) {
+ if (!leg.getMode().equals(FREIGHT)) {
+ leg.setMode(FREIGHT);
+ }
+ }
+ }
+ }
+
+ if (PopulationUtils.getSubpopulation(person).contains("commercialPersonTraffic") ||
+ PopulationUtils.getSubpopulation(person).contains("goodsTraffic")) {
+
+ Map> types = VehicleUtils.getVehicleTypes(person);
+
+ for (Plan plan : person.getPlans()) {
+ for (Leg leg : TripStructureUtils.getLegs(plan)) {
+ if (leg.getMode().equals(TransportMode.truck)) {
+ String vehicleTypes = person.getAttributes().getAttribute("vehicleTypes").toString();
+ if (vehicleTypes.contains("light8t")) {
+ leg.setMode(LIGHT_MODE);
+ } else if (vehicleTypes.contains("medium18t")) {
+ leg.setMode(MEDIUM_MODE);
+ } else if (vehicleTypes.contains("heavy40t")) {
+ leg.setMode(HEAVY_MODE);
+ } else {
+ log.error("Unknown vehicle type in: {}", vehicleTypes);
+ return 2;
+ }
+ } else if (leg.getMode().equals(TransportMode.car)) {
+// TODO
+ }
+ }
+ }
+
+ for (Map.Entry> entry : types.entrySet()) {
+ if (Set.of(HEAVY_MODE, MEDIUM_MODE, LIGHT_MODE).contains(entry.getKey())) {
+ types.put(entry.getKey(), Id.create(entry.getKey(), VehicleType.class));
+ }
+ }
+ }
+ }
+
+
+
+
+ PopulationUtils.writePopulation(population, output.toString());
+
+ return 0;
+ }
+
+ private static void adaptFreightPerson(Person person) {
+ // rename freight subpop to longDistanceFreight
+ person.getAttributes().removeAttribute("subpopulation");
+ person.getAttributes().putAttribute("subpopulation", FREIGHT);
+
+// rename each leg mode freight to longDistanceFreight
+ for (Plan plan : person.getPlans()) {
+ for (Leg leg : TripStructureUtils.getLegs(plan)) {
+ if (leg.getMode().equals("freight")) {
+ leg.setMode(FREIGHT);
+ }
+ }
+ }
+ }
+
+ private static @NotNull Population removeSmallScaleCommercialTrafficFromPopulation(Population population) {
+ Population newPop = PopulationUtils.createPopulation(ConfigUtils.createConfig());
+
+ for (Person person : population.getPersons().values()) {
+ if (PopulationUtils.getSubpopulation(person).contains("commercialPersonTraffic")
+ || PopulationUtils.getSubpopulation(person).contains("goodsTraffic")) {
+// do not add commercial or goods traffic from RE
+ continue;
+ }
+ newPop.addPerson(person);
+ }
+ return newPop;
+ }
+}
diff --git a/src/main/java/org/matsim/run/prepare/PrepareNetwork.java b/src/main/java/org/matsim/run/prepare/PrepareNetwork.java
new file mode 100644
index 0000000..bb5f89f
--- /dev/null
+++ b/src/main/java/org/matsim/run/prepare/PrepareNetwork.java
@@ -0,0 +1,87 @@
+package org.matsim.run.prepare;
+
+import com.google.common.collect.Sets;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+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.application.MATSimAppCommand;
+import org.matsim.contrib.emissions.HbefaRoadTypeMapping;
+import org.matsim.contrib.emissions.OsmHbefaMapping;
+import org.matsim.core.network.NetworkUtils;
+import org.matsim.core.network.algorithms.MultimodalNetworkCleaner;
+import picocli.CommandLine;
+
+import java.util.Set;
+
+import static org.matsim.run.LausitzScenario.*;
+
+@CommandLine.Command(
+ name = "network",
+ description = "Prepare network / link attributes."
+)
+public class PrepareNetwork implements MATSimAppCommand {
+
+ private static final Logger log = LogManager.getLogger(PrepareNetwork.class);
+
+ @CommandLine.Option(names = "--network", description = "Path to network file", required = true)
+ private String networkFile;
+
+ @CommandLine.Option(names = "--output", description = "Output path of the prepared network", required = true)
+ private String outputPath;
+
+ public static void main(String[] args) {
+ new PrepareNetwork().execute(args);
+ }
+
+ @Override
+ public Integer call() throws Exception {
+
+ Network network = NetworkUtils.readNetwork(networkFile);
+
+ prepareFreightNetwork(network);
+ prepareEmissionsAttributes(network);
+
+ NetworkUtils.writeNetwork(network, outputPath);
+
+ return 0;
+ }
+
+ /**
+ * prepare link attributes for freight and truck as allowed modes together with car.
+ */
+ public static void prepareFreightNetwork(Network network) {
+ int linkCount = 0;
+
+ for (Link link : network.getLinks().values()) {
+ Set modes = link.getAllowedModes();
+
+ // allow freight traffic together with cars
+ if (modes.contains(TransportMode.car)) {
+ Set newModes = Sets.newHashSet(modes);
+
+ newModes.add(HEAVY_MODE);
+ newModes.add(MEDIUM_MODE);
+ newModes.add(LIGHT_MODE);
+ newModes.add(FREIGHT);
+
+ link.setAllowedModes(newModes);
+ linkCount++;
+ }
+ }
+
+ log.info("For {} links {}, {}, {} and {} has been added as an allowed mode.", linkCount, HEAVY_MODE, MEDIUM_MODE, LIGHT_MODE, FREIGHT);
+
+ new MultimodalNetworkCleaner(network).run(Set.of(HEAVY_MODE, MEDIUM_MODE, LIGHT_MODE, FREIGHT));
+ }
+
+ /**
+ * add hbefa link attributes.
+ */
+ public static void prepareEmissionsAttributes(Network network) {
+// do not use VspHbefaRoadTypeMapping() as it results in almost every road to mapped to "highway"!
+ HbefaRoadTypeMapping roadTypeMapping = OsmHbefaMapping.build();
+ roadTypeMapping.addHbefaMappings(network);
+ }
+}
diff --git a/src/main/java/org/matsim/run/prepare/PreparePopulation.java b/src/main/java/org/matsim/run/prepare/PreparePopulation.java
index 01a70c6..f3cbec0 100644
--- a/src/main/java/org/matsim/run/prepare/PreparePopulation.java
+++ b/src/main/java/org/matsim/run/prepare/PreparePopulation.java
@@ -79,13 +79,9 @@ private void prepare(Person person) {
// Set car availability to "never" for agents below 18 years old
// Standardize the attribute "age"
String avail = "always";
- Object age = person.getAttributes().getAttribute("microm:modeled:age");
- if (age != null) {
- PersonUtils.setAge(person, (int) age);
- person.getAttributes().removeAttribute("microm:modeled:age");
- if ((int) age < 18) {
- avail = "never";
- }
+ Object age = person.getAttributes().getAttribute("age");
+ if (age != null && (int) age < 18) {
+ avail = "never";
}
// Replace with standardized car availability attribute
@@ -93,14 +89,15 @@ private void prepare(Person person) {
person.getAttributes().removeAttribute("sim_carAvailability");
// Standardize the attribute "sex"
- Object sex = person.getAttributes().getAttribute("microm:modeled:sex");
+ Object sex = person.getAttributes().getAttribute("gender");
if (sex != null) {
PersonUtils.setSex(person, (String) sex);
- person.getAttributes().removeAttribute("microm:modeled:sex");
+ person.getAttributes().removeAttribute("gender");
}
// Assign income to person (skip the freight agents)
- if (person.getId().toString().startsWith("freight")) {
+ if (person.getId().toString().startsWith("freight") || person.getId().toString().startsWith("commercial")
+ || person.getId().toString().startsWith("goods")) {
return;
}
diff --git a/src/main/python/calibrate.py b/src/main/python/calibrate.py
index 3ffcdf0..1add17e 100644
--- a/src/main/python/calibrate.py
+++ b/src/main/python/calibrate.py
@@ -33,7 +33,7 @@
"ride": -0.76
}
-# Based on MiD 2017, filtered on Lausitz region
+# Based on MiD 2017, filtered on Lausitz region (see create_ref.py)
target = {
"walk": 0.199819,
"bike": 0.116362,
@@ -47,7 +47,7 @@
def filter_persons(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")
+ df = gpd.sjoin(persons.set_crs("EPSG:25832"), region, how="inner", predicate="intersects")
print("Filtered %s persons" % len(df))
@@ -65,7 +65,7 @@ def filter_modes(df):
"calib",
ASCCalibrator(modes, initial, target, lr=utils.linear_scheduler(start=0.3, interval=12)),
"matsim-lausitz-1.x-SNAPSHOT-20c8ab3.jar",
- "../input/v1.0/lausitz-v1.0-25pct.config.xml",
+ "../input/v1.1/lausitz-v1.1-10pct.config.xml",
args="--25pct",
jvm_args="-Xmx60G -Xmx60G -XX:+AlwaysPreTouch -XX:+UseParallelGC",
transform_persons=filter_persons, transform_trips=filter_modes,
diff --git a/src/main/python/create_ref.py b/src/main/python/create_ref.py
index a440f6f..e46f19b 100644
--- a/src/main/python/create_ref.py
+++ b/src/main/python/create_ref.py
@@ -2,38 +2,55 @@
# -*- coding: utf-8 -*-
import geopandas as gpd
+import numpy as np
import pandas as pd
from matsim.scenariogen.data import run_create_ref_data
-from matsim.scenariogen.data.preparation import calc_needed_short_distance_trips
+from matsim.scenariogen.data.preparation import calc_needed_short_distance_trips, cut
CRS = "EPSG:25832"
def person_filter(df):
+ """ Filter person that are relevant for the calibration."""
+
df = gpd.GeoDataFrame(df, geometry=gpd.GeoSeries.from_wkt(df.geom, crs="EPSG:4326").to_crs(CRS))
df = gpd.sjoin(df, region, how="inner", predicate="intersects")
+ # Groups will be shown on the dashboard
+ df["age"] = cut(df.age, [0, 12, 18, 25, 35, 66, np.inf])
+
+ # Only weekdays are considered, with persons present in their home region
return df[df.present_on_day & (df.reporting_day <= 5)]
def trip_filter(df):
- # Other modes are ignored in the total share
+ # All modes, expect for "other" are considered
return df[df.main_mode != "other"]
if __name__ == "__main__":
+
+ # Defines the Lausitz region
region = gpd.read_file("../../../../shared-svn/projects/DiTriMo/data/shp/lausitz.shp").to_crs(CRS)
- persons, trips, share = run_create_ref_data.create("/Volumes/Untitled/B3_Lokal-Datensatzpaket/CSV",
- person_filter, trip_filter,
- run_create_ref_data.InvalidHandling.REMOVE_TRIPS)
+ # This contains the path to the MiD 2017 data with the highest resolution
+ # See https://daten.clearingstelle-verkehr.de/279/ for more information, the data is not included in this repository
+ r = run_create_ref_data.create(
+ # this is the MID2017 dataset, it is not available in svn as it has to be encrypted
+ "/Volumes/Untitled/B3_Lokal-Datensatzpaket/CSV",
+ person_filter, trip_filter,
+ run_create_ref_data.InvalidHandling.REMOVE_TRIPS,
+ ref_groups=["age", "economic_status"]
+ )
+
+ print("Filtered %s persons" % len(r.persons))
+ print("Filtered %s trips" % len(r.trips))
- print("Filtered %s persons" % len(persons))
- print("Filtered %s trips" % len(trips))
+ print(r.share)
- print(share)
+ # Calculate the number of short distance trips that are missing in the simulated data
+ # This function required that one run with 0 iterations has been performed beforehand
- # Simulated trips
sim_persons = pd.read_csv("../../../output/output-lausitz-100pct/lausitz-100pct.output_persons.csv.gz",
delimiter=";", dtype={"person": "str"})
sim_persons = sim_persons[sim_persons.subpopulation == "person"]
@@ -47,5 +64,5 @@ def trip_filter(df):
sim = pd.merge(sim, sim_persons, how="inner", left_on="person", right_on="person", validate="many_to_one")
- share, add_trips = calc_needed_short_distance_trips(trips, sim, max_dist=700)
+ share, add_trips = calc_needed_short_distance_trips(r.trips, sim, max_dist=700)
print("Short distance trip missing: ", add_trips)
diff --git a/src/main/resources/lausitz_mode_share.csv b/src/main/resources/lausitz_mode_share.csv
index c024d07..5674bb5 100644
--- a/src/main/resources/lausitz_mode_share.csv
+++ b/src/main/resources/lausitz_mode_share.csv
@@ -1,31 +1,31 @@
-dist_group,main_mode,mean_dist,share
-0 - 1000,bike,741.7474152768164,0.05431618817899002
-0 - 1000,car,845.2047065363095,0.031216669310203
-0 - 1000,pt,503.9569413263069,0.0012298417638100443
-0 - 1000,ride,798.8045427222489,0.01929390934129713
-0 - 1000,walk,474.8462693693281,0.14568353330391315
-1000 - 2000,bike,1644.2686306579485,0.01912094472020174
-1000 - 2000,car,1664.6974637289466,0.04206126416523887
-1000 - 2000,pt,1769.9848721595795,0.006125610783078046
-1000 - 2000,ride,1695.6202104840554,0.015018450003780185
-1000 - 2000,walk,1781.56327180136,0.028682645671379056
-2000 - 5000,bike,3415.967452046967,0.025207557865234546
-2000 - 5000,car,3821.2329823444597,0.13695546693420932
-2000 - 5000,pt,3715.77927121702,0.011575801348651667
-2000 - 5000,ride,3336.405564477932,0.03633788006858987
-2000 - 5000,walk,3058.339137223546,0.01911150073233698
-5000 - 10000,bike,6635.65436876184,0.011838556537851376
-5000 - 10000,car,7311.064045237122,0.11269186948089517
-5000 - 10000,pt,6979.744659157714,0.013102503056468777
-5000 - 10000,ride,6898.4939502130765,0.027491496179970917
-5000 - 10000,walk,6657.462194056846,0.006142216096671607
-10000 - 20000,bike,14378.984336238063,0.00281739136837012
-10000 - 20000,car,14576.783406018267,0.0755031637087224
-10000 - 20000,pt,13429.023672194808,0.01383155988361684
-10000 - 20000,ride,14240.788705878334,0.020277335207750966
-10000 - 20000,walk,12940.0,0.0001990871342660644
-20000+,bike,37248.118594095315,0.003061190266223855
-20000+,car,47805.15415602558,0.09845227912097768
-20000+,pt,41088.975762937975,0.0036358034320222465
-20000+,ride,68027.0017296671,0.01901828433527827
-20000+,walk,,0.0
+dist_group,main_mode,share
+0 - 1000,bike,0.05431618817899002
+0 - 1000,car,0.031216669310203
+0 - 1000,pt,0.0012298417638100443
+0 - 1000,ride,0.01929390934129713
+0 - 1000,walk,0.14568353330391315
+1000 - 2000,bike,0.01912094472020174
+1000 - 2000,car,0.04206126416523887
+1000 - 2000,pt,0.006125610783078046
+1000 - 2000,ride,0.015018450003780185
+1000 - 2000,walk,0.028682645671379056
+2000 - 5000,bike,0.025207557865234546
+2000 - 5000,car,0.13695546693420932
+2000 - 5000,pt,0.011575801348651667
+2000 - 5000,ride,0.03633788006858987
+2000 - 5000,walk,0.01911150073233698
+5000 - 10000,bike,0.011838556537851376
+5000 - 10000,car,0.11269186948089517
+5000 - 10000,pt,0.013102503056468777
+5000 - 10000,ride,0.027491496179970917
+5000 - 10000,walk,0.006142216096671607
+10000 - 20000,bike,0.00281739136837012
+10000 - 20000,car,0.0755031637087224
+10000 - 20000,pt,0.01383155988361684
+10000 - 20000,ride,0.020277335207750966
+10000 - 20000,walk,0.0001990871342660644
+20000+,bike,0.003061190266223855
+20000+,car,0.09845227912097768
+20000+,pt,0.0036358034320222465
+20000+,ride,0.01901828433527827
+20000+,walk,0.0
diff --git a/src/main/resources/lausitz_mode_share_distance_distribution.csv b/src/main/resources/lausitz_mode_share_distance_distribution.csv
new file mode 100644
index 0000000..63e7e6d
--- /dev/null
+++ b/src/main/resources/lausitz_mode_share_distance_distribution.csv
@@ -0,0 +1,300 @@
+dist,pt,car,walk,bike,ride
+0,0.006438245669147738,0.0,0.9484150897805789,0.045146664550273316,0.0
+100,0.006327610449135864,0.0,0.910583830071749,0.0830885594791151,0.0
+200,0.00598054549533058,0.017405807602964188,0.839438707191748,0.1189315928120385,0.018243346897918816
+300,0.005450902187050734,0.05275840556240312,0.749674373204305,0.15060447401810753,0.0415118450281335
+400,0.004955647814807161,0.0852400685425383,0.6675968757721392,0.1805885994356018,0.06161880843491355
+500,0.004596454177101397,0.1144153097222975,0.5942565497740416,0.20815102508674102,0.0785806612398184
+600,0.004529749666026908,0.14262310707701384,0.5243426476509152,0.23359292329753145,0.0949115723085125
+700,0.004923378063767409,0.16986609083397136,0.46558065131639925,0.2518380146030129,0.10779186518284924
+800,0.005333060454631698,0.19898456574829967,0.40818785004621944,0.26695083084451,0.12054369290633932
+900,0.005396555779972778,0.23166097760133228,0.3544954065942443,0.2820125224001066,0.1264345376243441
+1000,0.005351732114506731,0.2618361708021551,0.3114769150757107,0.2977458995383251,0.12358928246930245
+1100,0.005540426563423938,0.282993435969644,0.29282507993295465,0.3018862408875874,0.11675481664639006
+1200,0.008314784249587408,0.30117029503913556,0.2839188095223689,0.2949069404624742,0.11168917072643392
+1300,0.02093271273250267,0.3231382345225638,0.26902609806504424,0.27434330506036125,0.11255964961952812
+1400,0.04061249199841914,0.3504011288232404,0.25124763304167913,0.23482829734832505,0.12291044878833643
+1500,0.05599826518792499,0.3718880572097683,0.24361420760928576,0.1950600435160843,0.13343942647693657
+1600,0.06025445751723495,0.37414520052498174,0.2513192425229118,0.1762490983169205,0.13803200111795097
+1700,0.06093630973944652,0.37176862072832895,0.2580155561821115,0.16323062193289414,0.1460488914172189
+1800,0.06202658075765882,0.3718057106686226,0.25418492258425895,0.14565988063416185,0.16632290535529778
+1900,0.0634241190478512,0.3683893381186058,0.2410040750309724,0.13040690409828354,0.19677556370428698
+2000,0.06112981468923492,0.36325781221188735,0.22692954852348604,0.12486902832015703,0.22381379625523476
+2100,0.05442375301340649,0.3602590323401186,0.21417697411028253,0.1321691343977579,0.23897110613843456
+2200,0.04799918639877914,0.3696581724474864,0.19248868365155658,0.13904473137334097,0.2508092261288369
+2300,0.03980826036543077,0.41490833953221073,0.1530778772800475,0.1324382386490016,0.25976728417330947
+2400,0.03336501054752348,0.46318597230822395,0.1271681400629663,0.12165284177365095,0.2546280353076353
+2500,0.03358677043286916,0.4861734669545826,0.12875604813307134,0.1161157305283996,0.2353679839510773
+2600,0.03357352686335551,0.488291990271796,0.15376290103592838,0.11583651715906958,0.20853506466985047
+2700,0.033989709680119856,0.48984833528614785,0.17998732710267493,0.11518663609685538,0.18098799183420208
+2800,0.03584977410606193,0.5033898775019855,0.2006573324414881,0.10957516563226884,0.15052785031819568
+2900,0.03623733888003685,0.527540153252669,0.21606216892166458,0.09873468085119551,0.12142565809443402
+3000,0.03569518140241692,0.541534220120972,0.2276727459657778,0.09011841784738367,0.10497943466344964
+3100,0.042999046292663094,0.5293532894541403,0.2360929267269027,0.09182674269756592,0.09972799482872795
+3200,0.06018795463170257,0.5088096402196165,0.23837516384387597,0.09601204784530194,0.09661519345950291
+3300,0.08463469175276697,0.5157872285462167,0.20536662270912723,0.09958188144873067,0.09462957554315846
+3400,0.10460512401870552,0.5520746975758312,0.12459608099867803,0.12427167055425291,0.0944524268525324
+3500,0.1024464220613712,0.5912784977162414,0.053916072072763985,0.1558534147070865,0.09650559344253695
+3600,0.09337503042767863,0.5875575646383476,0.040053508063458844,0.18530870869351335,0.0937051881770017
+3700,0.08965196676501984,0.572134725363915,0.04135553061949895,0.206461856459528,0.09039592079203829
+3800,0.08642318935200445,0.5648182243533931,0.04066244947587096,0.21974968695362712,0.08834644986510434
+3900,0.07932893523923748,0.5672870094029965,0.0381022186795674,0.22846547269271128,0.08681636398548737
+4000,0.07482887255296264,0.566748919692337,0.03597451958155847,0.2379559921360168,0.08449169603712518
+4100,0.07101949884692793,0.575497589181237,0.03380069592199259,0.23329867197644535,0.0863835440733971
+4200,0.06263263586646314,0.6310764960582368,0.025354609369771207,0.1794041514935556,0.10153210721197332
+4300,0.05971858653415498,0.6934403262829657,0.015342359089211319,0.11225246026051731,0.1192462678331507
+4400,0.05776651836067621,0.7425629642021859,0.007915162315949674,0.05946349901619287,0.1322918561049954
+4500,0.05478741141076499,0.7712007792806495,0.004124020515657693,0.030936103429825418,0.13895168536310237
+4600,0.053016018137967705,0.7723578081888476,0.004455389620256622,0.03044375309348375,0.13972703095944425
+4700,0.050589758260552,0.7665523910875184,0.0065892744176563565,0.03693357094947323,0.1393350052848001
+4800,0.04528533992435008,0.7646249761571791,0.008957768221169397,0.04119082288931867,0.13994109280798273
+4900,0.039288874077308376,0.7633154460722922,0.01146881984810393,0.04478252640408249,0.1411443335982131
+5000,0.03464738886832429,0.7566785598455023,0.01490677587091647,0.05226641077463551,0.1415008646406215
+5100,0.0346852631666367,0.7293701543370285,0.019909919894227985,0.06701676068437455,0.14901790191773243
+5200,0.04160764538581697,0.6546160086930886,0.026843698499197318,0.08340405947129476,0.1935285879506025
+5300,0.04248629009697603,0.5739255247695899,0.03824378643495223,0.09692537209705526,0.2484190266014265
+5400,0.034803030378241846,0.5619381926282834,0.043672419508615265,0.09435647699105403,0.26522988049380547
+5500,0.030395899873260548,0.5646250055925516,0.04644456644094621,0.09134590601285017,0.26718862208039146
+5600,0.028338736852126928,0.5642833152818888,0.04806568032766621,0.09054281129132224,0.2687694562469958
+5700,0.02904832940012219,0.5633351684938348,0.04743007883230693,0.08953498170814846,0.2706514415655876
+5800,0.03886904690996476,0.5557152904402285,0.04538374779481093,0.0910814037401907,0.2689505111148051
+5900,0.054987641874901155,0.5394971321937506,0.045612599833908876,0.09747014578310163,0.2624324803143378
+6000,0.07532712020294512,0.5238223915434341,0.0471782499293425,0.10661374837739716,0.24705848994688123
+6100,0.09963396921817382,0.5333688962845382,0.04642640589337066,0.1118360315978464,0.208734697006071
+6200,0.12843006496656262,0.5755838832247749,0.041388239457068154,0.1102235993570844,0.14437421299450978
+6300,0.15334606517466196,0.644967761504715,0.0316516089859915,0.09989128141085288,0.07014328292377858
+6400,0.1516295171768019,0.7011258191081537,0.022424259352123107,0.0840296987269793,0.0407907056359419
+6500,0.1389012145266953,0.7170586779528824,0.025213745589750026,0.08721706386292616,0.03160929806774614
+6600,0.12779091189990632,0.7264889653815103,0.030728825237549252,0.09329832311414163,0.021692974366892603
+6700,0.12887259928135145,0.7332097946109424,0.033638394999754975,0.09015713075553944,0.014122080352411692
+6800,0.1402869285080043,0.7286776866906154,0.03568141741039551,0.08336824978686985,0.011985717604114965
+6900,0.16912472083629468,0.6969102981340811,0.039704829468853925,0.08296749430976895,0.011292657251001348
+7000,0.22447116048728416,0.6249221071181462,0.044016677569345145,0.0892703782402291,0.01731967658499537
+7100,0.2608257644844417,0.5672034119172427,0.040345037664761246,0.0818239124653476,0.04980187346820673
+7200,0.2500824201982796,0.573711056508783,0.03126188235521403,0.054338653695241816,0.09060598724248145
+7300,0.20975667958929547,0.6233784553309331,0.031494120903990536,0.025085144707167422,0.11028559946861345
+7400,0.17595293227237302,0.6555717108766906,0.04087345206670725,0.010323894909017417,0.11727800987521166
+7500,0.14361554486480518,0.6712620395351453,0.05494063901642022,0.009174211072940757,0.12100756551068852
+7600,0.10368258076595839,0.691802660489688,0.06745523668220929,0.011263949425721233,0.12579557263642324
+7700,0.056249690950847794,0.7220016616536249,0.07634942667120562,0.012749137398462174,0.13265008332585934
+7800,0.01883997628583133,0.743777590341943,0.08521656330431125,0.014229807891945211,0.13793606217596913
+7900,0.010104352859103261,0.7495806721548423,0.09470533981346073,0.01581428233704371,0.12979535283555008
+8000,0.011233438459009816,0.7868944132854582,0.09300169824315688,0.015529801347408102,0.09334064866496705
+8100,0.01145995552538548,0.8513919682042497,0.0789375940886519,0.013181320107015376,0.04502916207469733
+8200,0.011151939989467256,0.917867843502853,0.053334322298872805,0.008905981782553928,0.008739912426253047
+8300,0.00972167582827173,0.962738371764399,0.023599253240576948,0.003940699166752082,0.0
+8400,0.01128993551950345,0.9834882339170982,0.004474637429374381,0.0007471931340240244,0.0
+8500,0.02246936826048236,0.9775306317395176,0.0,0.0,0.0
+8600,0.03802609430908594,0.961973905690914,0.0,0.0,0.0
+8700,0.054045578072640425,0.9459544219273596,0.0,0.0,0.0
+8800,0.07275427476986282,0.9272457252301373,0.0,0.0,0.0
+8900,0.09462160547772164,0.8820954197843136,0.0,0.0,0.023282974737964618
+9000,0.10037783052439449,0.7757880742674531,0.0,0.0,0.1238340952081524
+9100,0.08548223084572293,0.6915071986030751,0.0,0.0,0.22301057055120188
+9200,0.06303691971829178,0.6781360976638311,0.00030475341464326666,0.004286186628155622,0.25423604257507826
+9300,0.04618210924360516,0.6748008171416514,0.0013187126467752305,0.01854695711811472,0.2591514038498536
+9400,0.033658638831829735,0.6678714358692739,0.0025996306776390854,0.03656235406478643,0.25930794055647083
+9500,0.022885132064759586,0.6618298551682028,0.0037391137581216254,0.05258854739978455,0.2589573516091316
+9600,0.01608443560619018,0.6560170790522112,0.004511186062509704,0.06344731330044286,0.2599399859786461
+9700,0.01688890395884207,0.6460300004469222,0.005110253294283316,0.07187285944633241,0.26009798285362007
+9800,0.020663695810538146,0.6289543232469773,0.00592801243147325,0.08337418514264489,0.26107978336836635
+9900,0.0250127395786839,0.6004658692802929,0.007051057938256803,0.09916919318093224,0.26830114002183414
+10000,0.03071006415525802,0.5648028887404409,0.008207934657970713,0.11544001834056712,0.2808390941057632
+10100,0.034075336304219196,0.543188945101003,0.008133248491200657,0.11438959910345133,0.3002128710001258
+10200,0.04099720775252687,0.5552313197731781,0.005540472692636627,0.07792365508566475,0.3203073446959936
+10300,0.07932007406188926,0.5598231318578172,0.0025057722392325477,0.03524228753129548,0.32310873430976544
+10400,0.12869711926658603,0.5566397853308812,0.00046756751418165575,0.0065760760363957945,0.3076194518519554
+10500,0.16486716816604535,0.550376827292983,0.0,0.0,0.2847560045409717
+10600,0.19170271098121153,0.5446560726834441,0.0,0.0,0.2636412163353445
+10700,0.22207540909917367,0.537007032787975,0.0,0.0,0.24091755811285137
+10800,0.2552499493650598,0.5375557039753471,0.0,0.0,0.20719434665959308
+10900,0.24124080263539452,0.584716071313769,0.0,0.0,0.17404312605083658
+11000,0.18760806628616214,0.6454911897746058,0.0,0.0,0.16690074393923204
+11100,0.13674346897902429,0.681437440316752,0.0,0.0012109581905704475,0.18060813251365318
+11200,0.116735480416273,0.6876178603227122,0.0,0.0054145311671518585,0.19023212809386286
+11300,0.11418176715371137,0.6799171840967368,0.0,0.010933007645745892,0.19496804110380592
+11400,0.12145956648800595,0.6650884463045678,0.0,0.01595107392897707,0.19750091327844913
+11500,0.1370868339651815,0.6467990421141375,0.0,0.01912254517783967,0.19699157874284132
+11600,0.1525098588999834,0.632635511477031,0.0,0.021273936982318907,0.19358069264066666
+11700,0.17451920062624104,0.6140965691169014,0.0,0.02434406865960143,0.18704016159725612
+11800,0.21446928267693074,0.5811891149231309,0.0,0.029916793820551235,0.17442480857938703
+11900,0.27830544449231204,0.5296042682440091,0.0,0.038821440991880306,0.1532688462717986
+12000,0.3343717221074819,0.4870889471768008,0.0,0.04644245875741983,0.13209687195829758
+12100,0.27751971391742203,0.541014916456082,0.0,0.03752553693909764,0.14393983268739816
+12200,0.16509159422686195,0.6416970884319487,0.0,0.020220085461751254,0.17299123187943807
+12300,0.06602201129535781,0.7284789632533315,0.002007987353610539,0.004557272923086476,0.19893376517461356
+12400,0.04128509019279321,0.7432790581355142,0.010551717594482462,0.0,0.20488413407721
+12500,0.0459716461266801,0.7293604206839843,0.0231483056689369,0.0,0.2015196275203988
+12600,0.05384340411204311,0.710734555854725,0.03904867111995304,0.0,0.19637336891327878
+12700,0.07106783238122144,0.6870235669056745,0.06194753563166143,0.0,0.17996106508144263
+12800,0.09410343780932219,0.6920815983140831,0.09286332900305595,0.0,0.12095163487353881
+12900,0.17648846484436062,0.692161172195042,0.10463886934203206,0.0,0.026711493618565216
+13000,0.3435787206097278,0.5861498526424009,0.07027142674787128,0.0,0.0
+13100,0.45031867176294194,0.4811456522869824,0.04550190785355103,0.023033768096524486,0.0
+13200,0.48875933752349326,0.3926087666328422,0.029288421319089618,0.08934347452457504,0.0
+13300,0.49001991242594384,0.33468396052756505,0.017034060685931045,0.15826206636056014,0.0
+13400,0.47779868774420003,0.3040312218722837,0.007446674799297519,0.21072341558421875,0.0
+13500,0.4724207617050805,0.2800620534218127,0.0014430588789745968,0.24607412599413217,0.0
+13600,0.43849022096654533,0.3119996066076421,0.0,0.24515729855101878,0.0043528738747937714
+13700,0.3175610490823876,0.4749018387679879,0.0,0.19057243440924285,0.016964677740381667
+13800,0.20874513783550974,0.6189764794763212,0.0,0.1449850840024522,0.027293298685716786
+13900,0.13683722746010277,0.7145282993506091,0.0,0.1151293456863067,0.03350512750298146
+14000,0.08756054883098702,0.7855595537358535,0.0,0.08978734527274444,0.03709255216041499
+14100,0.060560390683148155,0.8389640020978403,0.0,0.0613160215366772,0.03915958568233437
+14200,0.06054509269392205,0.8698786944874389,0.0,0.029599946988829506,0.039976265829809544
+14300,0.06545888337590082,0.8883278802683442,0.0,0.005946731942630292,0.04026650441312471
+14400,0.06962923381935174,0.890466528898434,0.0,0.0,0.03990423728221425
+14500,0.08019486863831854,0.8808912234391667,0.0,0.0,0.03891390792251484
+14600,0.10168940799103651,0.8619059879877031,0.0,0.0,0.036404604021260514
+14700,0.13329338694710358,0.8376567669360001,0.0,0.0,0.02904984611689625
+14800,0.14473184222570734,0.8398307866052082,0.0,0.0,0.015437371169084375
+14900,0.07438330803231356,0.9145966758496922,0.0,0.0,0.011020016117994216
+15000,0.014233908545515227,0.9730585245973059,0.0,0.0,0.012707566857178772
+15100,0.0,0.9862501711182988,0.0,0.0,0.013749828881701223
+15200,0.0,0.9856243905978475,0.0,0.0,0.014375609402152517
+15300,0.0,0.9854631132953934,0.0,0.0,0.014536886704606579
+15400,0.0,0.9854631132953934,0.0,0.0,0.01453688670460658
+15500,0.0,0.9862248822795526,0.0,0.0011472542438816138,0.012627863476565694
+15600,0.0,0.9885159044731241,0.0,0.004597624354844423,0.006886471172031582
+15700,0.0,0.9902776254257173,0.0,0.007250845845121395,0.0024715287291612984
+15800,0.0,0.9911065424537139,0.0,0.00849922770099915,0.00039422984528692206
+15900,0.0,0.9912638543524683,0.0,0.008736145647531609,0.0
+16000,0.0,0.9912638543524683,0.0,0.008736145647531609,0.0
+16100,0.0,0.9912638543524684,0.0,0.008736145647531609,0.0
+16200,0.0,0.9912638543524684,0.0,0.008736145647531609,0.0
+16300,0.0,0.9912638543524683,0.0,0.008736145647531609,0.0
+16400,0.0,0.9912638543524683,0.0,0.008736145647531609,0.0
+16500,0.0076453948913832,0.8949062493555942,0.0,0.007584646526735886,0.08986370922628677
+16600,0.035777064083764736,0.5403529128108264,0.0,0.003347639439233728,0.4205223836661752
+16700,0.05479310105991498,0.3006871001764792,0.0,0.0004835689536483367,0.6440362298099575
+16800,0.05800376404791598,0.26022198354469295,0.0,0.0,0.6817742524073911
+16900,0.05800376404791597,0.26022198354469295,0.0,0.0,0.6817742524073911
+17000,0.057998260805276196,0.26019729437599576,0.0,9.48773364988347e-05,0.6817095674822292
+17100,0.05797618320165284,0.26009824773822865,0.0,0.0004755009733566908,0.6814500680867618
+17200,0.05794546994448413,0.25996045901308734,0.0,0.0010050055266014027,0.6810890655158272
+17300,0.05791369430103596,0.25981790410993205,0.0,0.0015528258960162116,0.6807155756930158
+17400,0.06706650380204886,0.26576495058345323,0.0,0.0021534506663174772,0.6650150949481805
+17500,0.11687549335530208,0.29868501771124367,0.0,0.002911165065306265,0.5815283238681478
+17600,0.23159996077144143,0.37462725021494053,0.0,0.004124919106641223,0.38964786990697675
+17700,0.4019491765853675,0.4874688869828561,0.0,0.005573421909585601,0.10500851452219069
+17800,0.46521661623067767,0.5295792240850474,0.0,0.005204159684274656,0.0
+17900,0.4657284364248598,0.530161854480974,0.0,0.004109709094166364,0.0
+18000,0.4663373964400129,0.5308550639689249,0.0,0.002807539591062273,0.0
+18100,0.4670175803388063,0.5316293511478238,0.0,0.0013530685133697866,0.0
+18200,0.467517086032572,0.5321979633351395,0.0,0.00028495063228841955,0.0
+18300,0.46765034329358346,0.5323496567064165,0.0,0.0,0.0
+18400,0.36700767262585726,0.6174932211277873,0.0,0.0,0.015499106246355485
+18500,0.11868286444151634,0.8281772055282973,0.0,0.0,0.05313993003018631
+18600,0.014315511951936205,0.9177263784536728,0.0,0.0,0.067958109594391
+18700,0.0,0.9307114984163783,0.0,0.0,0.0692885015836217
+18800,0.0,0.9312832705121141,0.0,0.0,0.06871672948788585
+18900,0.0,0.9316585668039561,0.0,0.0,0.06834143319604388
+19000,0.0,0.9304530748803702,0.0,0.0014980239474023925,0.06804890117222727
+19100,0.0,0.9248408963808024,0.0,0.007589471801104684,0.06756963181809286
+19200,0.0,0.9165296446928366,0.0,0.01672198076271787,0.06674837454444554
+19300,0.0,0.9063907221945259,0.0,0.028240399184102778,0.06536887862137143
+19400,0.0,0.8918967526387833,0.0,0.04561883645554792,0.06248441090566866
+19500,0.0,0.861113904214634,0.0,0.0830926984278105,0.05579339735755564
+19600,0.0,0.7819085653691107,0.0,0.17817984770292372,0.039911586927965564
+19700,0.0,0.7259793069173521,0.0,0.24280886877433774,0.03121182430831021
+19800,0.0,0.7410754783125427,0.0,0.2260309976479617,0.03289352403949558
+19900,0.0,0.7703274636412357,0.0,0.19548062786212356,0.034191908496640624
+20000,0.0,0.8192845084845298,0.0,0.14435056585852302,0.0363649256569472
+20100,0.0,0.8819769615738162,0.0,0.07887543303803965,0.039147605388144144
+20200,0.0,0.938567880597209,0.0,0.01977265819187451,0.041659461210916425
+20300,0.0,0.9485240784120105,0.0,0.0029236228867766637,0.04855229870121288
+20400,0.0,0.9151789363263477,0.0,0.013784501580576935,0.0710365620930753
+20500,0.0,0.8923522436117296,0.0,0.021219405888893473,0.08642835049937678
+20600,0.0,0.8884750741484149,0.0,0.022482242529630873,0.08904268332195425
+20700,0.0,0.888475074148415,0.0,0.022482242529630873,0.08904268332195427
+20800,0.0,0.8884750741484149,0.0,0.02248224252963087,0.08904268332195425
+20900,0.0,0.8884750741484149,0.0,0.02248224252963087,0.08904268332195424
+21000,0.0,0.8884750741484149,0.0,0.022482242529630873,0.08904268332195424
+21100,0.0,0.8884750741484149,0.0,0.022482242529630877,0.08904268332195427
+21200,0.0,0.8878706319906309,0.0,0.022297283650988646,0.08983208435838054
+21300,0.0,0.8842537256088312,0.0,0.021190512821197216,0.09455576156997168
+21400,0.0,0.8729525437456094,0.0,0.017732359054397767,0.10931509719999279
+21500,0.0,0.8397543755090224,0.0,0.007573742731992333,0.15267188175898536
+21600,0.0,0.8150035258443139,0.0,0.0,0.18499647415568618
+21700,0.0,0.8150035258443139,0.0,0.0,0.18499647415568618
+21800,0.0,0.8150035258443139,0.0,0.0,0.18499647415568618
+21900,0.015299203647355687,0.8025346209291088,0.0,0.0,0.18216617542353555
+22000,0.07716015460588332,0.7521177277858265,0.0,0.0,0.17072211760829012
+22100,0.17275058356918543,0.6742111911437649,0.0,0.0,0.1530382252870497
+22200,0.3059600873305024,0.5656449759023202,0.0,0.0,0.1283949367671774
+22300,0.5240415218718567,0.3879078378299306,0.0,0.0,0.0880506402982128
+22400,0.855598652789068,0.11768760711357852,0.0,0.0,0.026713740097353438
+22500,1.0,0.0,0.0,0.0,0.0
+22600,1.0,0.0,0.0,0.0,0.0
+22700,1.0,0.0,0.0,0.0,0.0
+22800,1.0,0.0,0.0,0.0,0.0
+22900,1.0,0.0,0.0,0.0,0.0
+23000,1.0,0.0,0.0,0.0,0.0
+23100,0.009473809357837381,0.8711017725967473,0.0,0.0,0.11942441804541531
+23200,0.0,0.879433356559717,0.0,0.0,0.12056664344028294
+23300,0.0,0.879433356559717,0.0,0.0,0.12056664344028294
+23400,0.0,0.8794333565597171,0.0,0.0,0.12056664344028292
+23500,0.0,0.8794333565597171,0.0,0.0,0.12056664344028292
+23600,0.0,0.8794333565597171,0.0,0.0,0.12056664344028294
+23700,0.0,0.8794333565597171,0.0,0.0,0.12056664344028294
+23800,0.0,0.8794333565597171,0.0,0.0,0.12056664344028292
+23900,0.0,0.8744992169720435,0.0,0.005610589535716064,0.11989019349224048
+24000,0.0,0.850515523737705,0.0,0.03288234703211242,0.1166021292301826
+24100,0.0,0.8002268056385419,0.0,0.09207934478127415,0.10769384958018387
+24200,0.0,0.7129160617916496,0.0,0.2049500800359038,0.08213385817244667
+24300,0.0,0.6047783369162287,0.0,0.36061500830181314,0.03460665478195819
+24400,0.0,0.6135625297032158,0.0,0.3700012739167616,0.01643619638002265
+24500,0.0,0.6504565908571549,0.0,0.3321188896416631,0.017424519501181998
+24600,0.0,0.6655654893995708,0.0,0.3166052518729958,0.017829258727433486
+24700,0.0,0.6802872197727642,0.0,0.30148915378705343,0.01822362644018249
+24800,0.0,0.7052959303208088,0.0,0.27581050650415345,0.018893563175037587
+24900,0.0,0.7211408276030902,0.0,0.25954115396141364,0.019318018435496263
+25000,0.0,0.7363532718423524,0.0,0.23250706863774562,0.03113965951990184
+25100,0.0,0.7649002249280571,0.0,0.16904990456385005,0.06604987050809272
+25200,0.0,0.7737457856315542,0.0,0.13507469210634304,0.09117952226210285
+25300,0.0,0.7814216532436471,0.0,0.11543100335268851,0.10314734340366435
+25400,0.0,0.791856193594829,0.0,0.10152740780875759,0.10661639859641348
+25500,0.0,0.7973897248273442,0.0,0.09524883577678456,0.10736143939587134
+25600,0.0,0.8022930020480289,0.0,0.08968537585775409,0.10802162209421709
+25700,0.0,0.812071044822189,0.0,0.07859080652948583,0.10933814864832526
+25800,0.0,0.826900065863306,0.0,0.06176518960277376,0.11133474453392025
+25900,0.0,0.8447989686041656,0.0,0.041456358689988614,0.11374467270584585
+26000,0.0,0.8639489719082726,0.0,0.02364597807621561,0.1124050500155119
+26100,0.0,0.8880293363596617,0.0,0.024668451126703485,0.08730221251363476
+26200,0.0,0.937343109349061,0.0,0.036995858597342945,0.02566103205359613
+26300,0.0,0.9673046691958213,0.0,0.032695330804178774,0.0
+26400,0.0,0.9447455040999899,0.0,0.02518953875591632,0.0300649571440937
+26500,0.0,0.8390575056094834,0.0,0.016739710758253923,0.1442027836322626
+26600,0.0,0.7265670143775266,0.0,0.008197383612245339,0.26523560201022817
+26700,0.0,0.6674276794596885,0.0,0.0029265320045121805,0.3296457885357994
+26800,0.0,0.6371193587411531,0.0,0.0004900417475388654,0.362390599511308
+26900,0.0,0.6170752480459976,0.0,0.0,0.3829247519540024
+27000,0.0,0.6071534138553211,0.0,0.0,0.3928465861446789
+27100,0.0,0.601457017920451,0.0,0.0,0.398542982079549
+27200,0.0,0.6076054559221944,0.0,0.0,0.39239454407780555
+27300,0.0,0.6358314973909314,0.0,0.0,0.3641685026090686
+27400,0.0,0.6798939933377026,0.0,0.0,0.3201060066622975
+27500,0.0,0.7491661777925617,0.0,0.0,0.25083382220743833
+27600,0.0,0.857591065834512,0.0,0.0,0.14240893416548817
+27700,0.0,0.9648886531868479,0.0,0.0,0.035111346813152124
+27800,0.0,1.0,0.0,0.0,0.0
+27900,0.0,0.7132033959930415,0.0,0.0,0.2867966040069585
+28000,0.0,0.4405192351148883,0.0,0.0,0.5594807648851118
+28100,0.0,0.38540364787756415,0.0,0.0,0.6145963521224359
+28200,0.0,0.3790330381031897,0.0,0.0,0.6209669618968103
+28300,0.0,0.3790330381031897,0.0,0.0,0.6209669618968103
+28400,0.0,0.3790330381031897,0.0,0.0,0.6209669618968102
+28500,0.0,0.3790330381031897,0.0,0.0,0.6209669618968102
+28600,0.0,0.3790330381031897,0.0,0.0,0.6209669618968102
+28700,0.0,0.3790330381031898,0.0,0.0,0.6209669618968103
+28800,0.0,0.38151831839945327,0.0,0.0009763562362276555,0.617505325364319
+28900,0.0,0.39667219889233785,0.0,0.006929642770756788,0.5963981583369053
+29000,0.0,0.44736721845570226,0.0,0.026845464165545913,0.5257873173787518
+29100,0.0,0.6335381114083105,0.0,0.09998373859343504,0.2664781499982545
+29200,0.0,0.8248559720095832,0.0,0.17514402799041667,0.0
+29300,0.0,0.8248559720095834,0.0,0.17514402799041673,0.0
+29400,0.0,0.8248559720095833,0.0,0.1751440279904167,0.0
+29500,0.0,0.8248559720095834,0.0,0.17514402799041673,0.0
+29600,0.0,0.8248559720095833,0.0,0.1751440279904167,0.0
+29700,0.0,0.8248559720095833,0.0,0.1751440279904167,0.0
+29800,0.0,0.8248559720095833,0.0,0.1751440279904167,0.0
diff --git a/src/main/resources/lausitz_mode_share_per_dist.csv b/src/main/resources/lausitz_mode_share_per_dist.csv
index bfc48ff..a42b3d1 100644
--- a/src/main/resources/lausitz_mode_share_per_dist.csv
+++ b/src/main/resources/lausitz_mode_share_per_dist.csv
@@ -1,31 +1,31 @@
-dist_group,main_mode,mean_dist,share
-0 - 1000,bike,741.7474152768164,0.2157629203250064
-0 - 1000,car,845.2047065363095,0.12400354220355093
-0 - 1000,pt,503.9569413263069,0.004885362161698109
-0 - 1000,ride,798.8045427222489,0.07664216439942374
-0 - 1000,walk,474.8462693693281,0.5787060109103207
-1000 - 2000,bike,1644.2686306579485,0.17224692864536398
-1000 - 2000,car,1664.6974637289466,0.3788998751588497
-1000 - 2000,pt,1769.9848721595795,0.05518125066003455
-1000 - 2000,ride,1695.6202104840554,0.1352904850685536
-1000 - 2000,walk,1781.56327180136,0.2583814604671981
-2000 - 5000,bike,3415.967452046967,0.10998627809345088
-2000 - 5000,car,3821.2329823444597,0.5975676879599303
-2000 - 5000,pt,3715.77927121702,0.05050784027132093
-2000 - 5000,ride,3336.405564477932,0.15855039206564583
-2000 - 5000,walk,3058.339137223546,0.08338780160965216
-5000 - 10000,bike,6635.65436876184,0.06912354002160712
-5000 - 10000,car,7311.064045237122,0.6579907715325366
-5000 - 10000,pt,6979.744659157714,0.07650353246287123
-5000 - 10000,ride,6898.4939502130765,0.16051868573455097
-5000 - 10000,walk,6657.462194056846,0.03586347024843422
-10000 - 20000,bike,14378.984336238063,0.025014897963181838
-10000 - 20000,car,14576.783406018267,0.6703732954089843
-10000 - 20000,pt,13429.023672194808,0.12280688549155136
-10000 - 20000,ride,14240.788705878334,0.1800372773487143
-10000 - 20000,walk,12940.0,0.0017676437875682608
-20000+,bike,37248.118594095315,0.024653704529394964
-20000+,car,47805.15415602558,0.7928985749351034
-20000+,pt,41088.975762937975,0.029281428380669564
-20000+,ride,68027.0017296671,0.15316629215483207
-20000+,walk,,0.0
+dist_group,main_mode,share
+0 - 1000,bike,0.2157629203250064
+0 - 1000,car,0.12400354220355093
+0 - 1000,pt,0.004885362161698109
+0 - 1000,ride,0.07664216439942374
+0 - 1000,walk,0.5787060109103207
+1000 - 2000,bike,0.17224692864536398
+1000 - 2000,car,0.3788998751588497
+1000 - 2000,pt,0.05518125066003455
+1000 - 2000,ride,0.1352904850685536
+1000 - 2000,walk,0.2583814604671981
+2000 - 5000,bike,0.10998627809345088
+2000 - 5000,car,0.5975676879599303
+2000 - 5000,pt,0.05050784027132093
+2000 - 5000,ride,0.15855039206564583
+2000 - 5000,walk,0.08338780160965216
+5000 - 10000,bike,0.06912354002160712
+5000 - 10000,car,0.6579907715325366
+5000 - 10000,pt,0.07650353246287123
+5000 - 10000,ride,0.16051868573455097
+5000 - 10000,walk,0.03586347024843422
+10000 - 20000,bike,0.025014897963181838
+10000 - 20000,car,0.6703732954089843
+10000 - 20000,pt,0.12280688549155136
+10000 - 20000,ride,0.1800372773487143
+10000 - 20000,walk,0.0017676437875682608
+20000+,bike,0.024653704529394964
+20000+,car,0.7928985749351034
+20000+,pt,0.029281428380669564
+20000+,ride,0.15316629215483207
+20000+,walk,0.0
diff --git a/src/main/resources/lausitz_mode_share_per_group_dist_ref.csv b/src/main/resources/lausitz_mode_share_per_group_dist_ref.csv
new file mode 100644
index 0000000..570cc68
--- /dev/null
+++ b/src/main/resources/lausitz_mode_share_per_group_dist_ref.csv
@@ -0,0 +1,361 @@
+age,economic_status,dist_group,main_mode,share
+,,0 - 1000,bike,0.05431618817899002
+,,0 - 1000,car,0.031216669310203
+,,0 - 1000,pt,0.0012298417638100443
+,,0 - 1000,ride,0.01929390934129713
+,,0 - 1000,walk,0.14568353330391315
+,,1000 - 2000,bike,0.01912094472020174
+,,1000 - 2000,car,0.04206126416523887
+,,1000 - 2000,pt,0.006125610783078046
+,,1000 - 2000,ride,0.015018450003780185
+,,1000 - 2000,walk,0.028682645671379056
+,,2000 - 5000,bike,0.025207557865234546
+,,2000 - 5000,car,0.13695546693420932
+,,2000 - 5000,pt,0.011575801348651667
+,,2000 - 5000,ride,0.03633788006858987
+,,2000 - 5000,walk,0.01911150073233698
+,,5000 - 10000,bike,0.011838556537851376
+,,5000 - 10000,car,0.11269186948089517
+,,5000 - 10000,pt,0.013102503056468777
+,,5000 - 10000,ride,0.027491496179970917
+,,5000 - 10000,walk,0.006142216096671607
+,,10000 - 20000,bike,0.00281739136837012
+,,10000 - 20000,car,0.0755031637087224
+,,10000 - 20000,pt,0.01383155988361684
+,,10000 - 20000,ride,0.020277335207750966
+,,10000 - 20000,walk,0.0001990871342660644
+,,20000+,bike,0.003061190266223855
+,,20000+,car,0.09845227912097768
+,,20000+,pt,0.0036358034320222465
+,,20000+,ride,0.01901828433527827
+,,20000+,walk,0.0
+0 - 12,,0 - 1000,bike,0.0424123202325245
+0 - 12,,0 - 1000,car,0.0
+0 - 12,,0 - 1000,pt,0.0025770154730283814
+0 - 12,,0 - 1000,ride,0.08294092904837969
+0 - 12,,0 - 1000,walk,0.15670748750795632
+0 - 12,,1000 - 2000,bike,0.0
+0 - 12,,1000 - 2000,car,0.0
+0 - 12,,1000 - 2000,pt,0.0014082494088304978
+0 - 12,,1000 - 2000,ride,0.10545564882238147
+0 - 12,,1000 - 2000,walk,0.009056202303628748
+0 - 12,,2000 - 5000,bike,0.037572150203521004
+0 - 12,,2000 - 5000,car,0.0
+0 - 12,,2000 - 5000,pt,0.009004529686144179
+0 - 12,,2000 - 5000,ride,0.16067253829666814
+0 - 12,,2000 - 5000,walk,0.0810962661446554
+0 - 12,,5000 - 10000,bike,0.03955687551744341
+0 - 12,,5000 - 10000,car,0.0
+0 - 12,,5000 - 10000,pt,0.01584983411776204
+0 - 12,,5000 - 10000,ride,0.07850222305133919
+0 - 12,,5000 - 10000,walk,0.0
+0 - 12,,10000 - 20000,bike,0.0016497441420122042
+0 - 12,,10000 - 20000,car,0.0
+0 - 12,,10000 - 20000,pt,0.05815432505814488
+0 - 12,,10000 - 20000,ride,0.04878588463287295
+0 - 12,,10000 - 20000,walk,0.0
+0 - 12,,20000+,bike,0.0
+0 - 12,,20000+,car,0.0
+0 - 12,,20000+,pt,0.015905863530850498
+0 - 12,,20000+,ride,0.05269191282185665
+0 - 12,,20000+,walk,0.0
+12 - 18,,0 - 1000,bike,
+12 - 18,,0 - 1000,car,
+12 - 18,,0 - 1000,pt,
+12 - 18,,0 - 1000,ride,
+12 - 18,,0 - 1000,walk,
+12 - 18,,1000 - 2000,bike,
+12 - 18,,1000 - 2000,car,
+12 - 18,,1000 - 2000,pt,
+12 - 18,,1000 - 2000,ride,
+12 - 18,,1000 - 2000,walk,
+12 - 18,,2000 - 5000,bike,
+12 - 18,,2000 - 5000,car,
+12 - 18,,2000 - 5000,pt,
+12 - 18,,2000 - 5000,ride,
+12 - 18,,2000 - 5000,walk,
+12 - 18,,5000 - 10000,bike,
+12 - 18,,5000 - 10000,car,
+12 - 18,,5000 - 10000,pt,
+12 - 18,,5000 - 10000,ride,
+12 - 18,,5000 - 10000,walk,
+12 - 18,,10000 - 20000,bike,
+12 - 18,,10000 - 20000,car,
+12 - 18,,10000 - 20000,pt,
+12 - 18,,10000 - 20000,ride,
+12 - 18,,10000 - 20000,walk,
+12 - 18,,20000+,bike,
+12 - 18,,20000+,car,
+12 - 18,,20000+,pt,
+12 - 18,,20000+,ride,
+12 - 18,,20000+,walk,
+18 - 25,,0 - 1000,bike,0.023628729068553487
+18 - 25,,0 - 1000,car,0.0509727959700864
+18 - 25,,0 - 1000,pt,0.0
+18 - 25,,0 - 1000,ride,0.06730800660127076
+18 - 25,,0 - 1000,walk,0.05570051555128522
+18 - 25,,1000 - 2000,bike,0.0026268731883662367
+18 - 25,,1000 - 2000,car,0.045163694079610524
+18 - 25,,1000 - 2000,pt,0.0018588089679363957
+18 - 25,,1000 - 2000,ride,0.008227624942275675
+18 - 25,,1000 - 2000,walk,0.045787208794976234
+18 - 25,,2000 - 5000,bike,0.0
+18 - 25,,2000 - 5000,car,0.15413845753427738
+18 - 25,,2000 - 5000,pt,0.01767358089478364
+18 - 25,,2000 - 5000,ride,0.023951153220848218
+18 - 25,,2000 - 5000,walk,0.009418981413343209
+18 - 25,,5000 - 10000,bike,0.002180326452188062
+18 - 25,,5000 - 10000,car,0.2956410883664242
+18 - 25,,5000 - 10000,pt,0.0
+18 - 25,,5000 - 10000,ride,0.0
+18 - 25,,5000 - 10000,walk,0.004410446174211738
+18 - 25,,10000 - 20000,bike,0.002180326452188062
+18 - 25,,10000 - 20000,car,0.04474777480940164
+18 - 25,,10000 - 20000,pt,0.019463753587204403
+18 - 25,,10000 - 20000,ride,0.0
+18 - 25,,10000 - 20000,walk,0.0
+18 - 25,,20000+,bike,0.0
+18 - 25,,20000+,car,0.12491985393076852
+18 - 25,,20000+,pt,0.0
+18 - 25,,20000+,ride,0.0
+18 - 25,,20000+,walk,0.0
+25 - 35,,0 - 1000,bike,0.05155991322568403
+25 - 35,,0 - 1000,car,0.02940346396420906
+25 - 35,,0 - 1000,pt,0.0
+25 - 35,,0 - 1000,ride,0.0
+25 - 35,,0 - 1000,walk,0.13793811722547314
+25 - 35,,1000 - 2000,bike,0.00734091958509167
+25 - 35,,1000 - 2000,car,0.05064064975910667
+25 - 35,,1000 - 2000,pt,0.0
+25 - 35,,1000 - 2000,ride,0.0
+25 - 35,,1000 - 2000,walk,0.007391227373696437
+25 - 35,,2000 - 5000,bike,0.0008692454681906939
+25 - 35,,2000 - 5000,car,0.21804733449016767
+25 - 35,,2000 - 5000,pt,0.0
+25 - 35,,2000 - 5000,ride,0.01688102813071631
+25 - 35,,2000 - 5000,walk,0.0
+25 - 35,,5000 - 10000,bike,0.019907985529930266
+25 - 35,,5000 - 10000,car,0.1794390405205994
+25 - 35,,5000 - 10000,pt,0.0
+25 - 35,,5000 - 10000,ride,0.0062435004571335575
+25 - 35,,5000 - 10000,walk,0.0010293513824916702
+25 - 35,,10000 - 20000,bike,0.0
+25 - 35,,10000 - 20000,car,0.036126615191841495
+25 - 35,,10000 - 20000,pt,0.0
+25 - 35,,10000 - 20000,ride,0.03133824950229776
+25 - 35,,10000 - 20000,walk,0.001604319292314419
+25 - 35,,20000+,bike,0.0
+25 - 35,,20000+,car,0.12337935273681218
+25 - 35,,20000+,pt,0.012165299150001281
+25 - 35,,20000+,ride,0.06869438701424221
+25 - 35,,20000+,walk,0.0
+35 - 66,,0 - 1000,bike,0.05521591477916032
+35 - 66,,0 - 1000,car,0.03291030775012274
+35 - 66,,0 - 1000,pt,0.0013006264405648785
+35 - 66,,0 - 1000,ride,9.601198741017503e-05
+35 - 66,,0 - 1000,walk,0.13753164186210207
+35 - 66,,1000 - 2000,bike,0.03302689592640806
+35 - 66,,1000 - 2000,car,0.055338346414522635
+35 - 66,,1000 - 2000,pt,0.0013474008286139694
+35 - 66,,1000 - 2000,ride,0.006200285756656349
+35 - 66,,1000 - 2000,walk,0.032954940416333955
+35 - 66,,2000 - 5000,bike,0.03134893815004003
+35 - 66,,2000 - 5000,car,0.15542842616089586
+35 - 66,,2000 - 5000,pt,0.004866526258583225
+35 - 66,,2000 - 5000,ride,0.018032410978690957
+35 - 66,,2000 - 5000,walk,0.012209148022094102
+35 - 66,,5000 - 10000,bike,0.00547312959942679
+35 - 66,,5000 - 10000,car,0.0918541195950397
+35 - 66,,5000 - 10000,pt,0.01736203806835167
+35 - 66,,5000 - 10000,ride,0.03407688526547902
+35 - 66,,5000 - 10000,walk,0.009419066096745744
+35 - 66,,10000 - 20000,bike,0.0026992388500293564
+35 - 66,,10000 - 20000,car,0.10623166462574206
+35 - 66,,10000 - 20000,pt,0.0072520783683791374
+35 - 66,,10000 - 20000,ride,0.014359069762638843
+35 - 66,,10000 - 20000,walk,0.0
+35 - 66,,20000+,bike,0.002109102757092199
+35 - 66,,20000+,car,0.12371843881368494
+35 - 66,,20000+,pt,0.0009432073544393029
+35 - 66,,20000+,ride,0.006694139110751729
+35 - 66,,20000+,walk,0.0
+66+,,0 - 1000,bike,0.08996311476788804
+66+,,0 - 1000,car,0.033094849261911
+66+,,0 - 1000,pt,0.0021490923784345537
+66+,,0 - 1000,ride,0.02295994965810904
+66+,,0 - 1000,walk,0.2575787709607315
+66+,,1000 - 2000,bike,0.0035514016618607464
+66+,,1000 - 2000,car,0.010247207739564603
+66+,,1000 - 2000,pt,0.038928474608520475
+66+,,1000 - 2000,ride,0.0
+66+,,1000 - 2000,walk,0.03190855054479069
+66+,,2000 - 5000,bike,0.036156401682909046
+66+,,2000 - 5000,car,0.07698132112897955
+66+,,2000 - 5000,pt,0.04653332577176314
+66+,,2000 - 5000,ride,0.04241233610977728
+66+,,2000 - 5000,walk,0.025217249789610763
+66+,,5000 - 10000,bike,0.016762476294743575
+66+,,5000 - 10000,car,0.059790639433165135
+66+,,5000 - 10000,pt,0.017783802265883077
+66+,,5000 - 10000,ride,0.005252547907894181
+66+,,5000 - 10000,walk,0.004080046754010281
+66+,,10000 - 20000,bike,0.007477237812485118
+66+,,10000 - 20000,car,0.07499737275500735
+66+,,10000 - 20000,pt,0.013870515586087259
+66+,,10000 - 20000,ride,0.02934437128655692
+66+,,10000 - 20000,walk,0.0
+66+,,20000+,bike,0.014994460777765128
+66+,,20000+,car,0.025914263061886596
+66+,,20000+,pt,0.0
+66+,,20000+,ride,0.012050219999664736
+66+,,20000+,walk,0.0
+,very_low,0 - 1000,bike,0.1532158010608138
+,very_low,0 - 1000,car,0.0022992229465424972
+,very_low,0 - 1000,pt,0.0
+,very_low,0 - 1000,ride,0.03743723404808968
+,very_low,0 - 1000,walk,0.24416605035309982
+,very_low,1000 - 2000,bike,0.010165684107561896
+,very_low,1000 - 2000,car,0.055474844571949046
+,very_low,1000 - 2000,pt,0.0
+,very_low,1000 - 2000,ride,0.01679227909381634
+,very_low,1000 - 2000,walk,0.036048668714502054
+,very_low,2000 - 5000,bike,0.00195701458886808
+,very_low,2000 - 5000,car,0.03718202951888427
+,very_low,2000 - 5000,pt,0.0
+,very_low,2000 - 5000,ride,0.017829899489206928
+,very_low,2000 - 5000,walk,0.01860019184961413
+,very_low,5000 - 10000,bike,0.01012127475029992
+,very_low,5000 - 10000,car,0.06487202492553155
+,very_low,5000 - 10000,pt,0.07066048413214551
+,very_low,5000 - 10000,ride,0.08909675734607188
+,very_low,5000 - 10000,walk,0.004428275586711176
+,very_low,10000 - 20000,bike,0.0
+,very_low,10000 - 20000,car,0.0251862199038447
+,very_low,10000 - 20000,pt,0.002267077625873906
+,very_low,10000 - 20000,ride,0.07113136731886273
+,very_low,10000 - 20000,walk,0.0
+,very_low,20000+,bike,0.0
+,very_low,20000+,car,0.031067598067710082
+,very_low,20000+,pt,0.0
+,very_low,20000+,ride,0.0
+,very_low,20000+,walk,0.0
+,low,0 - 1000,bike,0.0196760051504376
+,low,0 - 1000,car,0.02902912226607395
+,low,0 - 1000,pt,0.0
+,low,0 - 1000,ride,0.043838736889225995
+,low,0 - 1000,walk,0.203987900430012
+,low,1000 - 2000,bike,0.0012606939749368246
+,low,1000 - 2000,car,0.020909193514941436
+,low,1000 - 2000,pt,0.028325839466482206
+,low,1000 - 2000,ride,0.0
+,low,1000 - 2000,walk,0.05103790341439842
+,low,2000 - 5000,bike,0.021395181328414455
+,low,2000 - 5000,car,0.11458194569966466
+,low,2000 - 5000,pt,0.020198639756178433
+,low,2000 - 5000,ride,0.015237395325772105
+,low,2000 - 5000,walk,0.03562454824847543
+,low,5000 - 10000,bike,0.002644965095335015
+,low,5000 - 10000,car,0.1153231443022159
+,low,5000 - 10000,pt,0.014406782791496051
+,low,5000 - 10000,ride,0.03275498205334363
+,low,5000 - 10000,walk,0.01127037355667964
+,low,10000 - 20000,bike,0.0050430067614131244
+,low,10000 - 20000,car,0.11257598181811466
+,low,10000 - 20000,pt,0.03155768138849295
+,low,10000 - 20000,ride,0.006216681509679064
+,low,10000 - 20000,walk,0.0
+,low,20000+,bike,0.00995357862548733
+,low,20000+,car,0.037246786798481944
+,low,20000+,pt,0.008219691423412924
+,low,20000+,ride,0.007683238410834419
+,low,20000+,walk,0.0
+,medium,0 - 1000,bike,0.06300190405343134
+,medium,0 - 1000,car,0.02494604812703637
+,medium,0 - 1000,pt,0.0020462680104455667
+,medium,0 - 1000,ride,0.008119978745958954
+,medium,0 - 1000,walk,0.14654998631682875
+,medium,1000 - 2000,bike,0.030830795362573382
+,medium,1000 - 2000,car,0.041911032104670426
+,medium,1000 - 2000,pt,0.0018127826809055151
+,medium,1000 - 2000,ride,0.015511902827120463
+,medium,1000 - 2000,walk,0.028513215726045062
+,medium,2000 - 5000,bike,0.023720339845668167
+,medium,2000 - 5000,car,0.15739466891350515
+,medium,2000 - 5000,pt,0.010608541185101725
+,medium,2000 - 5000,ride,0.03880510346799283
+,medium,2000 - 5000,walk,0.015831627715856677
+,medium,5000 - 10000,bike,0.014309687263366521
+,medium,5000 - 10000,car,0.11498642983864431
+,medium,5000 - 10000,pt,0.0026495681031093363
+,medium,5000 - 10000,ride,0.0175076002265085
+,medium,5000 - 10000,walk,0.003421461062573791
+,medium,10000 - 20000,bike,0.0031041989149803027
+,medium,10000 - 20000,car,0.07284910443303544
+,medium,10000 - 20000,pt,0.011494005595994542
+,medium,10000 - 20000,ride,0.013323325617900582
+,medium,10000 - 20000,walk,0.0
+,medium,20000+,bike,0.00043073779348276863
+,medium,20000+,car,0.11500699389312388
+,medium,20000+,pt,0.0008016637564945563
+,medium,20000+,ride,0.02051102841764511
+,medium,20000+,walk,0.0
+,high,0 - 1000,bike,0.014414229840746558
+,high,0 - 1000,car,0.06682180229718465
+,high,0 - 1000,pt,0.0
+,high,0 - 1000,ride,0.010449433548602392
+,high,0 - 1000,walk,0.05664303199739918
+,high,1000 - 2000,bike,0.01085380802477583
+,high,1000 - 2000,car,0.05759209320059677
+,high,1000 - 2000,pt,0.0
+,high,1000 - 2000,ride,0.02799037577983742
+,high,1000 - 2000,walk,0.007464625767411693
+,high,2000 - 5000,bike,0.04439384384338453
+,high,2000 - 5000,car,0.14495017848884723
+,high,2000 - 5000,pt,0.014387613853785982
+,high,2000 - 5000,ride,0.04305883377108926
+,high,2000 - 5000,walk,0.015147780802465219
+,high,5000 - 10000,bike,0.016264173481386875
+,high,5000 - 10000,car,0.13048730077454793
+,high,5000 - 10000,pt,0.003988150691210621
+,high,5000 - 10000,ride,0.014406014685132227
+,high,5000 - 10000,walk,0.009743041051192577
+,high,10000 - 20000,bike,0.0021943542456351987
+,high,10000 - 20000,car,0.07718946953694708
+,high,10000 - 20000,pt,0.010116263202447193
+,high,10000 - 20000,ride,0.013478806666944308
+,high,10000 - 20000,walk,0.0009668579540749592
+,high,20000+,bike,0.005252208448517857
+,high,20000+,car,0.15437673296803223
+,high,20000+,pt,0.008695068694669095
+,high,20000+,ride,0.038673906383135136
+,high,20000+,walk,0.0
+,very_high,0 - 1000,bike,0.016488297190040684
+,very_high,0 - 1000,car,0.008237168359539967
+,very_high,0 - 1000,pt,0.009258723235006186
+,very_high,0 - 1000,ride,0.04139259894777343
+,very_high,0 - 1000,walk,0.012047068679416168
+,very_high,1000 - 2000,bike,0.032853716527926534
+,very_high,1000 - 2000,car,0.010643861036026697
+,very_high,1000 - 2000,pt,0.007535327737950974
+,very_high,1000 - 2000,ride,0.0
+,very_high,1000 - 2000,walk,0.015070655475901949
+,very_high,2000 - 5000,bike,0.02893005603516004
+,very_high,2000 - 5000,car,0.283424270226448
+,very_high,2000 - 5000,pt,0.0
+,very_high,2000 - 5000,ride,0.153781762462469
+,very_high,2000 - 5000,walk,0.0007356547766904847
+,very_high,5000 - 10000,bike,0.003422965816339796
+,very_high,5000 - 10000,car,0.12262299811175442
+,very_high,5000 - 10000,pt,0.011660134175879763
+,very_high,5000 - 10000,ride,0.005835757418666393
+,very_high,5000 - 10000,walk,0.0
+,very_high,10000 - 20000,bike,0.0
+,very_high,10000 - 20000,car,0.07820627918213571
+,very_high,10000 - 20000,pt,0.015070655475901949
+,very_high,10000 - 20000,ride,0.0674310273414233
+,very_high,10000 - 20000,walk,0.0
+,very_high,20000+,bike,0.0
+,very_high,20000+,car,0.07535102178754859
+,very_high,20000+,pt,0.0
+,very_high,20000+,ride,0.0
+,very_high,20000+,walk,0.0
diff --git a/src/test/java/org/matsim/run/EmissionAnalysisOutputTest.java b/src/test/java/org/matsim/run/EmissionAnalysisOutputTest.java
new file mode 100644
index 0000000..cfeeab0
--- /dev/null
+++ b/src/test/java/org/matsim/run/EmissionAnalysisOutputTest.java
@@ -0,0 +1,115 @@
+package org.matsim.run;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.io.TempDir;
+import org.matsim.api.core.v01.Coord;
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.TransportMode;
+import org.matsim.api.core.v01.population.*;
+import org.matsim.application.MATSimApplication;
+import org.matsim.core.config.Config;
+import org.matsim.core.config.ConfigUtils;
+import org.matsim.core.population.PersonUtils;
+import org.matsim.core.population.PopulationUtils;
+import org.matsim.core.utils.io.IOUtils;
+import org.matsim.testcases.MatsimTestUtils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.matsim.application.ApplicationUtils.globFile;
+
+class EmissionAnalysisOutputTest {
+
+ @RegisterExtension
+ public MatsimTestUtils utils = new MatsimTestUtils();
+
+ @TempDir
+ public Path p;
+
+ private final static Id ptPersonId = Id.createPersonId("Hoyerswerda-Cottbus_CAR");
+
+ @Test
+ void runEmissionAnalysisOutputTest() throws IOException {
+ Config config = ConfigUtils.loadConfig(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION));
+
+ Path inputPath = p.resolve("emissions-test-population.xml.gz");
+
+ Population population = PopulationUtils.createPopulation(config);
+ PopulationFactory fac = population.getFactory();
+ Person person = fac.createPerson(ptPersonId);
+ Plan plan = PopulationUtils.createPlan(person);
+
+// home in hoyerswerda, nearest link 28922425#0
+ Activity home = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24));
+ home.setEndTime(8 * 3600);
+ Activity home2 = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24));
+ home2.setEndTime(19 * 3600);
+// work in hoyerswerda, nearest link(s): 686055693#1, -686055693#1
+ Activity work = fac.createActivityFromCoord("work_2400", new Coord(863866.47,5710961.86));
+ work.setEndTime(17 * 3600 + 25 * 60);
+
+ Leg leg = fac.createLeg(TransportMode.car);
+
+ plan.addActivity(home);
+ plan.addLeg(leg);
+ plan.addActivity(work);
+ plan.addLeg(leg);
+ plan.addActivity(home2);
+
+ person.addPlan(plan);
+ PersonUtils.setIncome(person, 1000.);
+ person.getAttributes().putAttribute("subpopulation", "person");
+ population.addPerson(person);
+
+ new PopulationWriter(population).write(inputPath.toString());
+
+ assert MATSimApplication.execute(LausitzScenario.class, config,
+ "--1pct",
+ "--iterations", "0",
+ "--output", utils.getOutputDirectory(),
+ "--config:plans.inputPlansFile", inputPath.toString(),
+ "--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code";
+
+
+ Path csvPath = globFile(Path.of(utils.getOutputDirectory() + "/analysis/emissions"), "*emissions_per_link.csv*");
+
+ Map nonZeroLinks = new HashMap<>();
+
+ try {
+ BufferedReader reader = IOUtils.getBufferedReader(csvPath.toUri().toURL());
+ String line;
+
+// skip header
+ reader.readLine();
+
+ while ((line = reader.readLine()) != null) {
+ String[] parts = line.split(",");
+
+// if first value (CO) is zero, all others are too
+ if (Double.parseDouble(parts[1]) == 0.) {
+ continue;
+ }
+
+ Double[] values = new Double[23];
+
+ for (int i = 1; i < parts.length; i++) {
+ values[i - 1] = Double.parseDouble(parts[i]);
+ }
+
+ nonZeroLinks.put(parts[0], values);
+ }
+ } finally {
+
+ }
+
+ Assertions.assertFalse(nonZeroLinks.isEmpty());
+ Assertions.assertTrue(nonZeroLinks.containsKey("28922425#0"));
+ Assertions.assertTrue(nonZeroLinks.containsKey("-686055693#1"));
+ }
+}
diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java
index 1efc69d..3b1bd33 100644
--- a/src/test/java/org/matsim/run/RunIntegrationTest.java
+++ b/src/test/java/org/matsim/run/RunIntegrationTest.java
@@ -1,27 +1,150 @@
package org.matsim.run;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.io.TempDir;
+import org.matsim.api.core.v01.Coord;
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.Scenario;
+import org.matsim.api.core.v01.TransportMode;
+import org.matsim.api.core.v01.events.PersonEntersVehicleEvent;
+import org.matsim.api.core.v01.events.handler.PersonEntersVehicleEventHandler;
+import org.matsim.api.core.v01.network.Network;
+import org.matsim.api.core.v01.population.*;
import org.matsim.application.MATSimApplication;
+import org.matsim.core.api.experimental.events.EventsManager;
+import org.matsim.core.config.Config;
+import org.matsim.core.config.ConfigUtils;
import org.matsim.core.events.EventsUtils;
+import org.matsim.core.network.NetworkUtils;
+import org.matsim.core.population.PersonUtils;
+import org.matsim.core.population.PopulationUtils;
+import org.matsim.core.scenario.ScenarioUtils;
+import org.matsim.pt.transitSchedule.api.*;
+import org.matsim.simwrapper.SimWrapperConfigGroup;
import org.matsim.testcases.MatsimTestUtils;
-import java.io.File;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
-public class RunIntegrationTest {
+import static org.matsim.application.ApplicationUtils.globFile;
+
+class RunIntegrationTest {
@RegisterExtension
public MatsimTestUtils utils = new MatsimTestUtils();
+ @TempDir
+ public Path p;
+
+ private final static Id ptPersonId = Id.createPersonId("Hoyerswerda-Cottbus_PT");
+
+ @Test
+ void runScenario() {
+ Config config = ConfigUtils.loadConfig(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION));
+ ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class).defaultDashboards = SimWrapperConfigGroup.Mode.disabled;
+
+ assert MATSimApplication.execute(LausitzScenario.class, config,
+ "--1pct",
+ "--iterations", "1",
+ "--config:plans.inputPlansFile", "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/lausitz/input/v1.1/lausitz-v1.1-1pct.plans-initial.xml.gz",
+ "--output", utils.getOutputDirectory(),
+ "--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code";
+ }
+
+ @Test
+ void runScenarioIncludingDrt() {
+ Config config = ConfigUtils.loadConfig(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION));
+ ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class).defaultDashboards = SimWrapperConfigGroup.Mode.disabled;
+
+ assert MATSimApplication.execute(RunLausitzDrtScenario.class, config,
+ "--1pct",
+ "--iterations", "1",
+ "--config:plans.inputPlansFile", "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/lausitz/input/v1.1/lausitz-v1.1-1pct.plans-initial.xml.gz",
+ "--output", utils.getOutputDirectory(),
+ "--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code";
+
+ }
+
@Test
- public void runScenario() {
+ void runScenarioIncludingAdditionalPtLine() {
+ Config config = ConfigUtils.loadConfig(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION));
+ ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class).defaultDashboards = SimWrapperConfigGroup.Mode.disabled;
+
+ Path inputPath = p.resolve("pt-test-population.xml.gz");
+
+ Population population = PopulationUtils.createPopulation(config);
+ PopulationFactory fac = population.getFactory();
+ Person person = fac.createPerson(ptPersonId);
+ Plan plan = PopulationUtils.createPlan(person);
+
+// home in hoyerswerda
+ Activity home = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24));
+ home.setEndTime(8 * 3600);
+ Activity home2 = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24));
+ home2.setEndTime(19 * 3600);
+// work in cottbus
+ Activity work = fac.createActivityFromCoord("work_2400", new Coord(867489.48,5746587.47));
+ work.setEndTime(17 * 3600 + 25 * 60);
+
+ Leg leg = fac.createLeg(TransportMode.pt);
+
+ plan.addActivity(home);
+ plan.addLeg(leg);
+ plan.addActivity(work);
+ plan.addLeg(leg);
+ plan.addActivity(home2);
+
+ person.addPlan(plan);
+ PersonUtils.setIncome(person, 1000.);
+ person.getAttributes().putAttribute("subpopulation", "person");
+ population.addPerson(person);
+
+ new PopulationWriter(population).write(inputPath.toString());
- assert MATSimApplication.execute(LausitzScenario.class,
+ assert MATSimApplication.execute(RunLausitzPtScenario.class, config,
"--1pct",
"--iterations", "1",
- "--config:plans.inputPlansFile", "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/lausitz/input/v1.0/lausitz-v1.0-1pct.plans-initial.xml.gz",
"--output", utils.getOutputDirectory(),
+ "--config:plans.inputPlansFile", inputPath.toString(),
"--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code";
+ Scenario scenario = ScenarioUtils.createScenario(ConfigUtils.createConfig());
+
+ new TransitScheduleReader(scenario).readFile(globFile(Path.of(utils.getOutputDirectory()), "*output_transitSchedule*").toString());
+ TransitSchedule schedule = scenario.getTransitSchedule();
+
+ Network network = NetworkUtils.readNetwork(globFile(Path.of(utils.getOutputDirectory()), "*output_network.*").toString());
+
+ Assertions.assertTrue(schedule.getFacilities().containsKey(Id.create("regio_135278.2_0", TransitStopFacility.class)));
+ Assertions.assertTrue(schedule.getTransitLines().containsKey(Id.create("RE-VSP1", TransitLine.class)));
+ Assertions.assertEquals(2, schedule.getTransitLines().get(Id.create("RE-VSP1", TransitLine.class)).getRoutes().size());
+ Assertions.assertEquals(20, schedule.getTransitLines().get(Id.create("RE-VSP1", TransitLine.class))
+ .getRoutes().get(Id.create("RE-VSP1_0", TransitRoute.class)).getDepartures().size());
+ Assertions.assertTrue(network.getLinks().containsKey(Id.createLinkId("pt_vsp_1")));
+ Assertions.assertTrue(network.getNodes().containsKey(Id.createNodeId("pt_short_2476.2")));
+
+ EventsManager manager = EventsUtils.createEventsManager();
+ manager.addHandler(new PersonEntersPtVehicleEventHandler());
+ EventsUtils.readEvents(manager, globFile(Path.of(utils.getOutputDirectory()), "*output_events*").toString());
+
+ Assertions.assertEquals(2, PersonEntersPtVehicleEventHandler.enterEvents.size());
+// to cottbus: train at 8:22, from cottbus train at 17:53
+ Assertions.assertEquals("pt_RE-VSP1_0_9", PersonEntersPtVehicleEventHandler.enterEvents.get(0).getVehicleId().toString());
+ Assertions.assertEquals("pt_RE-VSP1_1_18", PersonEntersPtVehicleEventHandler.enterEvents.get(1).getVehicleId().toString());
+
+ }
+
+ private static final class PersonEntersPtVehicleEventHandler implements PersonEntersVehicleEventHandler {
+ static List enterEvents = new ArrayList<>();
+
+ @Override
+ public void handleEvent(PersonEntersVehicleEvent event) {
+ if (event.getPersonId().equals(ptPersonId) && event.getVehicleId().toString().contains("RE-VSP1")) {
+ enterEvents.add(event);
+ }
+ }
}
}