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); + } + } } }