diff --git a/pom.xml b/pom.xml index ac713775..28b6112f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ matsim-all - 2025.0-PR3402 + 2025.0-PR3501 @@ -15,7 +15,7 @@ 4.0.0 com.github.matsim-scenarios matsim-kelheim - 3.x-SNAPSHOT + 2024.2-SNAPSHOT MATSim Kelheim Model A transport model of the district of Kelheim and it's surroundings @@ -212,7 +212,7 @@ org.apache.avro avro - 1.11.3 + 1.12.0 diff --git a/src/main/R/drtAnalysis/avConfiguration_modalShiftAnalysis.R b/src/main/R/drtAnalysis/avConfiguration_modalShiftAnalysis.R new file mode 100644 index 00000000..eaebee4b --- /dev/null +++ b/src/main/R/drtAnalysis/avConfiguration_modalShiftAnalysis.R @@ -0,0 +1,325 @@ +library(sf) +library(matsim) +library(tidyverse) +library(plotly) + + +###################################################################################### +####################### functions ####################################### + +#copied from matsim-r and modified +sankey <- function (trips_table1, trips_table2, show_onlychanges = FALSE, + unite_modes = character(0), united_name = "united") +{ + trips_table1 <- process_rename_mainmodes(trips_table = trips_table1, + unite_modes = unite_modes, united_name = united_name) + trips_table2 <- process_rename_mainmodes(trips_table = trips_table2, + unite_modes = unite_modes, united_name = united_name) + joined <- as_tibble(inner_join(trips_table1, trips_table2 %>% + select(trip_id, main_mode), by = "trip_id") %>% dplyr::rename(base_mode = main_mode.x, + policy_mode = main_mode.y)) + if (show_onlychanges == TRUE) { + joined <- joined %>% filter(base_mode != policy_mode) + } + joined <- joined %>% group_by(base_mode, policy_mode) %>% + count() + modes = sort(unique(c(joined$base_mode, joined$policy_mode))) + num_modes <- length(modes) + joined$base_mode <- as.numeric(factor(joined$base_mode, + levels = modes, + ordered = TRUE)) + joined$policy_mode <- as.numeric(factor(joined$policy_mode, + levels = modes, + ordered = TRUE)) + palette <- colorRampPalette(c("blue", "yellow", "red"))(num_modes) + fig <- plot_ly(type = "sankey", + orientation = "h", + node = list(label = c(modes,modes), + color = c(palette, palette), + pad = 15, thickness = 20, + line = list(color = "black", width = 0.5)), + link = list(source = joined$base_mode - 1, + target = joined$policy_mode + num_modes - 1, + value = joined$n)) %>% + layout(title = list(text = "Basic Sankey Diagram", + font = list(size = 24, weight = "bold"), # Fettschrift und große Schriftgröße + x = 0.5, # Zentriert den Titel horizontal + y = 0.95, # Positioniert den Titel vertikal etwas weiter unten (0.95 = 95% der Höhe) + xref = "paper", + yref = "container"), + margin = list(t = 90, r = 50, l = 50), # Vergrößert den oberen Rand, um Platz für den Titel zu schaffen + font = list(size = 18, weight = "bold")) + fig + return(fig) +} + + +###################################################################################### +####################### INPUT ####################################### + +drtArea <- st_read("D:/public-svn/matsim/scenarios/countries/de/kelheim/shp/prepare-network/av-and-drt-area.shp") + +no_kexi_trips <- read_output_trips("E:/matsim-kelheim/v3.0-release/output-base/25pct") + +## Zielwert der KEXI Kalibrierung waren 159 Passagiere, erreichter Mittelwert über 5 Seeds 157.4 Passagiere. +## Seed 4 hat 155 rides und ist damit sehr repräsentativ für den Case "nur konv. KEXI" bzw. am nächsten dran am Durchschnitt aller 5 seeds. +## ein anderer Kandidat waere seed-3 mit 151 rides +nur_konv_trips <- read_output_trips("E:/matsim-kelheim/v3.0-release/output-KEXI/seed-4-kexi") %>% + mutate(main_mode = recode(main_mode, + "av" = "AV KEXI", + "drt" = "Konv. KEXI", + "pt_w_drt_used" = "KEXI + pt")) + +## der case SAR2023 AV2 3.3mps ist die Kalibrierungsgrundlage für den AV im Jahr 2024 +## mit dem Zielwert von 2,7 Buchungen pro Tag und 2,6 simulierten Buchungen über 5 seeds. +## im Schnitt haben die 5 seeds konventionelle KEXI Passagiere (JAR-Wechsel) :/ .. +## seed-1 hat 2 AV-Buchungen, 151 +## seed-2 hat 3 AV-Buchungen, 144 konv. Pax +## seed-3 hat 3 AV-Buchungen, 154 konv. Pax +## seed-4 hat 3 AV-Buchungen, 145 konv. Pax +## seed-5 hat 2 AV-Buchungen, 170 konv. Pax + +## repraesentativ ist also vor allem seed-3 +av_base_trips <- read_output_trips("E:/matsim-kelheim/v3.1.1/output-KEXI-2.45-AV--0.0/AV-speed-mps-3.3/SAR2023-AV2/seed-3-SAR2023") %>% + mutate(main_mode = recode(main_mode, + "av" = "AV KEXI", + "drt" = "Konv. KEXI", + "pt_w_drt_used" = "KEXI + pt")) + +## weil es hier um Policy Cases bzgl der !AV!-Auslegung geht und weil der AV-Base-Case oben recht präzise noch die Zahlen des konv. KEXI trifft, +## ist das unser Bezugsfall + +######################################################################################## +###### PROGNOSEFÄLLE + +# SAR-AV2-mps3.3-allDay hat im Schnitt 11.2 AV-Buchungen und 138.4 KEXI-Passagiere +# seed-1 hat 10 / 143 +# seed-2 hat 10 / 140 +# seed-3 hat 9 / 125 +# seed-4 hat 14 / 129 +# seed-5 hat 13 / 155 +av2_3.3mps_allDay_trips <- + read_output_trips("E:/matsim-kelheim/v3.1.1/output-KEXI-2.45-AV--0.0/AV-speed-mps-3.3/SAR2023-AV2-allDay/seed-1-SAR2023-allDay") %>% + mutate(main_mode = recode(main_mode, + "av" = "AV KEXI", + "drt" = "Konv. KEXI", + "pt_w_drt_used" = "KEXI + pt")) + +# wIEKEXI-AV2-mps3.3 hat im Schnitt 3.4 AV-Buchungen und 142 KEXI-Passagiere +# seed-1 hat 3 / 141 +# seed-2 hat 1 / 132 +# seed-3 hat 6 / 145 +# seed-4 hat 3 / 150 +# seed-5 hat 4 / 142 +av2_3.3mps_largeArea_trips <- + read_output_trips("E:/matsim-kelheim/v3.1.1/output-KEXI-2.45-AV--0.0/AV-speed-mps-3.3/WIEKEXI-AV2-intermodal/seed-5-WIEKEXI") %>% + mutate(main_mode = recode(main_mode, + "av" = "AV KEXI", + "drt" = "Konv. KEXI", + "pt_w_drt_used" = "KEXI + pt")) + +# av2_8.3mps_trips hat im Schnitt 40 AV-Buchungen und 135 KEXI-Passagiere +# seed-1 hat 43 / 128 +# seed-2 hat 35 / 135 +# seed-3 hat 36 / 126 +# seed-4 hat 35 / 149 +# seed-5 hat 51 / 137 +av2_8.3mps_trips <- + read_output_trips("E:/matsim-kelheim/v3.1.1/output-KEXI-2.45-AV--0.0/AV-speed-mps-8.3//SAR2023-AV2/seed-1-SAR2023") %>% + mutate(main_mode = recode(main_mode, + "av" = "AV KEXI", + "drt" = "Konv. KEXI", + "pt_w_drt_used" = "KEXI + pt")) + + +# der groeßte AV case mit aktueller geschwindigkeit. Im schnitt haben wir 247.4 simulierte AV-Buchungen und 125 konv. KEXI-Passagiere. +# seed-5 hat 245 / 124 +av100_3.3mps_allDay_largeArea_trips <- + read_output_trips("E:/matsim-kelheim/v3.1.1/output-KEXI-2.45-AV--0.0/AV-speed-mps-3.3/WIEKEXI-AV100-intermodal-allDay/seed-5-WIEKEXI-allDay") %>% + mutate(main_mode = recode(main_mode, + "av" = "AV KEXI", + "drt" = "Konv. KEXI", + "pt_w_drt_used" = "KEXI + pt")) + + +# der groeßte AV case überhaupt. Im schnitt haben wir 1105.4 simulierte AV-Buchungen und 136.2 konv. KEXI-Passagiere. +# seed-5 hat 1082 / 138 +# seed-4 hat 1114 / 146 +# seed-4 hat 1144 / 138 +# seed-2 hat 1100 / 126 +# seed-1 hat 1087 / 133 +av100_8.3mps_allDay_largeArea_trips <- + read_output_trips("E:/matsim-kelheim/v3.1.1/output-KEXI-2.45-AV--0.0/AV-speed-mps-8.3/WIEKEXI-AV100-intermodal-allDay/seed-2-WIEKEXI-allDay") %>% + mutate(main_mode = recode(main_mode, + "av" = "AV KEXI", + "drt" = "Konv. KEXI", + "pt_w_drt_used" = "KEXI + pt")) + +# SAR-AV50-mps3.3 hat im Schnitt 64.8 AV-Buchungen und 138 KEXI-Passagiere +# seed-1 hat 65 / 148 +# seed-2 hat 65 / 138 +# seed-3 hat 66 / 128 +# seed-4 hat 61 / 134 +# seed-5 hat 67 / 142 +av50_3.3mps_trips <- + read_output_trips("E:/matsim-kelheim/v3.1.1/output-KEXI-2.45-AV--0.0/AV-speed-mps-3.3/SAR2023-AV50/seed-2-SAR2023") %>% + mutate(main_mode = recode(main_mode, + "av" = "AV KEXI", + "drt" = "Konv. KEXI", + "pt_w_drt_used" = "KEXI + pt")) + +# wIEKEXI-AV50-mps8.3-allDay hat im Schnitt 1093.4 AV-Buchungen und 141.6 KEXI-Passagiere +# seed-1 hat 1081 / 148 +# seed-2 hat 1096 / 153 +# seed-3 hat 1099 / 143 +# seed-4 hat 1099 / 130 +# seed-5 hat 1092 / 134 +av50_8.3mps_largeArea_allDay_trips <- + read_output_trips("E:/matsim-kelheim/v3.1.1/output-KEXI-2.45-AV--0.0/AV-speed-mps-8.3/WIEKEXI-AV50-intermodal-allDay/seed-3-WIEKEXI-allDay") %>% + mutate(main_mode = recode(main_mode, + "av" = "AV KEXI", + "drt" = "Konv. KEXI", + "pt_w_drt_used" = "KEXI + pt")) + +######################## FILTERN ###################### +######################################################## + + + +######################## VARIANTE 1: FILTERE DRT TRIPS AUS DEN POLICY CASES. DANN PLOTTE MODAL SHIFT +######################## (WO KOMMEN DIE DRT TRIPS HER ??) +######################################################## + +drt_modes <- c ("drt", "av", "pt_w_drt_used", "AV KEXI", "KEXI + pt", "Konv. KEXI") + +av_base_trips_drt <- av_base_trips %>% + filter(main_mode %in% drt_modes) + +av2_3.3mps_allDay_trips_drt <- av2_3.3mps_allDay_trips %>% + filter(main_mode %in% drt_modes) + +av2_3.3mps_largeArea_trips_drt <- av2_3.3mps_largeArea_trips %>% + filter(main_mode %in% drt_modes) + +av2_8.3mps_trips_drt <- av2_8.3mps_trips %>% + filter(main_mode %in% drt_modes) + +av50_3.3mps_trips_drt <- av50_3.3mps_trips %>% + filter(main_mode %in% drt_modes) + +av100_3.3mps_allDay_largeArea_trips_drt <- av100_3.3mps_allDay_largeArea_trips %>% + filter(main_mode %in% drt_modes) + +av100_8.3mps_allDay_largeArea_trips_drt <- av100_8.3mps_allDay_largeArea_trips %>% + filter(main_mode %in% drt_modes) + +av50_8.3mps_largeArea_allDay_trips_drt <- av50_8.3mps_largeArea_allDay_trips %>% + filter(main_mode %in% drt_modes) + + +################################### +####PLOTS +sankey(no_kexi_trips, av_base_trips_drt) %>% + layout(title = "Basisfall (ohne KEXI)\n vs. Status Quo Mai 2024") + +sankey(no_kexi_trips, av2_3.3mps_largeArea_trips_drt) %>% + layout(title = "Basisfall (ohne KEXI)\n vs. Vergrößerung Bediengebiet") + +#sankey(av_base_trips, av2_3.3mps_largeArea_trips_drt) %>% +# layout(title = "Status Quo (Mai 2024)\n vs. Vergrößerung Bediengebiet") + +sankey(no_kexi_trips, av2_8.3mps_trips_drt) %>% + layout(title = "Basisfall (ohne KEXI)\n vs. Beschleunigung auf 30 km/h") + +#sankey(av_base_trips, av2_8.3mps_trips_drt) %>% +# layout(title = "Status Quo (Mai 2024)\n vs. Beschleunigung auf 30 km/h") + +sankey(no_kexi_trips, av2_3.3mps_allDay_trips_drt) %>% + layout(title = "Basisfall (ohne KEXI)\n vs. Ganztägiger Betrieb") + +#sankey(av_base_trips, av2_3.3mps_allDay_trips_drt) %>% +# layout(title = "Status Quo (Mai 2024)\n vs. Ganztägiger Betrieb") + +sankey(no_kexi_trips, av50_3.3mps_trips_drt) %>% + layout(title = "Basisfall (ohne KEXI)\n vs. Große Flotte (50 AV)") + +#sankey(av_base_trips, av50_3.3mps_trips_drt) %>% +# layout(title = "Status Quo (Mai 2024)\n vs. Große Flotte (50 AV)") + +sankey(no_kexi_trips, av50_8.3mps_largeArea_allDay_trips_drt) %>% + layout(title = "Basisfall (ohne KEXI)\n vs. Alle Maßnahmen") + +sankey(av_base_trips, av50_8.3mps_largeArea_allDay_trips_drt) %>% + layout(title = "Status Quo (Mai 2024)\n vs. Alle Maßnahmen") + + + + + +sankey(av_base_trips, av100_3.3mps_allDay_largeArea_trips_drt) +sankey(no_kexi_trips, av100_3.3mps_allDay_largeArea_trips_drt) + + +######################## VARIANTE 2: Räumliches filtern nach Eimnzugsgebiet +######################################################## +#filter trips auf einzugsgebiet des konventionellen KEXI = Stadtgebiet. +no_kexi_trips_spatial <- no_kexi_trips %>% + process_filter_by_shape(shape_table = drtArea, crs = 25832) + +nur_konv_trips_spatial <- nur_konv_trips %>% + process_filter_by_shape(shape_table = drtArea, crs = 25832) + +av_base_trips_spatial <- av_base_trips %>% + process_filter_by_shape(shape_table = drtArea, crs = 25832) + +av100_3.3mps_allDay_largeArea_trips_spatial <- av100_3.3mps_allDay_largeArea_trips %>% + process_filter_by_shape(shape_table = drtArea, crs = 25832) + +av100_8.3mps_allDay_largeArea_trips_spatial <- av100_8.3mps_allDay_largeArea_trips %>% + process_filter_by_shape(shape_table = drtArea, crs = 25832) + + + + +################################################## +###PLOTS + +#kein KEXI +p <- plot_mainmode_piechart(no_kexi_trips) +p <- p %>% layout(title = "Kein KEXI") +p + +#AV-Base +p <- plot_mainmode_barchart(av_base_trips) +p <- p %>% layout(title = "AV Base Case") +p + +#av100_3.3mps_allDay_largeArea +p <- plot_mainmode_piechart(av100_3.3mps_allDay_largeArea_trips) +p <- p %>% layout(title = "av100_3.3mps_allDay_largeArea") +p + +#av100_8.3mps_allDay_largeArea +p <- plot_mainmode_piechart(av100_8.3mps_allDay_largeArea_trips) +p <- p %>% layout(title = "av100_8.3mps_allDay_largeArea") +p + + +####TODO: +#filter for trips that are drt or AV in the policy and then display sankey for those only. + +#av100_3.3mps_allDay_largeArea VERSUS av_base +plot_compare_mainmode_barchart(av_base_trips, av100_3.3mps_allDay_largeArea_trips) +plot_compare_mainmode_sankey(av_base_trips, av100_3.3mps_allDay_largeArea_trips, show_onlychanges = TRUE) + +#av100_8.3mps_allDay_largeArea VERSUS av_base +plot_compare_mainmode_barchart(av_base_trips, av100_8.3mps_allDay_largeArea_trips) +plot_compare_mainmode_sankey(av_base_trips, av100_8.3mps_allDay_largeArea_trips, show_onlychanges = TRUE) + + +#base vs large AV +plot_compare_mainmode_barchart(base_filtered, largeAV_filtered) +plot_compare_mainmode_sankey(base_filtered, largeAV_filtered, show_onlychanges = TRUE) +plot_mainmode_piechart(largeAV_filtered) + +matsim::plot_map_trips(kexi_filtered, crs = 25832) diff --git a/src/main/R/drtAnalysis/av_modalShiftAnalysis.R b/src/main/R/drtAnalysis/badWeather_av_modalShiftAnalysis.R similarity index 100% rename from src/main/R/drtAnalysis/av_modalShiftAnalysis.R rename to src/main/R/drtAnalysis/badWeather_av_modalShiftAnalysis.R diff --git a/src/main/R/drtAnalysis/plotRunSummaries.R b/src/main/R/drtAnalysis/plotRunSummaries.R index cf2f5021..c3f8e300 100644 --- a/src/main/R/drtAnalysis/plotRunSummaries.R +++ b/src/main/R/drtAnalysis/plotRunSummaries.R @@ -4,27 +4,32 @@ library(tidyr) mainDir <- "E:/matsim-kelheim/v3.1.1/output-KEXI-2.45-AV--0.0/" -transposed_result <- read.csv(paste(mainDir, "results-deutsch.csv", sep=""), check.names = FALSE, sep =",") -#names(transposed_result) <- make.names(names(transposed_result), unique = TRUE, allow_ = FALSE) +#set to true for AV and FALSE for conv. KEXI +stats_for_AV = TRUE -# Betriebszeiten umschreiben -transposed_result$Betriebszeiten <- factor(ifelse(transposed_result$Betriebszeiten == TRUE, "0h - 24h", "9h - 16h"), - levels = c("9h - 16h", "0h - 24h")) +################################################################################################ +################################################################################################ -### -#in Realität haben wir eine avg gruppengr0eße von 1.7 gemessen, diese aber nicht simuliert. -# wir rechnen die jetzt im nachhinein wieder drauf. -## --> machen wir jetzt im skript, dass die daten rausschreibt (readValuesFromRunSammaries.R) +if (stats_for_AV){ + input_file <- paste(mainDir, "results-av-deutsch.csv", sep="") +} else { + input_file <- paste(mainDir, "results-konvKEXI-deutsch.csv", sep="") +} + + +transposed_result <- read.csv(input_file, check.names = FALSE, sep =",") -#transposed_result <- transposed_result %>% -# mutate(`Anzahl Passagiere` = `Bediente Anfragen` * 1.7, -# `Gesamt Passagierkilometer [km]` = `Gesamt Passagierkilometer [km]` * 1.7) %>% -# mutate(`Passagiere pro Fahrzeug` = `Anzahl Passagiere` / Fahrzeuge, -# `Passagiere pro Fahrzeugkilometer` = `Anzahl Passagiere` / `Summe Fahrzeugkilometer [km]`, -# `Passagiere pro Fahrzeugstunde` = `Anzahl Passagiere` / `Summe Fzg.-Betriebsstunden`, -# `Besetzungsgrad [pax-km/v-km]` = `Gesamt Passagierkilometer [km]` / `Summe Fahrzeugkilometer [km]`)# +#Bediengebiete umkodieren +transposed_result <- transposed_result %>% + mutate(Bediengebiet = recode(Bediengebiet, + "ALLCITY" = "konv. KEXI\n schlechte Wartepunkte", + "SAR2023" = "AV 2024", + "WIEKEXI" = "konv. KEXI")) +# Betriebszeiten umschreiben und faktorisieren +transposed_result$Betriebszeiten <- factor(ifelse(transposed_result$Betriebszeiten == TRUE, "0h - 24h", "9h - 16h"), + levels = c("9h - 16h", "0h - 24h")) results <- transposed_result %>% gather(key = "parameter", value = "mean", -Geschwindigkeit, -Bediengebiet, -Flottengroeße, -Intermodal, -Betriebszeiten) @@ -42,6 +47,16 @@ plotByConfiguration <- function(parameterStr, scales = "free"){ paste(round(as.numeric(value) * 3.6, 0), "km/h") } + if (stats_for_AV){ + plot_title <- paste("AV KEXI:", + parameterStr, + "nach AV-Konfiguration\n (Geschwindigkeit, Flottengröße, Bediengebiet und Betriebszeiten)") + } else { + plot_title <- paste("KONV. KEXI:", + parameterStr, + "nach AV-Konfiguration\n (Geschwindigkeit, Flottengröße, Bediengebiet und Betriebszeiten)") + } + # Erstellen des Facet-Plots ggplot(plot_data, aes(x = Flottengroeße, y = mean, color = Bediengebiet, linetype = as.factor(Betriebszeiten), group = interaction(Bediengebiet, Betriebszeiten))) + geom_line(size = 1.2) + @@ -52,13 +67,14 @@ plotByConfiguration <- function(parameterStr, scales = "free"){ labeller = labeller(Geschwindigkeit = label_function) ,scales = scales ) + - labs(title = paste(parameterStr, "nach Geschwindigkeit, Flottengröße,\nBediengebiet und Betriebszeiten"), + labs(title = plot_title, x = "Flottengröße", y = parameterStr, color = "Bediengebiet", linetype = "Betriebszeiten" #,shape = "Intermodal" ) + + #geom_text(aes(label = Flottengroeße), vjust = -1, hjust = 0.5, size = 3, color = "black") + #theme_dark() + theme( plot.title = element_text(size = 20, face = "bold"), # Titelgröße anpassen @@ -73,12 +89,22 @@ plotByConfiguration <- function(parameterStr, scales = "free"){ } save <- function(fileName){ - ggsave(filename = paste(mainDir, "plots/", fileName, ".png", sep = ""), + if (stats_for_AV){ + output_file <- paste(mainDir, "plots/AV/", fileName, "-AV.png", sep = "") + } else { + output_file <- paste(mainDir, "plots/konvKEXI/", fileName, "-konvKEXI.png", sep = "") + } + ggsave(filename = output_file, dpi = 600, width = 32, height = 18, units = "cm") } unique(results$parameter) +results <- results %>% + filter(Bediengebiet != "konv. KEXI\n schlechte Wartepunkte", + Flottengroeße < 150) + + ###nachfrage plotByConfiguration("Bediente Anfragen") save("bedienteAnfragen") @@ -86,6 +112,9 @@ plotByConfiguration("Anzahl Passagiere", "fixed") save("passagiere") plotByConfiguration("Mittl. Wartezeit [s]", "fixed") save("wartezeit") +plotByConfiguration("Mittl. Gesamtreisezeit [s]", "fixed") + + plotByConfiguration("Umwegfaktor", "fixed") plotByConfiguration("Mittl. Reiseweite [km]", "fixed") save("reiseweite") @@ -94,15 +123,15 @@ save("leerkilometer") ###betrieb -plotByConfiguration("Summe Fahrzeugkilometer [km]") +plotByConfiguration("Summe Fahrzeugkilometer [km]", "fixed") save("fahrzeugkilometer") -plotByConfiguration("Besetzungsgrad [pax-km/v-km]") +plotByConfiguration("Besetzungsgrad [pax-km/v-km]", "fixed") save("besetzungsgrad") plotByConfiguration("Passagiere pro Fahrzeugkilometer", "fixed") save("paxPerKM") plotByConfiguration("Passagiere pro Fahrzeugstunde") plotByConfiguration("Passagiere pro Fahrzeugstunde", "fixed") -x^xsave("paxPerVehHour") +save("paxPerVehHour") plotByConfiguration("Gesamt Passagierkilometer [km]") diff --git a/src/main/R/drtAnalysis/readValuesFromRunSummaries.R b/src/main/R/drtAnalysis/readValuesFromRunSummaries.R index eb278b6d..d1fa8b84 100644 --- a/src/main/R/drtAnalysis/readValuesFromRunSummaries.R +++ b/src/main/R/drtAnalysis/readValuesFromRunSummaries.R @@ -23,21 +23,28 @@ extract_parameters <- function(folder_name, speed) { } # Funktion zum Einlesen der CSV-Datei und Extrahieren der "mean"-Werte -read_stats <- function(folder_path, file_name) { - print(paste("reading", folder_path)) - csv_path <- file.path(folder_path, "analysis/drt-drt-av", file_name) +read_stats <- function(folder_path, file_name, stats_for_AV) { + if (stats_for_AV){ + folder_name <- "analysis/drt-drt-av" + } else { + folder_name <- "analysis/drt-drt" + } + + csv_path <- file.path(folder_path, folder_name, file_name) if (file.exists(csv_path)) { + print(paste(Sys.time(), ": ", "reading", csv_path)) df <- read_csv(csv_path, show_col_types = FALSE) mean_values <- df %>% select(parameter, mean) return(mean_values) } else { + print(paste(Sys.time(), ": ", "could not find ", csv_path)) return(NULL) } } # Hauptfunktion zum Iterieren durch Unterordner -process_folders <- function(main_folder, speed) { +process_folders <- function(main_folder, speed, stats_for_AV) { # Liste aller Unterordner im Hauptordner subfolders <- list.dirs(main_folder, recursive = FALSE, full.names = FALSE) @@ -49,8 +56,8 @@ process_folders <- function(main_folder, speed) { parameters <- extract_parameters(subfolder, speed) full_path <- file.path(main_folder, subfolder) - demand_mean_values <- read_stats(full_path, "avg_demand_stats.csv") - supply_mean_values <- read_stats(full_path, "avg_supply_stats.csv") + demand_mean_values <- read_stats(full_path, "avg_demand_stats.csv", stats_for_AV) + supply_mean_values <- read_stats(full_path, "avg_supply_stats.csv", stats_for_AV) if (!is.null(demand_mean_values) || !is.null(supply_mean_values)) { if (!is.null(demand_mean_values)) { @@ -91,10 +98,12 @@ mainDir <- "E:/matsim-kelheim/v3.1.1/output-KEXI-2.45-AV--0.0/" speeds <- list(3.3, 5, 8.3) +stats_for_AV = TRUE #set to true for AV and FALSE for conv. KEXI + results <- list() for (speed in speeds) { main_folder <- paste(mainDir, "AV-speed-mps-", speed, "/", sep="") - runResults <- process_folders(main_folder, speed) + runResults <- process_folders(main_folder, speed, stats_for_AV) results[[speed]] <- runResults } @@ -106,16 +115,18 @@ transposed_result <- results %>% select(speed, area, fleetSize, intermodal, allDay, parameter, mean) %>% spread(key = parameter, value = mean) -### -#in Realität haben wir eine avg gruppengr0eße von 1.7 gemessen, diese aber nicht simuliert. -# wir rechnen die jetzt im nachhinein wieder drauf. -transposed_result <- transposed_result %>% - mutate(`Passengers (Pax)` = `Handled Requests` * 1.7, - `Total pax distance [km]` = `Total pax distance [km]` * 1.7) %>% - mutate(`Pax per veh` = `Passengers (Pax)` / Vehicles, - `Pax per veh-km` = `Passengers (Pax)` / `Total vehicle mileage [km]`, - `Pax per veh-h` = `Passengers (Pax)` / `Total service hours`, - `Occupancy rate [pax-km/v-km]` = `Total pax distance [km]` / `Total vehicle mileage [km]`) +if (stats_for_AV){ + ### + #in Realität haben wir eine avg gruppengr0eße von 1.7 gemessen, diese aber nicht simuliert. + # wir rechnen die jetzt im nachhinein wieder drauf. + transposed_result <- transposed_result %>% + mutate(`Passengers (Pax)` = `Handled Requests` * 1.7, + `Total pax distance [km]` = `Total pax distance [km]` * 1.7) %>% + mutate(`Pax per veh` = `Passengers (Pax)` / Vehicles, + `Pax per veh-km` = `Passengers (Pax)` / `Total vehicle mileage [km]`, + `Pax per veh-h` = `Passengers (Pax)` / `Total service hours`, + `Occupancy rate [pax-km/v-km]` = `Total pax distance [km]` / `Total vehicle mileage [km]`) +} #transponiere zurück results <- transposed_result %>% @@ -125,7 +136,12 @@ results <- transposed_result %>% print(results) print(transposed_result) -write_csv(transposed_result, paste(mainDir, "results.csv", sep="")) +if (stats_for_AV){ + output_file <- "results-av.csv" +} else { + output_file <- "results-konvKEXI.csv" +} +write_csv(transposed_result, paste(mainDir, output_file, sep="")) ##################################################################### ######PLOTS#### @@ -144,13 +160,13 @@ plotByConfiguration <- function(parameterStr){ # Erstellen des Facet-Plots ggplot(plot_data, aes(x = fleetSize, y = mean, color = area, linetype = as.factor(allDay), group = interaction(area, allDay))) + - geom_line(size = 1.2) + + geom_line(linewidth = 1.2) + geom_point(size = 3, #aes(shape = as.factor(intermodal)) ) + facet_wrap(~ speed, labeller = labeller(speed = label_function) - ,scales = "free" + ,scales = "fixed" ) + geom_text(aes(label = fleetSize), vjust = -1, hjust = 0.5, size = 3, color = "black") + labs(title = paste(parameterStr, "by Fleet Size, Speed, Area and Service Hours"), @@ -201,7 +217,7 @@ plotByConfiguration("Pax per veh-km") # Erstellen des Facet-Plots facet_plot <- ggplot(plot_data, aes(x = avg_wait_time, y = handled_requests, color = area, linetype = as.factor(allDay), group = interaction(area, allDay))) + - geom_line(size = 1.2) + + geom_line(linewidth = 1.2) + geom_point(size = 3 #,aes(shape = as.factor(intermodal)) ) + diff --git a/src/main/R/modeAnalysis-kexiArea.R b/src/main/R/modeAnalysis-kexiArea.R deleted file mode 100644 index cde5523d..00000000 --- a/src/main/R/modeAnalysis-kexiArea.R +++ /dev/null @@ -1,38 +0,0 @@ -library(sf) -library(matsim) -library(tidyverse) -library(plotly) - -drtArea <- st_read("D:/public-svn/matsim/scenarios/countries/de/kelheim/shp/prepare-network/av-and-drt-area.shp") - -baseTrips <- read_output_trips("E:/matsim-kelheim/v3.0-release/output-base/25pct") -kexiTrips <- read_output_trips("E:/matsim-kelheim/v3.0-release/output-KEXI/seed-3-kexi") -largeAVTrips <- read_output_trips("E:/matsim-kelheim/v3.1.1/output-KEXI-2.45-AV--0.0/AV-speed-mps-8.3/ALLCITY-AV100-intermodal/seed-1-ALLCITY") - - - -base_filtered <- baseTrips %>% - process_filter_by_shape(shape_table = drtArea, crs = 25832) -kexi_filtered <- kexiTrips %>% - process_filter_by_shape(shape_table = drtArea, crs = 25832) -largeAV_filtered <- largeAVTrips %>% - process_filter_by_shape(shape_table = drtArea, crs = 25832) - - -#base -p <- plot_mainmode_piechart(base_filtered) -p2 <- p %>% layout(title = "Base Case") -p2 - -#base vs KEXI -plot_compare_mainmode_barchart(base_filtered, kexi_filtered) -plot_compare_mainmode_sankey(base_filtered, kexi_filtered, show_onlychanges = TRUE) -plot_mainmode_piechart(kexi_filtered) - - -#base vs large AV -plot_compare_mainmode_barchart(base_filtered, largeAV_filtered) -plot_compare_mainmode_sankey(base_filtered, largeAV_filtered, show_onlychanges = TRUE) -plot_mainmode_piechart(largeAV_filtered) - -matsim::plot_map_trips(kexi_filtered, crs = 25832) diff --git a/src/main/java/org/matsim/analysis/postAnalysis/NoiseAverageAnalysis.java b/src/main/java/org/matsim/analysis/postAnalysis/NoiseAverageAnalysis.java index 2749a67a..e4526db4 100644 --- a/src/main/java/org/matsim/analysis/postAnalysis/NoiseAverageAnalysis.java +++ b/src/main/java/org/matsim/analysis/postAnalysis/NoiseAverageAnalysis.java @@ -4,9 +4,9 @@ import org.apache.avro.file.DataFileReader; import org.apache.avro.file.DataFileWriter; import org.apache.avro.file.FileReader; -import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericDatumReader; import org.apache.avro.generic.GenericRecord; +import org.apache.avro.generic.PrimitivesArrays; import org.apache.avro.io.DatumWriter; import org.apache.avro.specific.SpecificDatumWriter; import org.apache.avro.util.Utf8; @@ -215,10 +215,8 @@ private XYTData calcAvroMeans(List recordList, String dataFieldNa getCoordData(object1, xCoords); getCoordData(object2, yCoords); - -// TODO: for the example data even for the hourly data there was only one time stamp. This might be different with real data. this needs to be checked - if (object3 instanceof GenericData.Array) { - List ints = new ArrayList<>((GenericData.Array) object3); + if (object3 instanceof PrimitivesArrays.IntArray intArray) { + List ints = new ArrayList<>(intArray); if (!timeStamps.equals(ints)) { if (timeStamps.isEmpty()) { @@ -235,8 +233,8 @@ private XYTData calcAvroMeans(List recordList, String dataFieldNa List values = new ArrayList<>(); for (Map.Entry entry : ((HashMap) object4).entrySet()) { - if (entry.getKey() instanceof Utf8 && entry.getKey().toString().equals(dataFieldName) && entry.getValue() instanceof GenericData.Array) { - values.addAll((GenericData.Array) entry.getValue()); + if (entry.getKey() instanceof Utf8 && entry.getKey().toString().equals(dataFieldName) && entry.getValue() instanceof PrimitivesArrays.FloatArray floatArray) { + values.addAll(floatArray); String entryString = ((Utf8) entry.getKey()).toString(); @@ -265,8 +263,8 @@ private XYTData calcAvroMeans(List recordList, String dataFieldNa } private void getCoordData(Object object, List target) { - if (object instanceof GenericData.Array) { - List floats = new ArrayList<>((GenericData.Array) object); + if (object instanceof PrimitivesArrays.FloatArray floatArray) { + List floats = new ArrayList<>(floatArray); if (!target.equals(floats)) { if (target.isEmpty()) { diff --git a/src/main/java/org/matsim/analysis/postAnalysis/emissions/KelheimOfflineAirPollutionAnalysisByEngineInformation.java b/src/main/java/org/matsim/analysis/postAnalysis/emissions/KelheimOfflineAirPollutionAnalysisByEngineInformation.java index 2c5ab6c9..8bcbacc5 100644 --- a/src/main/java/org/matsim/analysis/postAnalysis/emissions/KelheimOfflineAirPollutionAnalysisByEngineInformation.java +++ b/src/main/java/org/matsim/analysis/postAnalysis/emissions/KelheimOfflineAirPollutionAnalysisByEngineInformation.java @@ -109,10 +109,17 @@ public class KelheimOfflineAirPollutionAnalysisByEngineInformation implements MA @CommandLine.Option(names = "--grid-size", description = "Grid size in meter", defaultValue = "250") private double gridSize; + private final NumberFormat numberFormat; //dump out all pollutants. to include only a subset of pollutants, adjust! static List pollutants2Output = Arrays.asList(Pollutant.values()); + public KelheimOfflineAirPollutionAnalysisByEngineInformation(){ + numberFormat = NumberFormat.getInstance(Locale.US); + numberFormat.setMaximumFractionDigits(4); + numberFormat.setGroupingUsed(false); + } + @Override public Integer call() throws Exception { @@ -140,7 +147,6 @@ private void process(Config config, Scenario scenario) throws IOException { // the following is copied from the example and supplemented... //------------------------------------------------------------------------------ - NetworkUtils.writeNetwork(scenario.getNetwork(), output.getPath( "emissionNetwork.xml.gz").toString()); final String eventsFile = input.getEventsPath(); @@ -301,10 +307,6 @@ private void writeLinkOutput(String linkEmissionAnalysisFile, String linkEmissio log.info("Writing output..."); - NumberFormat nf = NumberFormat.getInstance(Locale.US); - nf.setMaximumFractionDigits(4); - nf.setGroupingUsed(false); - { //dump link-based output files File absolutFile = new File(linkEmissionAnalysisFile); @@ -340,14 +342,14 @@ private void writeLinkOutput(String linkEmissionAnalysisFile, String linkEmissio if (link2pollutants.get(linkId).get(pollutant) != null) { emissionValue = link2pollutants.get(linkId).get(pollutant); } - absolutWriter.write(";" + nf.format(emissionValue)); + absolutWriter.write(";" + numberFormat.format(emissionValue)); double emissionPerM = Double.NaN; Link link = network.getLinks().get(linkId); if (link != null) { emissionPerM = emissionValue / link.getLength(); } - perMeterWriter.write(";" + nf.format(emissionPerM)); + perMeterWriter.write(";" + numberFormat.format(emissionPerM)); } absolutWriter.newLine(); @@ -435,18 +437,7 @@ private void writeRaster(Network fullNetwork, Network filteredNetwork, Config co try (CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(output.getPath("emissions_grid_per_day.xyt.csv")), CSVFormat.DEFAULT.builder().setCommentMarker('#').build())) { - NumberFormat nf = NumberFormat.getInstance(Locale.US); - nf.setMaximumFractionDigits(4); - nf.setGroupingUsed(false); - - String crs = ProjectionUtils.getCRS(fullNetwork); - if (crs == null) - crs = config.network().getInputCRS(); - if (crs == null) - crs = config.global().getCoordinateSystem(); - - // print coordinate system -// printer.printComment(crs); +// printCrsComment(fullNetwork, config, printer); // print header printer.print("time"); @@ -480,7 +471,7 @@ private void writeRaster(Network fullNetwork, Network filteredNetwork, Config co printer.print(coord.getY()); double value = rasterMap.get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi); - printer.print(nf.format(value)); + printer.print(numberFormat.format(value)); printer.println(); } @@ -517,18 +508,7 @@ private void writeTimeDependentRaster(Network fullNetwork, Network filteredNetwo try (CSVPrinter printer = new CSVPrinter(IOUtils.getBufferedWriter(output.getPath("emissions_grid_per_hour.csv").toString()), CSVFormat.DEFAULT.builder().setCommentMarker('#').build())) { - NumberFormat nf = NumberFormat.getInstance(Locale.US); - nf.setMaximumFractionDigits(4); - nf.setGroupingUsed(false); - - String crs = ProjectionUtils.getCRS(fullNetwork); - if (crs == null) - crs = config.network().getInputCRS(); - if (crs == null) - crs = config.global().getCoordinateSystem(); - -// print coordinate system -// printer.printComment(crs); +// printCrsComment(fullNetwork, config, printer); // print header printer.print("time"); @@ -566,7 +546,7 @@ private void writeTimeDependentRaster(Network fullNetwork, Network filteredNetwo printer.print(coord.getX()); printer.print(coord.getY()); - printer.print(nf.format(value)); + printer.print(numberFormat.format(value)); printer.println(); } @@ -579,4 +559,15 @@ private void writeTimeDependentRaster(Network fullNetwork, Network filteredNetwo } + private static void printCrsComment(Network fullNetwork, Config config, CSVPrinter printer) throws IOException { + String crs = ProjectionUtils.getCRS(fullNetwork); + if (crs == null) + crs = config.network().getInputCRS(); + if (crs == null) + crs = config.global().getCoordinateSystem(); + + //print coordinate system + printer.printComment(crs); + } + } diff --git a/src/main/java/org/matsim/dashboard/AverageKelheimEmissionsDashboard.java b/src/main/java/org/matsim/dashboard/AverageKelheimEmissionsDashboard.java index fa369af5..b5263be8 100644 --- a/src/main/java/org/matsim/dashboard/AverageKelheimEmissionsDashboard.java +++ b/src/main/java/org/matsim/dashboard/AverageKelheimEmissionsDashboard.java @@ -21,17 +21,12 @@ package org.matsim.dashboard; import org.matsim.analysis.postAnalysis.emissions.EmissionsPostProcessingAverageAnalysis; -import org.matsim.simwrapper.Dashboard; -import org.matsim.simwrapper.Data; -import org.matsim.simwrapper.Header; -import org.matsim.simwrapper.Layout; +import org.matsim.simwrapper.*; import org.matsim.simwrapper.viz.*; import java.util.ArrayList; import java.util.List; -import static org.matsim.dashboard.AverageKelheimNoiseDashboard.*; - /** * Average emissions dashboard for several runs with the same config but a different random seed. */ @@ -130,21 +125,16 @@ public void configure(Header header, Layout layout) { layout.row("second").el(GridMap.class, (viz, data) -> { viz.title = "CO₂ Emissions"; viz.description = "per day. Be aware that CO2 values are provided in the simulation sample size!"; - setGridMapStandards(viz); + DashboardUtils.setGridMapStandards(viz, data, "EPSG:25832"); viz.file = postProcess(data, "mean_emissions_grid_per_day.xyt.csv"); }); layout.row("third") .el(GridMap.class, (viz, data) -> { viz.title = "CO₂ Emissions"; viz.description = "per hour. Be aware that CO2 values are provided in the simulation sample size!"; - setGridMapStandards(viz); + DashboardUtils.setGridMapStandards(viz, data, "EPSG:25832"); viz.file = postProcess(data, "mean_emissions_grid_per_hour.csv"); }); } - private static void setGridMapStandards(GridMap viz) { - viz.projection = "EPSG:25832"; - viz.setColorRamp(new double[]{30, 40, 50, 60, 70}, new String[]{DARK_BLUE, LIGHT_BLUE, YELLOW, SAND, ORANGE, RED}); - viz.height = 12.0; - } } diff --git a/src/main/java/org/matsim/dashboard/AverageKelheimNoiseDashboard.java b/src/main/java/org/matsim/dashboard/AverageKelheimNoiseDashboard.java index b4715dd9..d3d175e3 100644 --- a/src/main/java/org/matsim/dashboard/AverageKelheimNoiseDashboard.java +++ b/src/main/java/org/matsim/dashboard/AverageKelheimNoiseDashboard.java @@ -1,10 +1,7 @@ package org.matsim.dashboard; import org.matsim.analysis.postAnalysis.NoiseAverageAnalysis; -import org.matsim.simwrapper.Dashboard; -import org.matsim.simwrapper.Data; -import org.matsim.simwrapper.Header; -import org.matsim.simwrapper.Layout; +import org.matsim.simwrapper.*; import org.matsim.simwrapper.viz.ColorScheme; import org.matsim.simwrapper.viz.GridMap; import org.matsim.simwrapper.viz.MapPlot; @@ -23,12 +20,7 @@ public class AverageKelheimNoiseDashboard implements Dashboard { private final List dirs; private final Integer noRuns; private static final String NOISE = "noise"; - static final String DARK_BLUE = "#1175b3"; - static final String LIGHT_BLUE = "#95c7df"; - static final String ORANGE = "#f4a986"; - static final String RED = "#cc0c27"; - static final String SAND = "#dfb095"; - static final String YELLOW = "#dfdb95"; + public AverageKelheimNoiseDashboard(List dirs, Integer noRuns) { this.dirs = dirs; @@ -78,38 +70,28 @@ public void configure(Header header, Layout layout) { .el(GridMap.class, (viz, data) -> { viz.title = "Noise Immissions (Grid)"; viz.description = "Total Noise Immissions per day"; - setGridMapStandards(viz, data); + DashboardUtils.setGridMapStandards(viz, data, "EPSG:25832"); viz.file = postProcess(data, "mean_immission_per_day.avro"); }) .el(GridMap.class, (viz, data) -> { viz.title = "Hourly Noise Immissions (Grid)"; viz.description = "Noise Immissions per hour"; - setGridMapStandards(viz, data); + DashboardUtils.setGridMapStandards(viz, data, "EPSG:25832"); viz.file = postProcess(data, "mean_immission_per_hour.avro"); }); layout.row("damages") .el(GridMap.class, (viz, data) -> { viz.title = "Daily Noise Damages (Grid)"; viz.description = "Total Noise Damages per day [€]"; - setGridMapStandards(viz, data); + DashboardUtils.setGridMapStandards(viz, data, "EPSG:25832"); viz.file = postProcess(data, "mean_damages_receiverPoint_per_day.avro"); }) .el(GridMap.class, (viz, data) -> { viz.title = "Hourly Noise Damages (Grid)"; viz.description = "Noise Damages per hour [€]"; - setGridMapStandards(viz, data); + DashboardUtils.setGridMapStandards(viz, data, "EPSG:25832"); viz.file = postProcess(data, "mean_damages_receiverPoint_per_hour.avro"); }); } - private static void setGridMapStandards(GridMap viz, Data data) { - viz.height = 12.0; - viz.cellSize = 250; - viz.opacity = 0.1; - viz.maxHeight = 40; - viz.projection = "EPSG:25832"; - viz.center = data.context().getCenter(); - viz.zoom = data.context().mapZoomLevel; - viz.setColorRamp(new double[]{30, 40, 50, 60, 70}, new String[]{DARK_BLUE, LIGHT_BLUE, YELLOW, SAND, ORANGE, RED}); - } } diff --git a/src/main/java/org/matsim/dashboard/KelheimEmissionsDashboard.java b/src/main/java/org/matsim/dashboard/KelheimEmissionsDashboard.java index 8be29839..f59d55e0 100644 --- a/src/main/java/org/matsim/dashboard/KelheimEmissionsDashboard.java +++ b/src/main/java/org/matsim/dashboard/KelheimEmissionsDashboard.java @@ -23,7 +23,7 @@ import org.matsim.analysis.postAnalysis.emissions.KelheimOfflineAirPollutionAnalysisByEngineInformation; import org.matsim.application.prepare.network.CreateGeoJsonNetwork; import org.matsim.simwrapper.Dashboard; -import org.matsim.simwrapper.Data; +import org.matsim.simwrapper.DashboardUtils; import org.matsim.simwrapper.Header; import org.matsim.simwrapper.Layout; import org.matsim.simwrapper.viz.GridMap; @@ -95,21 +95,16 @@ public void configure(Header header, Layout layout) { layout.row("second").el(GridMap.class, (viz, data) -> { viz.title = "CO₂ Emissions"; viz.description = "per day. Be aware that CO2 values are provided in the simulation sample size!"; - setGridMapStandards(viz, 12.0, data.compute(KelheimOfflineAirPollutionAnalysisByEngineInformation.class, "emissions_grid_per_day.xyt.csv", new String[0])); - + DashboardUtils.setGridMapStandards(viz, data, "EPSG:25832"); + viz.file = data.compute(KelheimOfflineAirPollutionAnalysisByEngineInformation.class, "emissions_grid_per_day.xyt.csv", new String[0]); }); layout.row("third") .el(GridMap.class, (viz, data) -> { viz.title = "CO₂ Emissions"; viz.description = "per hour. Be aware that CO2 values are provided in the simulation sample size!"; - setGridMapStandards(viz, 12., data.compute(KelheimOfflineAirPollutionAnalysisByEngineInformation.class, "emissions_grid_per_hour.csv")); + DashboardUtils.setGridMapStandards(viz, data, "EPSG:25832"); + viz.file = data.compute(KelheimOfflineAirPollutionAnalysisByEngineInformation.class, "emissions_grid_per_hour.csv"); }); } - private static void setGridMapStandards(GridMap viz, double height, String data) { - viz.height = height; - viz.projection = "EPSG:25832"; - viz.file = data; - viz.setColorRamp(new double[]{30, 40, 50, 60, 70}, new String[]{DARK_BLUE, LIGHT_BLUE, YELLOW, SAND, ORANGE, RED}); - } } diff --git a/src/main/java/org/matsim/dashboard/KelheimSimWrapperRunner.java b/src/main/java/org/matsim/dashboard/KelheimSimWrapperRunner.java index 01b3c3a6..7baec11c 100644 --- a/src/main/java/org/matsim/dashboard/KelheimSimWrapperRunner.java +++ b/src/main/java/org/matsim/dashboard/KelheimSimWrapperRunner.java @@ -106,7 +106,7 @@ public Integer call() throws Exception { new DrtDashboardProvider().getDashboards(config, sw).forEach(sw::addDashboard); } if (noise){ - sw.addDashboard(new NoiseDashboard()); + sw.addDashboard(new NoiseDashboard(config.global().getCoordinateSystem())); } try { diff --git a/src/main/java/org/matsim/run/KelheimPtFareModule.java b/src/main/java/org/matsim/run/KelheimPtFareModule.java deleted file mode 100644 index 2f823747..00000000 --- a/src/main/java/org/matsim/run/KelheimPtFareModule.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.matsim.run; - -import org.matsim.api.core.v01.TransportMode; -import org.matsim.core.config.ConfigUtils; -import org.matsim.core.controler.AbstractModule; -import playground.vsp.pt.fare.DistanceBasedPtFareHandler; -import playground.vsp.pt.fare.DistanceBasedPtFareParams; -import playground.vsp.pt.fare.PtFareConfigGroup; -import playground.vsp.pt.fare.PtFareUpperBoundHandler; - -/** - * Module to install classes for pt fare. - */ -public class KelheimPtFareModule extends AbstractModule { - @Override - public void install() { - // Set the money related thing in the config (planCalcScore) file to 0. - getConfig().scoring().getModes().get(TransportMode.pt).setDailyMonetaryConstant(0); - getConfig().scoring().getModes().get(TransportMode.pt).setMarginalUtilityOfDistance(0); - - // Initialize config group (and also write in the output config) - PtFareConfigGroup ptFareConfigGroup = ConfigUtils.addOrGetModule(this.getConfig(), PtFareConfigGroup.class); - DistanceBasedPtFareParams distanceBasedPtFareParams = ConfigUtils.addOrGetModule(this.getConfig(), DistanceBasedPtFareParams.class); - - - // Add bindings - addEventHandlerBinding().toInstance(new DistanceBasedPtFareHandler(distanceBasedPtFareParams)); - if (ptFareConfigGroup.getApplyUpperBound()) { - PtFareUpperBoundHandler ptFareUpperBoundHandler = new PtFareUpperBoundHandler(ptFareConfigGroup.getUpperBoundFactor()); - addEventHandlerBinding().toInstance(ptFareUpperBoundHandler); - addControlerListenerBinding().toInstance(ptFareUpperBoundHandler); - } - } -} diff --git a/src/main/java/org/matsim/run/RunKelheimScenario.java b/src/main/java/org/matsim/run/RunKelheimScenario.java index d146f381..0a243b6e 100644 --- a/src/main/java/org/matsim/run/RunKelheimScenario.java +++ b/src/main/java/org/matsim/run/RunKelheimScenario.java @@ -43,6 +43,7 @@ import org.matsim.contrib.dvrp.run.DvrpModule; import org.matsim.contrib.dvrp.run.DvrpQSimComponents; import org.matsim.contrib.dvrp.trafficmonitoring.DvrpModeLimitedMaxSpeedTravelTimeModule; +import org.matsim.contrib.vsp.pt.fare.PtFareModule; import org.matsim.contrib.vsp.scenario.SnzActivities; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.config.Config; @@ -62,8 +63,8 @@ import org.matsim.simwrapper.SimWrapperModule; import org.matsim.vehicles.VehicleType; import picocli.CommandLine; -import playground.vsp.pt.fare.DistanceBasedPtFareParams; -import playground.vsp.pt.fare.PtFareConfigGroup; +import org.matsim.contrib.vsp.pt.fare.DistanceBasedPtFareParams; +import org.matsim.contrib.vsp.pt.fare.PtFareConfigGroup; import playground.vsp.scoring.IncomeDependentUtilityOfMoneyPersonScoringParameters; import javax.annotation.Nullable; @@ -221,16 +222,18 @@ protected Config prepareConfig(Config config) { // Minimum fare (e.g. short trip or 1 zone ticket) distanceBasedPtFareParams.setMinFare(2.0); - // Division between long trip and short trip (unit: m) - distanceBasedPtFareParams.setLongDistanceTripThreshold(50000); - // y = ax + b --> a value, for short trips - distanceBasedPtFareParams.setNormalTripSlope(0.00017); - // y = ax + b --> b value, for short trips - distanceBasedPtFareParams.setNormalTripIntercept(1.6); - // y = ax + b --> a value, for long trips - distanceBasedPtFareParams.setLongDistanceTripSlope(0.00025); - // y = ax + b --> b value, for long trips - distanceBasedPtFareParams.setLongDistanceTripIntercept(30); + + distanceBasedPtFareParams.setTransactionPartner("pt-operator"); + DistanceBasedPtFareParams.DistanceClassLinearFareFunctionParams shortDistance = distanceBasedPtFareParams.getOrCreateDistanceClassFareParams(50000); + shortDistance.setFareIntercept(1.6); + shortDistance.setFareSlope(0.00017); + + DistanceBasedPtFareParams.DistanceClassLinearFareFunctionParams longDistance = distanceBasedPtFareParams.getOrCreateDistanceClassFareParams(Double.POSITIVE_INFINITY); + longDistance.setFareIntercept(30); + longDistance.setFareSlope(0.00025); + distanceBasedPtFareParams.setOrder(1); + + ptFareConfigGroup.addParameterSet(distanceBasedPtFareParams); //enable plan inheritance analysis config.planInheritance().setEnabled(true); @@ -291,7 +294,7 @@ protected void prepareControler(Controler controler) { controler.addOverridingModule(new AbstractModule() { @Override public void install() { - install(new KelheimPtFareModule()); + install(new PtFareModule()); install(new SwissRailRaptorModule()); install(new PersonMoneyEventsAnalysisModule()); install(new SimWrapperModule()); @@ -377,17 +380,6 @@ public void install() { // TODO: when to include AV? //estimatorConfig.addParameterSet(new DrtEstimatorConfigGroup("av")); - -// if (intermodal){ -// controler.addOverridingModule(new IntermodalTripFareCompensatorsModule()); -// controler.addOverridingModule(new PtIntermodalRoutingModesModule()); -// controler.addOverridingModule(new AbstractModule() { -// @Override -// public void install() { -// bind(RaptorIntermodalAccessEgress.class).to(EnhancedRaptorIntermodalAccessEgress.class); -// } -// }); -// } } } }