diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index e322411a..11507255 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -94,4 +94,4 @@ jobs:
path: staging
env:
- MAVEN_OPTS: -Xmx10G
\ No newline at end of file
+ MAVEN_OPTS: -Xmx512m
\ No newline at end of file
diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml
index 4ef94b1d..55ba46d1 100644
--- a/.github/workflows/publish.yaml
+++ b/.github/workflows/publish.yaml
@@ -17,4 +17,4 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
env:
- MAVEN_OPTS: -Xmx10G
\ No newline at end of file
+ MAVEN_OPTS: -Xmx512m
\ No newline at end of file
diff --git a/CITATION.cff b/CITATION.cff
new file mode 100644
index 00000000..e24476fd
--- /dev/null
+++ b/CITATION.cff
@@ -0,0 +1,38 @@
+# This CITATION.cff file was generated with cffinit.
+# Visit https://bit.ly/cffinit to generate yours today!
+
+cff-version: 1.2.0
+title: The MATSim Open Kelheim Scenario
+message: >-
+ If you use this software, please cite it using the
+ metadata from this file.
+type: software
+authors:
+ - given-names: Tilmann
+ family-names: Schlenther
+ email: schlenther@vsp.tu-berlin.de
+ affiliation: Technische Universität Berlin
+ orcid: 'https://orcid.org/0000-0001-6781-6918'
+ - given-names: Chengqi
+ family-names: Lu
+ email: lu@vsp.tu-berlin.de
+ affiliation: Technische Universität Berlin
+ - given-names: Christian
+ family-names: Rakow
+ email: rakow@vsp.tu-berlin.de
+ affiliation: Technische Universität Berlin
+ - given-names: Simon
+ family-names: Meinhardt
+ email: meinhardt@vsp.tu-berlin.de
+ affiliation: Technische Universität Berlin
+ - given-names: Kai
+ family-names: Nagel
+ email: nagel@vsp.tu-berlin.de
+ affiliation: Technische Universität Berlin
+ orcid: 'https://orcid.org/0000-0003-2775-6898'
+url: "https://github.com/matsim-scenarios/matsim-kelheim"
+doi: 10.5281/zenodo.8322240
+date-released: 2023-09-06
+year: 2023
+version: 3.0
+license: AGPL-3.0
diff --git a/README.md b/README.md
index bc944805..5c1eff26 100644
--- a/README.md
+++ b/README.md
@@ -2,14 +2,19 @@
[![Build Status](https://github.com/matsim-scenarios/matsim-kelheim/actions/workflows/build.yaml/badge.svg)](https://github.com/matsim-scenarios/matsim-kelheim/actions/workflows/build.yaml)
![license](https://img.shields.io/github/license/matsim-scenarios/matsim-kelheim.svg)
+[![DOI (v3.0)](https://zenodo.org/badge/360167859.svg)](https://zenodo.org/badge/latestdoi/360167859)
![JDK](https://img.shields.io/badge/JDK-17+-green.svg)
![Kelheim MATSim network and agents](visualization-kelheim.png "Kelheim MATSim network and agents")
+
+
+
+
### About this project
-This repository provides an open MATSim transport model for Kelheim, provided by the [Transport Systems Planning and Transport Telematics group](https://www.vsp.tu-berlin.de) of [Technische Universität Berlin](http://www.tu-berlin.de).
+This repository provides an open MATSim transport model for Kelheim, provided by the [Transport Systems Planning and Transport Telematics group](https://www.tu.berlin/vsp) of [Technische Universität Berlin](http://www.tu-berlin.de).
@@ -24,9 +29,11 @@ The **MATSim input files, output files, analysis data and visualizations** are l
**Other data files**, in particular in `original-input-data`, have their own individual licenses that need to be individually clarified with the copyright holders.
-### Note
+The input plans (person transport demand) for this project were generated based on data provided by [Senozon AG](https://senozon.com/).
+
+### Note (where to find input and output)
-Handling of large files within git is not without problems (git lfs files are not included in the zip download; we have to pay; ...). In consequence, large files, both on the input and on the output side, reside at https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/kelheim .
+Handling of large files within git is not without problems (git lfs files are not included in the zip download; we have to pay; ...). In consequence, large files, both on the input and on the output side, reside at [the public matsim-kelheim data repo](https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/kelheim).
----
### Run the MATSim Kelheim scenario
@@ -42,7 +49,8 @@ It can be used by using either of these methods:
1. Set up the project in your IDE.
1. Make sure the project is configured as maven project.
-1. Run the JAVA class `src/main/java/org/matsim/run/RunKelheimScenario.java` with the following program argument `run`. Add '--1pct' for test runs with a smaller sample size.
+1. Run the JAVA class `src/main/java/org/matsim/run/RunKelheimScenario.java` with the following program argument `run`.
+ 1. Add '--1pct' for test runs with a smaller sample size. Be aware that the model is calibrated with 25 pct, and outputs for 1 pct might be a little off.
1. "Open" the output directory. You can drag files into VIA as was already done above.
1. Edit the config file or adjust the run class. Re-run MATSim.
@@ -51,8 +59,26 @@ It can be used by using either of these methods:
1. Open the cmd and go to your project directory
2. Build the scenario using `mvnw package`. Add the option `-Dskiptests=true` in order to skip tests and speed up the process.
-3. There should be a file directly in the `matsim-kelheim` directory with name approximately as `matsim-kelheim-2.x.jar`.
-4. Run this file from the command line using `java -jar matsim-kelheim-2.x.jar --help` to see all possible options.
+3. There should be a file directly in the `matsim-kelheim` directory with name approximately as `matsim-kelheim-3.x-SNAPSHOT-.jar`.
+4. Run this file from the command line using `java -jar matsim-kelheim-3.x-SNAPSHOT-.jar --help` to see all possible options.
1. For example, one can disable lanes or run smaller sample sizes using the available options
-5. Start this scenario using the default config by running `java -jar matsim-kelheim-2.x.jar`.
-6. "Open" the output directory. You can drag files into VIA as was already done above.
+5. Start this scenario using the default config by running `java -jar matsim-kelheim-3.x-SNAPSHOT-.jar`.
+ 1. If you want to run the scenario somewhere else, e.g. on a computation cluster, make sure to not only copy the jar but also the 'input' directory and put it right next to the jar.
+6. "Open" the output directory.
+ 1. You can drag files into VIA as was already done above.
+ 2. You can also browse the output directory on vsp.berlin/simwrapper and analyze some of your results with interactive dashboards.
+
+----
+### Results and analysis
+
+Here are the most common ways to analyse and visualize the results (and inputs):
+
+1. [Simunto VIA](https://www.simunto.com/via/)
+2. [SimWrapper](https://www.vsp.berlin/simwrapper)
+ 1. (use Google for the best experience)
+ 2. Browse your local output directory or [the public matsim-kelheim data repo](https://vsp.berlin/simwrapper/public/de/kelheim)
+ 2. Explore and create many interactive visualisations and dashboards
+3. Analysis the output .csv tables using the R language and [the matsim-r package](https://github.com/matsim-vsp/matsim-r)
+
+If you have questions, feel free to contact us [(VSP)](https://www.tu.berlin/vsp) any time :)
+
diff --git a/input/test.config.xml b/input/test.config.xml
index 17261b83..a9f7e502 100644
--- a/input/test.config.xml
+++ b/input/test.config.xml
@@ -67,8 +67,8 @@
-
-
+
+
@@ -87,56 +87,56 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
@@ -145,11 +145,12 @@
-
+
+
-
-
+
+
@@ -158,46 +159,48 @@
+
+
+
+
+
-
-
-
+
-
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
@@ -206,7 +209,7 @@
-
+
@@ -215,10 +218,11 @@
-
+
+
diff --git a/input/test.with-drt.config.xml b/input/test.with-drt.config.xml
index e5d76695..d32dc581 100644
--- a/input/test.with-drt.config.xml
+++ b/input/test.with-drt.config.xml
@@ -22,10 +22,10 @@
-
-
-
-
+
+
+
+
@@ -33,12 +33,12 @@
-
+
-
-
+
+
@@ -72,72 +72,70 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
@@ -146,11 +144,12 @@
-
+
+
-
-
+
+
@@ -159,55 +158,62 @@
+
+
+
+
-
-
+
+
-
-
+
+
-
+
+
+
-
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
@@ -216,7 +222,7 @@
-
+
@@ -225,10 +231,11 @@
-
+
+
@@ -240,44 +247,62 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -305,17 +330,16 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/input/v3.0/kelheim-v3.0-25pct.kexi.config.xml b/input/v3.0/kelheim-v3.0-25pct.kexi.config.xml
new file mode 100644
index 00000000..823714fe
--- /dev/null
+++ b/input/v3.0/kelheim-v3.0-25pct.kexi.config.xml
@@ -0,0 +1,343 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/input/v3.0/kelheim-v3.0-config.xml b/input/v3.0/kelheim-v3.0-config.xml
index 649c572f..4b7ba234 100644
--- a/input/v3.0/kelheim-v3.0-config.xml
+++ b/input/v3.0/kelheim-v3.0-config.xml
@@ -163,66 +163,63 @@
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 06c4a421..132d2965 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
matsim-all
- 16.0-PR2680
+ 16.0-PR2750
@@ -208,7 +208,7 @@
1
false
- @{argLine} -Xmx9500m -Djava.awt.headless=true -Dmatsim.preferLocalDtds=true
+ @{argLine} -Xmx6500m -Djava.awt.headless=true -Dmatsim.preferLocalDtds=true
diff --git a/src/main/R/drtAnalysis/kpi_averaging.R b/src/main/R/drtAnalysis/kpi_averaging.R
new file mode 100644
index 00000000..f4997782
--- /dev/null
+++ b/src/main/R/drtAnalysis/kpi_averaging.R
@@ -0,0 +1,111 @@
+#####libraries####
+library(stringr)
+library(tidyverse)
+
+#####global variables####
+path_to_data <- "path/to/data (folder of a specific case, with different seeds)"
+stats = c("mean","median","sd" ,"max", "min")
+
+##### Collect all folder names####
+folders_list<-list.files(path_to_data,full.names = TRUE)
+folders_seeded = list()
+
+for(i in 1:length(folders_list)){
+ if (endsWith(folders_list[i],".tsv")){
+ next
+ }
+
+ case_name = tail(str_split(folders_list[i],"-")[[1]],n = 1)
+
+ if(!case_name %in% names(folders_seeded)){
+ folders_seeded[[case_name]] = folders_list[i]
+ }else{
+ folders_seeded[[case_name]] = append(folders_seeded[[case_name]],folders_list[i])
+ }
+}
+
+#########################################
+#####Reading and averaging drt tables####
+folders_drt_averaged_table = list()
+
+for(case_name in names(folders_seeded)){
+ for(folder in folders_seeded[[case_name]]){
+ files_list<- list.files(paste0(folder,"/analysis-drt-service-quality"),full.names = TRUE)
+ drt_KPI_file <- files_list[grepl(pattern = "drt_KPI.tsv",files_list)]
+ cat("processing ",drt_KPI_file," \r\n")
+ drt_KPI_table <- read.delim(drt_KPI_file)
+
+ if(!case_name %in% names(folders_drt_averaged_table)){
+ folders_drt_averaged_table[[case_name]] = drt_KPI_table
+ }else{
+ folders_drt_averaged_table[[case_name]] = rbind(folders_drt_averaged_table[[case_name]],drt_KPI_table)
+ }
+
+ }
+
+ tbl_colnames = c("stat",colnames(folders_drt_averaged_table[[case_name]]))
+ result_tibble = tbl_colnames %>% purrr::map_dfc(setNames, object = list(numeric()))
+ for(stat in stats){
+ func = get(stat)
+ new_row = c(stat)
+ for(column in colnames(folders_drt_averaged_table[[case_name]])){
+ new_row = append(new_row,func(folders_drt_averaged_table[[case_name]][[column]]))
+ }
+
+ result_tibble = rbind(result_tibble,new_row)
+ }
+ colnames(result_tibble) = tbl_colnames
+
+ folders_drt_averaged_table[[case_name]] = result_tibble
+
+}
+
+print(folders_drt_averaged_table)
+
+#Write averaged drt tables####
+for(case_name in names(folders_drt_averaged_table)){
+ write.table(folders_drt_averaged_table[[case_name]],paste0(path_to_data, "/kpi_summary_drt_", case_name, ".tsv"),quote = FALSE,row.names = FALSE)
+}
+
+
+
+#########################################
+#####Reading and averaging av tables#####
+folders_av_averaged_table = list()
+for(case_name in names(folders_seeded)){
+ for(folder in folders_seeded[[case_name]]){
+ files_list<- list.files(paste0(folder,"/analysis-drt-service-quality"),full.names = TRUE)
+ av_KPI_file <- files_list[grepl(pattern = "av_KPI.tsv",files_list)]
+ cat("processing ",av_KPI_file," \r\n")
+ av_KPI_table <- read.delim(av_KPI_file)
+
+ if(!case_name %in% names(folders_av_averaged_table)){
+ folders_av_averaged_table[[case_name]] = av_KPI_table
+ }else{
+ folders_av_averaged_table[[case_name]] = rbind(folders_av_averaged_table[[case_name]],av_KPI_table)
+ }
+ }
+
+ tbl_colnames = c("stat",colnames(folders_av_averaged_table[[case_name]]))
+ result_tibble = tbl_colnames %>% purrr::map_dfc(setNames, object = list(numeric()))
+ for(stat in stats){
+ func = get(stat)
+ new_row = c(stat)
+ for(column in colnames(folders_av_averaged_table[[case_name]])){
+ new_row = append(new_row,func(folders_av_averaged_table[[case_name]][[column]]))
+ }
+ result_tibble = rbind(result_tibble,new_row)
+ }
+ colnames(result_tibble) = tbl_colnames
+ folders_av_averaged_table[[case_name]] = result_tibble
+}
+
+print(folders_av_averaged_table)
+
+#Write averaged av tables####
+for(case_name in names(folders_av_averaged_table)){
+ write.table(folders_av_averaged_table[[case_name]],paste0(path_to_data, "/kpi_summary_av_",case_name,".tsv"),quote = FALSE,row.names = FALSE)
+}
+
+
+
diff --git a/src/main/R/mid.csv b/src/main/R/mid.csv
deleted file mode 100644
index 12275451..00000000
--- a/src/main/R/mid.csv
+++ /dev/null
@@ -1,31 +0,0 @@
-dist_group,mode,share
-0 - 1000,car,0.0557
-1000 - 2000,car,0.0758
-2000 - 5000,car,0.1507
-5000 - 10000,car,0.1139
-10000 - 20000,car,0.098
-20000+,car,0.0935
-0 - 1000,walk,0.0804
-1000 - 2000,walk,0.0318
-2000 - 5000,walk,0.0165
-5000 - 10000,walk,0.0044
-10000 - 20000,walk,0.0009
-20000+,walk,0.0006
-0 - 1000,pt,0.001
-1000 - 2000,pt,0.0012
-2000 - 5000,pt,0.0086
-5000 - 10000,pt,0.007
-10000 - 20000,pt,0.0061
-20000+,pt,0.0101
-0 - 1000,bike,0.0247
-1000 - 2000,bike,0.0242
-2000 - 5000,bike,0.0235
-5000 - 10000,bike,0.0063
-10000 - 20000,bike,0.0025
-20000+,bike,0.0019
-0 - 1000,ride,0.0144
-1000 - 2000,ride,0.0212
-2000 - 5000,ride,0.0447
-5000 - 10000,ride,0.0316
-10000 - 20000,ride,0.0257
-20000+,ride,0.0265
diff --git a/src/main/R/mid_adj.csv b/src/main/R/mid_adj.csv
deleted file mode 100644
index ddfca9f3..00000000
--- a/src/main/R/mid_adj.csv
+++ /dev/null
@@ -1,31 +0,0 @@
-dist_group,mode,share
-0 - 1000,car,0.04917652958739915
-1000 - 2000,car,0.04956785176611809
-2000 - 5000,car,0.10849424221801696
-5000 - 10000,car,0.15076819523354637
-10000 - 20000,car,0.14211152124057438
-20000+,car,0.11194215806986973
-0 - 1000,walk,0.07098371595739482
-1000 - 2000,walk,0.0207949562818279
-2000 - 5000,walk,0.011878931629709887
-5000 - 10000,walk,0.005824232300505742
-10000 - 20000,walk,0.0013051058073113972
-20000+,walk,0.0007183453993788432
-0 - 1000,pt,0.00088288203927108
-1000 - 2000,pt,0.000784715331389732
-2000 - 5000,pt,0.00619144315245485
-5000 - 10000,pt,0.009265824114440954
-10000 - 20000,pt,0.008845717138443916
-20000+,pt,0.012092147556210528
-0 - 1000,bike,0.021807186369995676
-1000 - 2000,bike,0.0158250925163596
-2000 - 5000,bike,0.01691847838170802
-5000 - 10000,bike,0.00833924170299686
-10000 - 20000,bike,0.0036252939091983255
-20000+,bike,0.002274760431366337
-0 - 1000,ride,0.012713501365503551
-1000 - 2000,ride,0.013863304187885268
-2000 - 5000,ride,0.03218110568775951
-5000 - 10000,ride,0.04182857743090488
-10000 - 20000,ride,0.03726802138655879
-20000+,ride,0.03172692180589891
diff --git a/src/main/R/srv.R b/src/main/R/srv.R
index ec9f4c19..9ff94757 100644
--- a/src/main/R/srv.R
+++ b/src/main/R/srv.R
@@ -8,7 +8,7 @@ library(sf)
source("https://raw.githubusercontent.com/matsim-scenarios/matsim-duesseldorf/master/src/main/R/theme.R")
-setwd("PLEASE ADJUST TO YOUR LOCAL DIRECTORY FOR matsim-kelheim/src/main/R")
+setwd("D:/git/matsim-kelheim/src/main/R")
theme_set(theme_Publication(18))
@@ -23,7 +23,12 @@ shape <- st_read("../../../input/shp/dilutionArea.shp", crs=25832)
#########
sim_scale <- 4 # set to 4 for 25pct, 10 for 10pct, 100 for 1pct, ...
-f <- "../../../output/output-kelheim-25pct/" # set to run output directory
+#f <- "../../../output/output-kelheim-25pct/" # set to run output directory
+
+
+f <- "//sshfs.r/schlenther@cluster.math.tu-berlin.de/net/ils/matsim-kelheim/calibration-v3.0-noMgnUtl/runs/014-cnt/" # set to run output directory
+f <- "//sshfs.r/schlenther@cluster.math.tu-berlin.de/net/ils/matsim-kelheim/calibration-ride12/calibration-bike-3-mc/runs/009/" # set to run output directory
+
homes <- read_csv("https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/kelheim/kelheim-v3.0/input/kelheim-v3.0-homes.csv",
@@ -65,8 +70,7 @@ sim <- trips %>%
# Read survey data
########
-srv <- read_csv("mid_adj.csv") %>%
- mutate(main_mode=mode) %>%
+srv <- read_csv("../resources/kelheim_mode_share.csv") %>%
mutate(scaled_trips=122258 * 3.2 * share) %>%
mutate(source = "mid") %>%
mutate(dist_group=fct_relevel(dist_group, levels)) %>%
@@ -77,9 +81,9 @@ srv <- read_csv("mid_adj.csv") %>%
#######
srv_aggr <- srv %>%
- group_by(mode) %>%
+ group_by(main_mode) %>%
summarise(share=sum(share)) %>% # assume shares sum to 1
- mutate(mode=fct_relevel(mode, "walk", "bike", "pt", "ride", "car"))
+ mutate(mode=fct_relevel(main_mode, "walk", "bike", "pt", "ride", "car"))
aggr <- sim %>%
group_by(mode) %>%
@@ -109,7 +113,7 @@ combined + plot_layout(guides = "collect")
g <- arrangeGrob(p1_aggr, p2_aggr, ncol = 2)
g
-out <- file.path(f, "analysis-mode-choice")
+out <- file.path(f, "R-analysis-mode-choice")
if(!file.exists(out)){
print("creating analysis sub-directory")
dir.create(out)
@@ -122,6 +126,9 @@ ggsave(filename = "modal-split.png", path = out, g,
# Combined plot by distance
##########
+srv <- srv %>%
+ mutate(mode = main_mode)
+
total <- bind_rows(srv, sim) %>%
mutate(mode=fct_relevel(mode, "walk", "bike", "pt", "ride", "car"))
@@ -160,16 +167,15 @@ numTrips <- (shortDistance - sim_sum * tripShare) / (tripShare - 1)
# Distance distributions based on RegioStar data
##########################
-levels <- c("0 - 500", "500 - 1000", "1000 - 2000", "2000 - 5000", "5000 - 10000",
- "10000 - 20000", "20000 - 50000", "50000 - 100000", "100000+")
-
-breaks <-c (0, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, Inf)
+levels <- c("0 - 1000", "1000 - 2000", "2000 - 5000", "5000 - 10000", "10000 - 20000", "20000+")
+breaks <- c(0, 1000, 2000, 5000, 10000, 20000, Inf)
trips2 <- trips %>%
mutate(dist_group = cut(traveled_distance, breaks=breaks, labels=levels, right = F)) %>%
mutate(mode = fct_relevel(main_mode, "walk", "bike", "pt", "ride", "car"))
-rs <- read_csv("tidied-mode-share-per-distance.csv") %>%
+rs <- read_csv("../resources/kelheim_mode_share_per_dist.csv") %>%
+ mutate(mode = main_mode) %>%
mutate(source="rs")
sim <- trips2 %>%
@@ -182,7 +188,7 @@ sim <- mutate(sim, share=trips/sum(sim$trips))
total_distance_dist <- bind_rows(filter(rs, mode=="total_distance_distribution"), sim)
dist_order <- factor(total_distance_dist$dist_group, level = levels)
-dist_order <- fct_explicit_na(dist_order, "100000+")
+dist_order <- fct_explicit_na(dist_order, "20000+")
g <- ggplot(total_distance_dist, aes(y=share, x=source, fill=source)) +
@@ -209,7 +215,7 @@ by_distance <- bind_rows(filter(rs, mode!="total_distance_distribution"), sim) %
mutate(mode=fct_relevel(mode, "walk", "bike", "pt", "ride", "car"))
dist_order <- factor(by_distance$dist_group, level = levels)
-dist_order <- fct_explicit_na(dist_order, "100000+")
+dist_order <- fct_explicit_na(dist_order, "20000+")
g <- ggplot(by_distance, aes(y=share, x=source, fill=mode)) +
labs(subtitle = paste("Kelheim scenario", substring(f, 52)), x="distance [m]", y="share") +
@@ -222,3 +228,4 @@ g
ggsave(filename = "modal-distance-distribution-relative.png", path = out, g,
width = 12, height = 10, device='png', dpi=300)
+
diff --git a/src/main/java/org/matsim/analysis/postAnalysis/drt/DrtServiceQualityAnalysis.java b/src/main/java/org/matsim/analysis/postAnalysis/drt/DrtServiceQualityAnalysis.java
index 58d953f1..db49ee7f 100644
--- a/src/main/java/org/matsim/analysis/postAnalysis/drt/DrtServiceQualityAnalysis.java
+++ b/src/main/java/org/matsim/analysis/postAnalysis/drt/DrtServiceQualityAnalysis.java
@@ -31,7 +31,6 @@
import org.matsim.core.utils.gis.ShapeFileReader;
import org.matsim.core.utils.gis.ShapeFileWriter;
import org.matsim.core.utils.io.IOUtils;
-import org.matsim.run.RunKelheimScenario;
import org.matsim.utils.gis.shp2matsim.ShpGeometryUtils;
import org.matsim.vehicles.Vehicle;
import org.matsim.vehicles.VehicleType;
@@ -80,7 +79,7 @@ public Integer call() throws Exception {
Files.createDirectory(outputFolder);
}
- Config config = ConfigUtils.loadConfig(configPath.toString());
+ Config config = ConfigUtils.loadConfig(configPath.toString(), new MultiModeDrtConfigGroup(DrtWithExtensionsConfigGroup::new));
int lastIteration = config.controler().getLastIteration();
String runId = config.controler().getRunId();
Path folderOfLastIteration = Path.of(directory.toString() + "/ITERS/it." + lastIteration);
@@ -88,11 +87,6 @@ public Integer call() throws Exception {
List modes = new ArrayList<>();
for (DrtConfigGroup drtCfg : multiModeDrtConfigGroup.getModalElements()) {
modes.add(drtCfg.getMode());
- //only the KEXI (conventionally driven drt) should get companions
- if (drtCfg.getMode().equals(TransportMode.drt)) {
- DrtWithExtensionsConfigGroup drtWithExtensionsConfigGroup = (DrtWithExtensionsConfigGroup) drtCfg;
- RunKelheimScenario.addDrtCompanionParameters(drtWithExtensionsConfigGroup);
- }
}
VehicleType vehicleTypeAv = VehicleUtils.createVehicleType(Id.create("av_type_for_route_calculation", VehicleType.class));
diff --git a/src/main/java/org/matsim/dashboards/KelheimDashboardProvider.java b/src/main/java/org/matsim/dashboards/KelheimDashboardProvider.java
index e98819f5..40a8de49 100644
--- a/src/main/java/org/matsim/dashboards/KelheimDashboardProvider.java
+++ b/src/main/java/org/matsim/dashboards/KelheimDashboardProvider.java
@@ -1,9 +1,12 @@
package org.matsim.dashboards;
import org.matsim.core.config.Config;
+import org.matsim.core.utils.io.IOUtils;
+import org.matsim.run.RunKelheimScenario;
import org.matsim.simwrapper.Dashboard;
import org.matsim.simwrapper.DashboardProvider;
import org.matsim.simwrapper.SimWrapper;
+import org.matsim.simwrapper.dashboard.TravelTimeComparisonDashboard;
import org.matsim.simwrapper.dashboard.TripDashboard;
import java.util.List;
@@ -20,8 +23,10 @@ public List getDashboards(Config config, SimWrapper simWrapper) {
TripDashboard trips = new TripDashboard("kelheim_mode_share.csv", "kelheim_mode_share_per_dist.csv", null);
trips.setAnalysisArgs("--dist-groups", "0,1000,2000,5000,10000,20000");
-
- return List.of(trips);
+ return List.of(
+ trips,
+ new TravelTimeComparisonDashboard(IOUtils.resolveFileOrResource( "kelheim-v" + RunKelheimScenario.VERSION + "-routes-ref.csv.gz").toString())
+ );
}
}
diff --git a/src/main/java/org/matsim/run/RunKelheimScenario.java b/src/main/java/org/matsim/run/RunKelheimScenario.java
index 76a3f6b5..b4995552 100644
--- a/src/main/java/org/matsim/run/RunKelheimScenario.java
+++ b/src/main/java/org/matsim/run/RunKelheimScenario.java
@@ -54,7 +54,6 @@
import org.matsim.extensions.pt.routing.ptRoutingModes.PtIntermodalRoutingModesConfigGroup;
import org.matsim.run.prepare.PrepareNetwork;
import org.matsim.run.prepare.PreparePopulation;
-import org.matsim.run.utils.KelheimCaseStudyTool;
import org.matsim.simwrapper.SimWrapperConfigGroup;
import org.matsim.simwrapper.SimWrapperModule;
import org.matsim.vehicles.VehicleType;
@@ -79,7 +78,7 @@
})
public class RunKelheimScenario extends MATSimApplication {
- static final String VERSION = "3.0";
+ public static final String VERSION = "3.0";
private static final double WEIGHT_1_PASSENGER = 16517.;
private static final double WEIGHT_2_PASSENGER = 2084.;
private static final double WEIGHT_3_PASSENGER = 532.;
@@ -102,19 +101,13 @@ public class RunKelheimScenario extends MATSimApplication {
@CommandLine.Option(names = "--av-fare", defaultValue = "0.0", description = "AV fare (euro per trip)")
private double avFare;
- /**
- * this command line option allows to circumvent setting the drt service area per config. Not my preferred option, but its used to reduce nr. of configs (ts 07/23)
- */
- @CommandLine.Option(names = "--case-study", defaultValue = "NULL", description = "Case study for the av scenario")
- private KelheimCaseStudyTool.AvServiceArea avServiceArea;
-
@CommandLine.Option(names = "--bike-rnd", defaultValue = "false", description = "enable randomness in ASC of bike")
private boolean bikeRnd;
@CommandLine.Option(names = "--random-seed", defaultValue = "4711", description = "setting random seed for the simulation")
private long randomSeed;
- @CommandLine.Option(names = "--intermodal", defaultValue = "false", description = "enable DRT service")
+ @CommandLine.Option(names = "--intermodal", defaultValue = "false", description = "enable intermodality for DRT service")
private boolean intermodal;
@CommandLine.Option(names = "--plans", defaultValue = "", description = "Use different input plans")
@@ -345,9 +338,6 @@ public void handleEvent(PersonDepartureEvent event) {
for (DrtConfigGroup drtCfg : multiModeDrtConfig.getModalElements()) {
controler.addOverridingModule(new KelheimDrtFareModule(drtCfg, network, avFare));
- if (drtCfg.getMode().equals("av")) {
- KelheimCaseStudyTool.setConfigFile(config, drtCfg, avServiceArea);
- }
}
//controler.addOverridingModule(new DrtEstimatorModule());
diff --git a/src/main/java/org/matsim/run/prepare/DrtStopsWriter.java b/src/main/java/org/matsim/run/prepare/DrtStopsWriter.java
index 799c7ddf..6b59ba95 100644
--- a/src/main/java/org/matsim/run/prepare/DrtStopsWriter.java
+++ b/src/main/java/org/matsim/run/prepare/DrtStopsWriter.java
@@ -1,23 +1,28 @@
package org.matsim.run.prepare;
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVParser;
+import org.apache.commons.csv.CSVRecord;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.locationtech.jts.geom.Geometry;
import org.matsim.api.core.v01.Coord;
+import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.network.Network;
import org.matsim.application.options.ShpOptions;
+import org.matsim.core.network.NetworkUtils;
import org.matsim.core.utils.collections.Tuple;
import org.matsim.core.utils.geometry.CoordUtils;
import org.matsim.core.utils.geometry.geotools.MGC;
+import org.matsim.core.utils.io.IOUtils;
import org.matsim.core.utils.io.MatsimXmlWriter;
import org.matsim.core.utils.io.UncheckedIOException;
+import org.matsim.run.RunKelheimScenario;
import org.opengis.feature.simple.SimpleFeature;
-import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
@@ -66,13 +71,19 @@ public void write() throws UncheckedIOException, IOException {
this.writeDoctype("transitSchedule", "http://www.matsim.org/files/dtd/transitSchedule_v1.dtd");
this.writeStartTag("transitSchedule", null);
this.writeStartTag("transitStops", null);
- this.writeTransitStops(network);
+ this.writeTransitStopsAndVizFiles(network);
this.writeEndTag("transitStops");
this.writeEndTag("transitSchedule");
this.close();
}
- private void writeTransitStops(Network network) throws IOException {
+ /**
+ * additionally to writing the stops xml file, also writes a csv file that contains the same information as well as a network file that contains only
+ * the links assigned to stops (for visualisation).
+ * @param network to retrieve link id's from
+ * @throws IOException if some file can't be opened or written
+ */
+ private void writeTransitStopsAndVizFiles(Network network) throws IOException {
// Write csv file for adjusted stop location
FileWriter csvWriter = new FileWriter(outputFolder + "/"
+ mode + "-stops-locations.csv");
@@ -89,39 +100,64 @@ private void writeTransitStops(Network network) throws IOException {
log.info("Start processing the network. This may take some time...");
URL data = new URL("https://svn.vsp.tu-berlin.de/" +
"repos/public-svn/matsim/scenarios/countries/de/kelheim/original-data/" +
- "KEXI_Haltestellen_Liste_Kelheim_utm32n.csv");
-
- BufferedReader csvReader = new BufferedReader(new InputStreamReader(data.openStream()));
- csvReader.readLine();
- String stopEntry = csvReader.readLine();
- while (stopEntry != null) {
-
- String[] stopData = stopEntry.split(";");
- // write stop
- Coord coord = new Coord(Double.parseDouble(stopData[2]), Double.parseDouble(stopData[3]));
-
- if (serviceArea == null || MGC.coord2Point(coord).within(serviceArea)) {
- List> attributes = new ArrayList>(5);
- attributes.add(createTuple("id", stopData[0]));
- attributes.add(createTuple("x", stopData[2]));
- attributes.add(createTuple("y", stopData[3]));
- Link link = getStopLink(coord, network);
- attributes.add(createTuple("linkRefId", link.getId().toString()));
- this.writeStartTag("stopFacility", attributes, true);
-
- csvWriter.append(stopData[0]);
- csvWriter.append(",");
- csvWriter.append(link.getId().toString());
- csvWriter.append(",");
- csvWriter.append(Double.toString(link.getToNode().getCoord().getX()));
- csvWriter.append(",");
- csvWriter.append(Double.toString(link.getToNode().getCoord().getY()));
- csvWriter.append("\n");
+ "KEXI_Haltestellen_Liste_Kelheim_utm32n_withLinkIds.csv");
+ Set> allLinks = new HashSet<>();
+
+ try (CSVParser parser = new CSVParser(IOUtils.getBufferedReader(data),
+ CSVFormat.DEFAULT.withDelimiter(';').withFirstRecordAsHeader())) {
+ for (CSVRecord row : parser) {
+ Coord coord = new Coord(Double.parseDouble(row.get("x")), Double.parseDouble(row.get("y")));
+ if (serviceArea == null || MGC.coord2Point(coord).within(serviceArea)) {
+ List> attributes = new ArrayList<>(5);
+ attributes.add(createTuple("id", row.get("Haltestellen-Nr.")));
+ attributes.add(createTuple("x", row.get("x")));
+ attributes.add(createTuple("y", row.get("y")));
+ Link link = null;
+ // If link is already determined by hand in the raw data, then use that link directly.
+ if (row.get("linkId_v" + RunKelheimScenario.VERSION)!=null){
+ link = network.getLinks().get(Id.createLinkId(row.get("linkId_v" + RunKelheimScenario.VERSION)));
+ } else {
+ link = getStopLink(coord, network);
+ }
+ allLinks.add(link.getId());
+ attributes.add(createTuple("linkRefId", link.getId().toString()));
+
+ //write into stops xml file
+ this.writeStartTag("stopFacility", attributes, true);
+
+ //write into csv file for viz
+ csvWriter.append(row.get("Haltestellen-Nr."));
+ csvWriter.append(",");
+ csvWriter.append(link.getId().toString());
+ csvWriter.append(",");
+ csvWriter.append(Double.toString(link.getToNode().getCoord().getX()));
+ csvWriter.append(",");
+ csvWriter.append(Double.toString(link.getToNode().getCoord().getY()));
+ csvWriter.append("\n");
+ }
}
-
- stopEntry = csvReader.readLine();
}
+
csvWriter.close();
+
+ //write filtered network file (for viz)
+ writeFilteredNetwork(network, allLinks);
+ }
+
+ private void writeFilteredNetwork(Network network, Set> allLinks) {
+ //remove all links but the ones in the set
+ network.getLinks().keySet()
+ .forEach(linkId -> {
+ if (!allLinks.contains(linkId)) {
+ network.removeLink(linkId);
+ }
+ });
+ //remove 'empty' nodes
+ network.getNodes().values().stream()
+ .filter(node -> node.getInLinks().size() == 0 && node.getOutLinks().size() == 0)
+ .forEach(node -> network.removeNode(node.getId()));
+
+ NetworkUtils.writeNetwork(network, outputFolder + "/" + mode + "-stops-links.xml.gz");
}
private Link getStopLink(Coord coord, Network network) {
diff --git a/src/main/java/org/matsim/run/prepare/PrepareNetwork.java b/src/main/java/org/matsim/run/prepare/PrepareNetwork.java
index 1ca9dbe8..3bafb9f9 100644
--- a/src/main/java/org/matsim/run/prepare/PrepareNetwork.java
+++ b/src/main/java/org/matsim/run/prepare/PrepareNetwork.java
@@ -159,14 +159,18 @@ private void prepareNetworkDrt(Network network) {
}
}
+ Set allowedModes = new HashSet<>(link.getAllowedModes());
if (isAvAllowed) {
- Set allowedModes = new HashSet<>(link.getAllowedModes());
-
if (!allowedModes.contains("av")) {
allowedModes.add("av");
link.setAllowedModes(allowedModes);
linkCount[1] = linkCount[1] + 1;
}
+ } else {
+ if (allowedModes.contains("av")) {
+ allowedModes.remove("av");
+ link.setAllowedModes(allowedModes);
+ }
}
}
diff --git a/src/main/java/org/matsim/run/utils/KelheimCaseStudyTool.java b/src/main/java/org/matsim/run/utils/KelheimCaseStudyTool.java
deleted file mode 100644
index 928e9e33..00000000
--- a/src/main/java/org/matsim/run/utils/KelheimCaseStudyTool.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.matsim.run.utils;
-
-import org.matsim.contrib.drt.run.DrtConfigGroup;
-import org.matsim.core.config.Config;
-
-/**
- * Helper class to setup config file for case studies.
- */
-public final class KelheimCaseStudyTool {
-
- private KelheimCaseStudyTool() {
- }
-
- /**
- * Different possible services areas for the AV.
- */
- public enum AvServiceArea {NULL, CORE, CORE_WITH_SHOP, HOHENPFAHL, BAUERNSIEDLUNG}
- // NULL: do not change anything; CORE: Donaupark + Altstadt; HOHENPFAHL: CORE + Hohenpfahl area; BAUERNSIEDLUNG: CORE + Bauernsiedlung area
-
- public static void setConfigFile(Config config, DrtConfigGroup drtConfig, AvServiceArea avServiceAreas) {
- // Set drt related things (vehicle file, stops file)
- if (avServiceAreas == AvServiceArea.CORE) {
- drtConfig.transitStopFile = "av-stops-DP-AS.xml";
- }
-
- if (avServiceAreas == AvServiceArea.CORE_WITH_SHOP) {
- drtConfig.transitStopFile = "av-stops-DP-AS-shops.xml";
- }
-
- if (avServiceAreas == AvServiceArea.HOHENPFAHL) {
- drtConfig.transitStopFile = "av-stops-Hohenpfahl-DP-AS.xml";
- }
-
- if (avServiceAreas == AvServiceArea.BAUERNSIEDLUNG) {
- drtConfig.transitStopFile = "av-stops-Bauernsiedlung-DP-AS.xml";
- }
-
- // Update output directory
- if (avServiceAreas != AvServiceArea.NULL) {
- String outputPath = config.controler().getOutputDirectory() + "-" + avServiceAreas.toString();
- config.controler().setOutputDirectory(outputPath);
- }
- }
-}
diff --git a/src/main/resources/kelheim-v3.0-routes-ref.csv.gz b/src/main/resources/kelheim-v3.0-routes-ref.csv.gz
new file mode 100644
index 00000000..7f0eaaee
Binary files /dev/null and b/src/main/resources/kelheim-v3.0-routes-ref.csv.gz differ