├── codecov.yml ├── .gitignore ├── data └── db_stations.rda ├── tests ├── testthat.R └── testthat │ └── tests.R ├── NEWS.md ├── .Rbuildignore ├── .travis.yml ├── openbahn.Rproj ├── NAMESPACE ├── tools └── datasets.R ├── R ├── openbahn-package.R ├── openbahn_auth.R ├── data.R ├── helpers.R ├── openbahn_locations.R ├── openbahn_journeys.R ├── openbahn_departures.R └── openbahn_arrivals.R ├── man ├── openbahn-package.Rd ├── openbahn_auth.Rd ├── openbahn_locations.Rd ├── openbahn_arrivals.Rd ├── openbahn_departures.Rd ├── db_stations.Rd └── openbahn_journeys.Rd ├── DESCRIPTION ├── appveyor.yml ├── CONDUCT.md ├── README.Rmd ├── vignettes └── openbahn.Rmd └── README.md /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | inst/doc 6 | *.Rproj 7 | -------------------------------------------------------------------------------- /data/db_stations.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ottlngr/openbahn/HEAD/data/db_stations.rda -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(openbahn) 3 | 4 | test_check("openbahn") 5 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # openbahn 1.0.0 2 | 3 | * 4 | 5 | # openbahn 0.1.0 6 | 7 | * Initial version of `openbahn` 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^\.travis\.yml$ 4 | ^codecov\.yml$ 5 | ^README\.Rmd$ 6 | ^README-.*\.png$ 7 | ^CONDUCT\.md$ 8 | ^appveyor\.yml$ 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r 2 | 3 | language: R 4 | sudo: false 5 | cache: packages 6 | 7 | r_github_packages: 8 | - jimhester/covr 9 | after_success: 10 | - Rscript -e 'covr::codecov()' -------------------------------------------------------------------------------- /openbahn.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | BuildType: Package 16 | PackageUseDevtools: Yes 17 | PackageInstallArgs: --no-multiarch --with-keep.source 18 | PackageRoxygenize: rd,collate,namespace 19 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(print,openbahn_arrivals) 4 | S3method(print,openbahn_departures) 5 | S3method(print,openbahn_journeys) 6 | S3method(print,openbahn_locations) 7 | export(openbahn_arrivals) 8 | export(openbahn_auth) 9 | export(openbahn_departures) 10 | export(openbahn_journeys) 11 | export(openbahn_locations) 12 | importFrom(httr,GET) 13 | importFrom(httr,content) 14 | importFrom(httr,http_type) 15 | importFrom(httr,modify_url) 16 | importFrom(httr,user_agent) 17 | importFrom(jsonlite,fromJSON) 18 | -------------------------------------------------------------------------------- /tools/datasets.R: -------------------------------------------------------------------------------- 1 | library(readr) 2 | library(dplyr) 3 | 4 | db_stations_url <- "http://download-data.deutschebahn.com/static/datasets/haltestellen/D_Bahnhof_2017_09.csv" 5 | db_stations <- read_csv2(db_stations_url) %>% 6 | select("station_id" = EVA_NR, 7 | "authority" = DS100, 8 | "unique_station_key" = IFOPT, 9 | "station_name" = NAME, 10 | "station_traffic" = VERKEHR, 11 | "station_lon" = LAENGE, 12 | "station_lat" = BREITE, 13 | "station_status" = STATUS) 14 | devtools::use_data(db_stations, overwrite = TRUE) 15 | 16 | 17 | -------------------------------------------------------------------------------- /R/openbahn-package.R: -------------------------------------------------------------------------------- 1 | #' openbahn: Query the Deutsche Bahn Timetable API 2 | #' 3 | #' This package provides functions to query the Deutsche Bahn timetable 4 | #' API to find locations, get departure or arrival boards and to get 5 | #' further details for specific journeys. 6 | #' 7 | #' At the moment, only the timetable for German long distance traffic 8 | #' is supported. 9 | #' 10 | #' The use this package an API key is required. An API key can be 11 | #' obtained by mailing to \code{DBOpenData@deutschebahn.com}. 12 | #' 13 | #' To learn more about \code{openbahn}, start with the vignettes: 14 | #' \code{browseVignettes(package = "openbahn")} 15 | #' @docType package 16 | #' @name openbahn-package 17 | NULL -------------------------------------------------------------------------------- /man/openbahn-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/openbahn-package.R 3 | \docType{package} 4 | \name{openbahn-package} 5 | \alias{openbahn-package} 6 | \title{openbahn: Query the Deutsche Bahn Timetable API} 7 | \description{ 8 | This package provides functions to query the Deutsche Bahn timetable 9 | API to find locations, get departure or arrival boards and to get 10 | further details for specific journeys. 11 | } 12 | \details{ 13 | At the moment, only the timetable for German long distance traffic 14 | is supported. 15 | 16 | The use this package an API key is required. An API key can be 17 | obtained by mailing to \code{DBOpenData@deutschebahn.com}. 18 | 19 | To learn more about \code{openbahn}, start with the vignettes: 20 | \code{browseVignettes(package = "openbahn")} 21 | } 22 | -------------------------------------------------------------------------------- /man/openbahn_auth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/openbahn_auth.R 3 | \name{openbahn_auth} 4 | \alias{openbahn_auth} 5 | \title{Store the API key in an environment variable} 6 | \usage{ 7 | openbahn_auth(key) 8 | } 9 | \arguments{ 10 | \item{key}{character, the API key provided by \url{http://data.deutschebahn.com/}} 11 | } 12 | \description{ 13 | \code{openbahn_auth()} stores the API key in an environment variable to make it accessible for all \code{openbahn} functions. 14 | } 15 | \details{ 16 | The API key is stored in the environment variable \code{OPENBAHN_KEY}. In addition, \code{openbahn_auth()} sets another environment variable (\code{OPENBAHN_USER_AGENT}) holding the user agent which is used for HTTP calls. 17 | } 18 | \examples{ 19 | \dontrun{ 20 | openbahn_auth("YOUR_API_KEY_HERE") 21 | } 22 | } 23 | \author{ 24 | Philipp Ottolinger 25 | } 26 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: openbahn 2 | Type: Package 3 | Title: Query the Deutsche Bahn Timetable API 4 | Version: 1.0.0 5 | Authors@R: person("Philipp", "Ottolinger", email = "philipp@ottolinger.de", "role" = c("aut", "cre")) 6 | Maintainer: Philipp Ottolinger 7 | Description: This package queries the Deutsche Bahn Timetable API which covers the German long distance traffic. Each API endpoint is handled by its own function providing searches for locations, retrieval of arrival and departure boards as well as getting further details on specific journeys. 8 | URL: https://github.com/ottlngr/openbahn 9 | BugReports: http://github.com/ottlngr/openbahn/issues 10 | References: http://data.deutschebahn.com/dataset/api-fahrplan 11 | License: GPL-3 12 | Encoding: UTF-8 13 | LazyData: true 14 | RoxygenNote: 6.0.1 15 | Depends: R (>= 2.10) 16 | Imports: httr, jsonlite 17 | Suggests: testthat, 18 | covr, 19 | knitr, 20 | rmarkdown, 21 | dplyr, 22 | ggplot2, 23 | ggmap 24 | VignetteBuilder: knitr 25 | -------------------------------------------------------------------------------- /man/openbahn_locations.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/openbahn_locations.R 3 | \name{openbahn_locations} 4 | \alias{openbahn_locations} 5 | \title{Find a location} 6 | \usage{ 7 | openbahn_locations(query) 8 | } 9 | \arguments{ 10 | \item{query}{character, a city or train station to look for} 11 | } 12 | \value{ 13 | A \code{list} containing the \code{path}, \code{response} and \code{content} of the \code{GET} request. 14 | } 15 | \description{ 16 | \code{openbahn_locations()} enables you to find locations and their respective IDs and coordinates known by the API. 17 | } 18 | \details{ 19 | \code{openbahn_locations()} uses the API key stored by \code{openbahn_auth}. 20 | } 21 | \examples{ 22 | \dontrun{ 23 | # Set your API key 24 | openbahn_auth("YOUR_KEY_HERE") 25 | # Look for a location or station name 26 | openbahn_locations("Mainz Hbf") 27 | } 28 | } 29 | \references{ 30 | \url{http://data.deutschebahn.com/dataset/api-fahrplan} 31 | } 32 | \author{ 33 | Philipp Ottolinger 34 | } 35 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE the "init" and "install" sections below 2 | 3 | # Download script file from GitHub 4 | init: 5 | ps: | 6 | $ErrorActionPreference = "Stop" 7 | Invoke-WebRequest http://raw.github.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1" 8 | Import-Module '..\appveyor-tool.ps1' 9 | 10 | install: 11 | ps: Bootstrap 12 | 13 | cache: 14 | - C:\RLibrary 15 | 16 | # Adapt as necessary starting from here 17 | 18 | build_script: 19 | - travis-tool.sh install_deps 20 | 21 | test_script: 22 | - travis-tool.sh run_tests 23 | 24 | on_failure: 25 | - 7z a failure.zip *.Rcheck\* 26 | - appveyor PushArtifact failure.zip 27 | 28 | artifacts: 29 | - path: '*.Rcheck\**\*.log' 30 | name: Logs 31 | 32 | - path: '*.Rcheck\**\*.out' 33 | name: Logs 34 | 35 | - path: '*.Rcheck\**\*.fail' 36 | name: Logs 37 | 38 | - path: '*.Rcheck\**\*.Rout' 39 | name: Logs 40 | 41 | - path: '\*_*.tar.gz' 42 | name: Bits 43 | 44 | - path: '\*_*.zip' 45 | name: Bits 46 | -------------------------------------------------------------------------------- /R/openbahn_auth.R: -------------------------------------------------------------------------------- 1 | #' Store the API key in an environment variable 2 | #' 3 | #' \code{openbahn_auth()} stores the API key in an environment variable to make it accessible for all \code{openbahn} functions. 4 | #' 5 | #' @param key character, the API key provided by \url{http://data.deutschebahn.com/} 6 | #' @details The API key is stored in the environment variable \code{OPENBAHN_KEY}. In addition, \code{openbahn_auth()} sets another environment variable (\code{OPENBAHN_USER_AGENT}) holding the user agent which is used for HTTP calls. 7 | #' @author Philipp Ottolinger 8 | #' @examples 9 | #' \dontrun{ 10 | #' openbahn_auth("YOUR_API_KEY_HERE") 11 | #' } 12 | #' @export openbahn_auth 13 | openbahn_auth <- function(key) { 14 | 15 | if (missing(key)) { 16 | stop("Please provide your API key.", call. = FALSE) 17 | } 18 | 19 | if (typeof(key) != "character") { 20 | stop("Please provide a character string.", call. = FALSE) 21 | } 22 | 23 | Sys.setenv(OPENBAHN_KEY = key) 24 | Sys.setenv(OPENBAHN_USER_AGENT = "http://github.com/ottlngr/openbahn") 25 | 26 | } 27 | -------------------------------------------------------------------------------- /R/data.R: -------------------------------------------------------------------------------- 1 | #' All stations in German rail network 2 | #' 3 | #' A dataset containing all stations in the rail network of German railway company Deutsche Bahn. 4 | #' 5 | #' @format A data frame with 6605 rows and 8 variables: 6 | #' \describe{ 7 | #' \item{station_id}{Internal station id as also used by the Timetable API} 8 | #' \item{authority}{Superior authority of the station} 9 | #' \item{unique_station_key}{Unique station key} 10 | #' \item{station_name}{Name of the station} 11 | #' \item{station_traffic}{Type of traffic the station serves} 12 | #' \item{station_lon}{Longitude of the station} 13 | #' \item{station_lat}{Latitude of the station} 14 | #' \item{station_status}{Status of the station} 15 | #' } 16 | #' 17 | #' @details The \code{station_id} is the same id as used by the Timetable API in \code{locationNameApi()}. 18 | #' 19 | #' \code{station_traffic} indicates what type of traffic a stations serves, like long-distance traffic (\code{FV}), regional traffic only (\code{RV}) or regional traffic by not-state-owned companies only (\code{nur DPN}). 20 | #' 21 | #' @source \url{http://data.deutschebahn.com/dataset/data-haltestellen} 22 | "db_stations" -------------------------------------------------------------------------------- /man/openbahn_arrivals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/openbahn_arrivals.R 3 | \name{openbahn_arrivals} 4 | \alias{openbahn_arrivals} 5 | \title{Get an arrival board for a specific station} 6 | \usage{ 7 | openbahn_arrivals(id, date, time) 8 | } 9 | \arguments{ 10 | \item{id}{character, the internal ID of the station, received from \code{locationNameApi}.} 11 | 12 | \item{date}{character, the date of the arrival board in format \code{YYYY-MM-DD}. Must not be a past date.} 13 | 14 | \item{time}{character, the time of the arrival board in format \code{HH:MM:SS}.} 15 | } 16 | \value{ 17 | A \code{list} containing the \code{path}, \code{response} and \code{content} of the \code{GET} request. 18 | } 19 | \description{ 20 | \code{openbahn_arrivals} returns an arrival board for a specific station, date and time. 21 | } 22 | \details{ 23 | \code{openbahn_arrivals()} uses the API key stored by \code{openbahn_auth}. 24 | } 25 | \examples{ 26 | \dontrun{ 27 | # Set your API key 28 | openbahn_auth("YOUR_KEY_HERE") 29 | # Get an arrival board for a specific station, date and time 30 | openbahn_arrivals("008000240", date = Sys.Date() + 1, time = "12:00") 31 | } 32 | } 33 | \references{ 34 | \url{http://data.deutschebahn.com/dataset/api-fahrplan} 35 | } 36 | \author{ 37 | Philipp Ottolinger 38 | } 39 | -------------------------------------------------------------------------------- /man/openbahn_departures.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/openbahn_departures.R 3 | \name{openbahn_departures} 4 | \alias{openbahn_departures} 5 | \title{Get a departure board for a specific station} 6 | \usage{ 7 | openbahn_departures(id, date, time) 8 | } 9 | \arguments{ 10 | \item{id}{character, the internal ID of the station, received from \code{locationNameApi}.} 11 | 12 | \item{date}{character, the date of the departure board in format \code{YYYY-MM-DD}. Must not be a past date.} 13 | 14 | \item{time}{character, the time of the departure board in format \code{HH:MM:SS}.} 15 | } 16 | \value{ 17 | A \code{list} containing the \code{path}, \code{response} and \code{content} of the \code{GET} request. 18 | } 19 | \description{ 20 | \code{openbahn_departures} returns a departure board for a specific station, date and time. 21 | } 22 | \details{ 23 | \code{openbahn_departures()} uses the API key stored by \code{openbahn_auth}. 24 | } 25 | \examples{ 26 | \dontrun{ 27 | # Set your API key 28 | openbahn_auth("YOUR_KEY_HERE") 29 | # Get a departure board for a specific station, date and time 30 | openbahn_departures("008000240", date = Sys.Date() + 1, time = "12:00") 31 | } 32 | } 33 | \references{ 34 | \url{http://data.deutschebahn.com/dataset/api-fahrplan} 35 | } 36 | \author{ 37 | Philipp Ottolinger 38 | } 39 | -------------------------------------------------------------------------------- /man/db_stations.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{db_stations} 5 | \alias{db_stations} 6 | \title{All stations in German rail network} 7 | \format{A data frame with 6605 rows and 8 variables: 8 | \describe{ 9 | \item{station_id}{Internal station id as also used by the Timetable API} 10 | \item{authority}{Superior authority of the station} 11 | \item{unique_station_key}{Unique station key} 12 | \item{station_name}{Name of the station} 13 | \item{station_traffic}{Type of traffic the station serves} 14 | \item{station_lon}{Longitude of the station} 15 | \item{station_lat}{Latitude of the station} 16 | \item{station_status}{Status of the station} 17 | }} 18 | \source{ 19 | \url{http://data.deutschebahn.com/dataset/data-haltestellen} 20 | } 21 | \usage{ 22 | db_stations 23 | } 24 | \description{ 25 | A dataset containing all stations in the rail network of German railway company Deutsche Bahn. 26 | } 27 | \details{ 28 | The \code{station_id} is the same id as used by the Timetable API in \code{locationNameApi()}. 29 | 30 | \code{station_traffic} indicates what type of traffic a stations serves, like long-distance traffic (\code{FV}), regional traffic only (\code{RV}) or regional traffic by not-state-owned companies only (\code{nur DPN}). 31 | } 32 | \keyword{datasets} 33 | -------------------------------------------------------------------------------- /man/openbahn_journeys.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/openbahn_journeys.R 3 | \name{openbahn_journeys} 4 | \alias{openbahn_journeys} 5 | \title{Get details of a specific journey} 6 | \usage{ 7 | openbahn_journeys(reference_url) 8 | } 9 | \arguments{ 10 | \item{reference_url}{character, a reference url of a journey obtained using \code{departureBoardApi()} or \code{arrivalBoardApi()}.} 11 | } 12 | \value{ 13 | A \code{list} containing the \code{path}, \code{response} and \code{content} of the \code{GET} request. 14 | } 15 | \description{ 16 | \code{openbahn_journeys} returns detailed information on a journey found using \code{departureBoardApi()} or \code{arrivalBoardApi()}. 17 | } 18 | \details{ 19 | \code{openbahn_journeys()} uses the API key stored by \code{openbahn_auth}. 20 | } 21 | \examples{ 22 | \dontrun{ 23 | # Set your API key 24 | openbahn_auth("YOUR_KEY_HERE") 25 | # Get an arrival or departure board for a specific station, date and time 26 | dep <- departureBoardApi("008000240", date = Sys.Date() + 1, time = "12:00") 27 | # Get a reference URL for a specific train in the arrival or departure board 28 | ref <- dep$content$DepartureBoard$Departure$JourneyDetailRef$ref[1] 29 | # Get train details 30 | openbahn_journeys(ref) 31 | } 32 | } 33 | \references{ 34 | \url{http://data.deutschebahn.com/dataset/api-fahrplan} 35 | } 36 | \author{ 37 | Philipp Ottolinger 38 | } 39 | -------------------------------------------------------------------------------- /CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (http:contributor-covenant.org), version 1.0.0, available at 25 | http://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /R/helpers.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | print.openbahn_locations <- function(x, ...) { 3 | 4 | cat("< https://open-api.bahn.de/ >\n< ", x$path, " >\n\n", sep = "") 5 | print(x$content$LocationList$StopLocation) 6 | invisible(x) 7 | 8 | } 9 | 10 | #' @export 11 | print.openbahn_departures <- function(x, ...) { 12 | 13 | cat("< https://open-api.bahn.de/ >\n< ", x$path, " >\n\n", sep = "") 14 | obj <- x$content$DepartureBoard$Departure 15 | print(obj[, c("date", 16 | "time", 17 | "name", 18 | "type", 19 | "stopid", 20 | "stop", 21 | "direction", 22 | "track")]) 23 | invisible(x) 24 | 25 | } 26 | 27 | #' @export 28 | print.openbahn_arrivals <- function(x, ...) { 29 | 30 | cat("< https://open-api.bahn.de/ >\n< ", x$path, " >\n\n", sep = "") 31 | obj <- x$content$ArrivalBoard$Arrival 32 | print(obj[, c("date", 33 | "time", 34 | "name", 35 | "type", 36 | "stopid", 37 | "stop", 38 | "origin", 39 | "track")]) 40 | invisible(x) 41 | 42 | } 43 | 44 | #' @export 45 | print.openbahn_journeys <- function(x, ...) { 46 | 47 | cat("< https://open-api.bahn.de/ >\n< ", x$path, " >\n\n", sep = "") 48 | obj <- x$content$JourneyDetail$Stops$Stop 49 | print(obj[, c("routeIdx", 50 | "name", 51 | "id", 52 | "depDate", 53 | "depTime", 54 | "arrDate", 55 | "arrTime", 56 | "track")]) 57 | invisible(x) 58 | 59 | } 60 | 61 | # #' @export 62 | openbahn_check_auth <- function() { 63 | x <- Sys.getenv("OPENBAHN_KEY") 64 | if (x == "") { 65 | stop("No API key found in the current environment. 66 | Please use openbahn_auth() to provide an API key.", 67 | .call = FALSE) 68 | } else { 69 | message("Using provided API key.\n\n") 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /R/openbahn_locations.R: -------------------------------------------------------------------------------- 1 | #' Find a location 2 | #' 3 | #' \code{openbahn_locations()} enables you to find locations and their respective IDs and coordinates known by the API. 4 | #' 5 | #' @param query character, a city or train station to look for 6 | #' @return A \code{list} containing the \code{path}, \code{response} and \code{content} of the \code{GET} request. 7 | #' @details \code{openbahn_locations()} uses the API key stored by \code{openbahn_auth}. 8 | #' @author Philipp Ottolinger 9 | #' @references \url{http://data.deutschebahn.com/dataset/api-fahrplan} 10 | #' @importFrom httr modify_url user_agent GET http_type content 11 | #' @importFrom jsonlite fromJSON 12 | #' @examples 13 | #' \dontrun{ 14 | #' # Set your API key 15 | #' openbahn_auth("YOUR_KEY_HERE") 16 | #' # Look for a location or station name 17 | #' openbahn_locations("Mainz Hbf") 18 | #' } 19 | #' @export openbahn_locations 20 | openbahn_locations <- function(query) { 21 | 22 | if (missing(query)) { 23 | stop("No query string provided.", call. = FALSE) 24 | } 25 | 26 | openbahn_check_auth() 27 | 28 | base_url <- "https://open-api.bahn.de/bin/rest.exe/" 29 | api_path <- "bin/rest.exe/location.name" 30 | api_format <- "json" 31 | api_key <- Sys.getenv("OPENBAHN_KEY") 32 | 33 | request <- modify_url(base_url, 34 | path = api_path, 35 | query = list(authKey = api_key, 36 | format = api_format, 37 | input = query)) 38 | 39 | ua <- user_agent(Sys.getenv("OPENBAHN_USER_AGENT")) 40 | 41 | response <- GET(request, ua) 42 | 43 | if (http_type(response) != "application/json") { 44 | stop("API did not return JSON.", .call = FALSE) 45 | } 46 | 47 | parsed <- fromJSON(content(response, "text")) 48 | 49 | structure( 50 | list( 51 | content = parsed, 52 | path = api_path, 53 | response = response 54 | ), 55 | class = "openbahn_locations" 56 | ) 57 | } 58 | -------------------------------------------------------------------------------- /R/openbahn_journeys.R: -------------------------------------------------------------------------------- 1 | #' Get details of a specific journey 2 | #' 3 | #' \code{openbahn_journeys} returns detailed information on a journey found using \code{departureBoardApi()} or \code{arrivalBoardApi()}. 4 | #' 5 | #' @param reference_url character, a reference url of a journey obtained using \code{departureBoardApi()} or \code{arrivalBoardApi()}. 6 | #' @return A \code{list} containing the \code{path}, \code{response} and \code{content} of the \code{GET} request. 7 | #' @details \code{openbahn_journeys()} uses the API key stored by \code{openbahn_auth}. 8 | #' @author Philipp Ottolinger 9 | #' @references \url{http://data.deutschebahn.com/dataset/api-fahrplan} 10 | #' @importFrom httr modify_url user_agent GET http_type content 11 | #' @importFrom jsonlite fromJSON 12 | #' @examples 13 | #' \dontrun{ 14 | #' # Set your API key 15 | #' openbahn_auth("YOUR_KEY_HERE") 16 | #' # Get an arrival or departure board for a specific station, date and time 17 | #' dep <- departureBoardApi("008000240", date = Sys.Date() + 1, time = "12:00") 18 | #' # Get a reference URL for a specific train in the arrival or departure board 19 | #' ref <- dep$content$DepartureBoard$Departure$JourneyDetailRef$ref[1] 20 | #' # Get train details 21 | #' openbahn_journeys(ref) 22 | #' } 23 | #' @export openbahn_journeys 24 | openbahn_journeys <- function(reference_url) { 25 | 26 | if (missing(reference_url)) { 27 | stop("No reference url provided.", call. = FALSE) 28 | } 29 | 30 | api_path <- "bin/rest.exe/journeyDetail" 31 | 32 | request <- reference_url 33 | 34 | ua <- user_agent(Sys.getenv("OPENBAHN_USER_AGENT")) 35 | 36 | response <- GET(request, ua) 37 | 38 | if (http_type(response) != "application/json") { 39 | stop("API did not return JSON.", .call = FALSE) 40 | } 41 | 42 | parsed <- fromJSON(content(response, "text")) 43 | 44 | structure( 45 | list( 46 | content = parsed, 47 | path = api_path, 48 | response = response 49 | ), 50 | class = c("openbahn_journeys") 51 | ) 52 | 53 | } 54 | -------------------------------------------------------------------------------- /R/openbahn_departures.R: -------------------------------------------------------------------------------- 1 | #' Get a departure board for a specific station 2 | #' 3 | #' \code{openbahn_departures} returns a departure board for a specific station, date and time. 4 | #' 5 | #' @param id character, the internal ID of the station, received from \code{locationNameApi}. 6 | #' @param date character, the date of the departure board in format \code{YYYY-MM-DD}. Must not be a past date. 7 | #' @param time character, the time of the departure board in format \code{HH:MM:SS}. 8 | #' @return A \code{list} containing the \code{path}, \code{response} and \code{content} of the \code{GET} request. 9 | #' @details \code{openbahn_departures()} uses the API key stored by \code{openbahn_auth}. 10 | #' @author Philipp Ottolinger 11 | #' @references \url{http://data.deutschebahn.com/dataset/api-fahrplan} 12 | #' @importFrom httr modify_url user_agent GET http_type content 13 | #' @importFrom jsonlite fromJSON 14 | #' @examples 15 | #' \dontrun{ 16 | #' # Set your API key 17 | #' openbahn_auth("YOUR_KEY_HERE") 18 | #' # Get a departure board for a specific station, date and time 19 | #' openbahn_departures("008000240", date = Sys.Date() + 1, time = "12:00") 20 | #' } 21 | #' @export openbahn_departures 22 | openbahn_departures <- function(id, date, time) { 23 | if (missing(id)) { 24 | stop("No id provided.", call. = FALSE) 25 | } 26 | if (missing(date)) { 27 | stop("No date provided.", call. = FALSE) 28 | } 29 | if (missing(time)) { 30 | stop("No time provided.", call. = FALSE) 31 | } 32 | 33 | openbahn_check_auth() 34 | 35 | base_url <- "https://open-api.bahn.de/bin/rest.exe/" 36 | api_path <- "bin/rest.exe/departureBoard" 37 | api_format <- "json" 38 | api_key <- Sys.getenv("OPENBAHN_KEY") 39 | 40 | request <- modify_url( 41 | base_url, 42 | path = api_path, 43 | query = list( 44 | authKey = api_key, 45 | format = api_format, 46 | id = id, 47 | date = date, 48 | time = time 49 | ) 50 | ) 51 | 52 | ua <- user_agent(Sys.getenv("OPENBAHN_USER_AGENT")) 53 | 54 | response <- GET(request, ua) 55 | 56 | if (http_type(response) != "application/json") { 57 | stop("API did not return JSON.", .call = FALSE) 58 | } 59 | 60 | parsed <- fromJSON(content(response, "text")) 61 | 62 | if ("errorCode" %in% names(parsed$DepartureBoard)) { 63 | stop( 64 | sprintf( 65 | "API request failed with error <%s>:\n%s", 66 | parsed$DepartureBoard$errorCode, 67 | parsed$DepartureBoard$errorText 68 | ), 69 | call. = FALSE 70 | ) 71 | } 72 | 73 | ### 74 | if ("tyte" %in% colnames(parsed$DepartureBoard$Departure)) { 75 | parsed$DepartureBoard$Departure$type <- 76 | ifelse( 77 | is.na(parsed$DepartureBoard$Departure$type), 78 | parsed$DepartureBoard$Departure$tyte, 79 | parsed$DepartureBoard$Departure$type 80 | ) 81 | parsed$DepartureBoard$Departure$tyte <- NULL 82 | } 83 | ### 84 | 85 | structure(list( 86 | content = parsed, 87 | path = api_path, 88 | response = response 89 | ), 90 | class = "openbahn_departures") 91 | 92 | } 93 | -------------------------------------------------------------------------------- /tests/testthat/tests.R: -------------------------------------------------------------------------------- 1 | l <- openbahn_locations("Mainz Hbf") 2 | a <- openbahn_arrivals("008000240", Sys.Date() + 1, "12:00:00") 3 | d <- openbahn_departures("008000240", Sys.Date() + 1, "12:00:00") 4 | j <- openbahn_journeys(a$content$ArrivalBoard$Arrival$JourneyDetailRef$ref[1]) 5 | 6 | test_that("Results have the right class", { 7 | 8 | expect_true(class(l) == "openbahn_locations") 9 | expect_true(class(a) == "openbahn_arrivals") 10 | expect_true(class(d) == "openbahn_departures") 11 | expect_true(class(j) == "openbahn_journeys") 12 | 13 | }) 14 | 15 | test_that("Results have named objects", { 16 | 17 | expect_named(l, c("content", "path", "response"), ignore.order = TRUE) 18 | expect_named(a, c("content", "path", "response"), ignore.order = TRUE) 19 | expect_named(d, c("content", "path", "response"), ignore.order = TRUE) 20 | expect_named(j, c("content", "path", "response"), ignore.order = TRUE) 21 | 22 | }) 23 | 24 | test_that("openbahn_arrivals() throws errors", { 25 | 26 | expect_error( 27 | openbahn_arrivals(date = Sys.Date() + 1, time = "12:00:00"), 28 | "No id provided." 29 | ) 30 | expect_error( 31 | openbahn_arrivals(id = "008000240", time = "12:00:00"), 32 | "No date provided." 33 | ) 34 | expect_error( 35 | openbahn_arrivals(id = "008000240", date = Sys.Date() + 1), 36 | "No time provided." 37 | ) 38 | 39 | }) 40 | 41 | test_that("openbahn_departures() throws errors", { 42 | 43 | expect_error( 44 | openbahn_departures(date = Sys.Date() + 1, time = "12:00:00"), 45 | "No id provided." 46 | ) 47 | expect_error( 48 | openbahn_departures(id = "008000240", time = "12:00:00"), 49 | "No date provided." 50 | ) 51 | expect_error( 52 | openbahn_departures(id = "008000240", date = Sys.Date() + 1), 53 | "No time provided." 54 | ) 55 | 56 | }) 57 | 58 | test_that("journeyDetailsApi() throws error", { 59 | 60 | expect_error(openbahn_journeys(), "No reference url provided.") 61 | 62 | }) 63 | 64 | test_that("openbahn_check_auth() works", { 65 | 66 | expect_message(openbahn:::openbahn_check_auth(), "Using provided API key.") 67 | 68 | }) 69 | 70 | test_that("print methods", { 71 | 72 | expect_true(capture.output(a)[1] == "< https://open-api.bahn.de/ >") 73 | expect_true(capture.output(a)[2] == "< bin/rest.exe/arrivalBoard >") 74 | 75 | expect_true(capture.output(d)[1] == "< https://open-api.bahn.de/ >") 76 | expect_true(capture.output(d)[2] == "< bin/rest.exe/departureBoard >") 77 | 78 | expect_true(capture.output(l)[1] == "< https://open-api.bahn.de/ >") 79 | expect_true(capture.output(l)[2] == "< bin/rest.exe/location.name >") 80 | 81 | expect_true(capture.output(j)[1] == "< https://open-api.bahn.de/ >") 82 | expect_true(capture.output(j)[2] == "< bin/rest.exe/journeyDetail >") 83 | 84 | }) 85 | 86 | test_that("openbahn_locations() throws error", { 87 | 88 | expect_error(openbahn_locations(), "No query string provided.") 89 | 90 | }) 91 | 92 | test_that("openbahn_auth() throws error", { 93 | 94 | expect_error(openbahn_auth(), "Please provide your API key.") 95 | expect_error(openbahn_auth(123), "Please provide a character") 96 | }) 97 | -------------------------------------------------------------------------------- /R/openbahn_arrivals.R: -------------------------------------------------------------------------------- 1 | #' Get an arrival board for a specific station 2 | #' 3 | #' \code{openbahn_arrivals} returns an arrival board for a specific station, date and time. 4 | #' 5 | #' @param id character, the internal ID of the station, received from \code{locationNameApi}. 6 | #' @param date character, the date of the arrival board in format \code{YYYY-MM-DD}. Must not be a past date. 7 | #' @param time character, the time of the arrival board in format \code{HH:MM:SS}. 8 | #' @return A \code{list} containing the \code{path}, \code{response} and \code{content} of the \code{GET} request. 9 | #' @details \code{openbahn_arrivals()} uses the API key stored by \code{openbahn_auth}. 10 | #' @author Philipp Ottolinger 11 | #' @references \url{http://data.deutschebahn.com/dataset/api-fahrplan} 12 | #' @importFrom httr modify_url user_agent GET http_type content 13 | #' @importFrom jsonlite fromJSON 14 | #' @examples 15 | #' \dontrun{ 16 | #' # Set your API key 17 | #' openbahn_auth("YOUR_KEY_HERE") 18 | #' # Get an arrival board for a specific station, date and time 19 | #' openbahn_arrivals("008000240", date = Sys.Date() + 1, time = "12:00") 20 | #' } 21 | #' @export openbahn_arrivals 22 | openbahn_arrivals <- function(id, date, time) { 23 | 24 | if (missing(id)) { 25 | stop("No id provided.", call. = FALSE) 26 | } 27 | if (missing(date)) { 28 | stop("No date provided.", call. = FALSE) 29 | } 30 | if (missing(time)) { 31 | stop("No time provided.", call. = FALSE) 32 | } 33 | 34 | openbahn_check_auth() 35 | 36 | base_url <- "https://open-api.bahn.de/bin/rest.exe/" 37 | api_path <- "bin/rest.exe/arrivalBoard" 38 | api_format <- "json" 39 | api_key <- Sys.getenv("OPENBAHN_KEY") 40 | 41 | request <- modify_url(base_url, 42 | path = api_path, 43 | query = list(authKey = api_key, 44 | format = api_format, 45 | id = id, 46 | date = date, 47 | time = time)) 48 | 49 | ua <- user_agent(Sys.getenv("OPENBAHN_USER_AGENT")) 50 | 51 | response <- GET(request, ua) 52 | 53 | if (http_type(response) != "application/json") { 54 | stop("API did not return JSON.", .call = FALSE) 55 | } 56 | 57 | parsed <- fromJSON(content(response, "text")) 58 | 59 | if ("errorCode" %in% names(parsed$ArrivalBoard)) { 60 | stop( 61 | sprintf( 62 | "API request failed with error <%s>:\n%s", 63 | parsed$ArrivalBoard$errorCode, 64 | parsed$ArrivalBoard$errorText 65 | ), 66 | call. = FALSE 67 | ) 68 | } 69 | 70 | ### 71 | if ("tyte" %in% colnames(parsed$ArrivalBoard$Arrival)) { 72 | parsed$ArrivalBoard$Arrival$type <- ifelse( 73 | is.na(parsed$ArrivalBoard$Arrivaltype), 74 | parsed$ArrivalBoard$Arrival$tyte, 75 | parsed$ArrivalBoard$Arrival$type) 76 | parsed$ArrivalBoard$Arrival$tyte <- NULL 77 | } 78 | ### 79 | 80 | structure( 81 | list( 82 | content = parsed, 83 | path = api_path, 84 | response = response 85 | ), 86 | class = "openbahn_arrivals" 87 | ) 88 | 89 | } 90 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, echo = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "README-" 12 | ) 13 | options(width = 999) 14 | ``` 15 | 16 | # openbahn 17 | 18 | [![CRAN\_Status\_Badge](http://www.r-pkg.org/badges/version/openbahn)](https://cran.r-project.org/package=openbahn) [![Travis-CI](https://api.travis-ci.org/ottlngr/openbahn.svg)](https://travis-ci.org/ottlngr/openbahn) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/ottlngr/openbahn?branch=master&svg=true)](https://ci.appveyor.com/project/ottlngr/openbahn) [![codecov](https://codecov.io/gh/ottlngr/openbahn/branch/master/graph/badge.svg)](https://codecov.io/gh/ottlngr/openbahn) [![](http://cranlogs.r-pkg.org/badges/openbahn)](http://cran.rstudio.com/web/packages/openbahn/index.html) 19 | 20 | 21 | 22 | `openbahn` provides functions to easily interact with the Timetable API, provided by the German railroad company _Deutsche Bahn_ (DB). At the moment, the API does only provide timetable data for the German long-distance traffic. The following API endpoints exist and are covered by `openbahn`: 23 | 24 | - `openbahn_locations` to look up train stations 25 | - `openbahn_arrivals` to retrieve arrival boards 26 | - `openbahn_departures` to retrieve departure boards 27 | - `openbahn_jounreys` to retrieve detailed information for specific trains 28 | 29 | To interact with the API, an API key is required. 30 | 31 | ## API Key 32 | 33 | To get an API key, one has to email to the [DB Open-Data-Team](mailto:DBOpenData@deutschebahn.com) and request a key for the timetable or _Fahrplan_ API, respectively. 34 | 35 | ## Installation 36 | 37 | You can install openbahn from github with: 38 | 39 | ```{r gh-installation, eval = FALSE} 40 | # install.packages("devtools") 41 | devtools::install_github("ottlngr/openbahn") 42 | ``` 43 | 44 | ## Usage 45 | 46 | First, `openbahn_auth()` can be used to store the API key in an environment variable all further `openbahn` functions will access: 47 | 48 | ```{r} 49 | library(openbahn) 50 | ``` 51 | 52 | ```{r,eval=FALSE} 53 | openbahn_auth("YOUR_API_KEY_HERE") 54 | ``` 55 | 56 | `openbahn_locations()` can be used to find a train station along with an internal ID and its coordinates: 57 | 58 | ```{r} 59 | stations <- openbahn_locations(query = "Mainz Hbf") 60 | stations 61 | ``` 62 | 63 | To retrieve arrival or departure boards, an `id` found in `stations` can be used. Furthermore, date and time the arrival or departure boards shall build on have to be provided: 64 | 65 | ```{r} 66 | mainz_hbf <- stations$content$LocationList$StopLocation$id[1] 67 | 68 | departures <- openbahn_departures(id = mainz_hbf, date = Sys.Date() + 1, time = "12:00") 69 | departures 70 | 71 | arrivals <- openbahn_arrivals(id = mainz_hbf, date = Sys.Date() + 1, time = "12:00") 72 | arrivals 73 | ``` 74 | 75 | For the particular trains in the arrival or departures board one can retrieve detailed information using `openbahn_journey()`. Therefor, the reference url of the desired train has to be looked up in the `JourneyDetailRef` data.frame: 76 | 77 | ```{r} 78 | reference <- departures$content$DepartureBoard$Departure$JourneyDetailRef$ref[1] 79 | details <- openbahn_journeys(reference_url = reference) 80 | details 81 | ``` 82 | 83 | ## References 84 | 85 | For general information on the DB Timetable API visit http://data.deutschebahn.com/dataset/api-fahrplan (German). The data behind this API is licenced unter CC BY 4.0. 86 | 87 | # Community Guidelines 88 | 89 | Please note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). By participating in this project you agree to abide by its terms. 90 | -------------------------------------------------------------------------------- /vignettes/openbahn.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "openbahn - Query the Deutsche Bahn Timetable API " 3 | author: "Philip Ottolinger" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{openbahn} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | # openbahn 13 | 14 | In 2016, the German railway company _Deutsche Bahn_ launched its Open Data portal, where a growing number of datasets are made available. Besides datasets, _Deutsche Bahn_ also offers some APIs to access even more data in a machine readable manner. 15 | 16 | One of these APIs is the timetable or _Fahrplan_ API, which offers target timetables for the German long-distance rail traffic. `openbahn` is mainly a wrapper around this API and provides additional static datasets from _Deutsche Bahn_. 17 | 18 | ## Using openbahn 19 | 20 | ### API key 21 | 22 | To use `openbahn` or the timetable API in general, one has to acquire an API key from the _Deutsche Bahn_ Open Data team. The easiest way to get such an API key is to email the Open Data team at [DBOpenData@deutschebahn.com](mailto:DBOpenData@deutschebahn.com) as described on the [website](http://data.deutschebahn.com/dataset/api-fahrplan). 23 | 24 | To avoid having to specify the API key with every call to the API, `openbahn` offers the `openbahn_auth()` function to store your API key in an environment variable in your R session. When necessary, `openbahn` will look for this environment variable and will read the API key from it. 25 | 26 | ```{r,eval=FALSE,message=FALSE} 27 | library(openbahn) 28 | 29 | openbahn_auth("YOUR_API_KEY_HERE") 30 | ``` 31 | 32 | The API key is now stored in your R session in the `OPENBAHN_KEY` variable. Along with the API key, also a user agent is set with `openbahn_auth()` used to identify towards the API: 33 | 34 | ```{r,message=FALSE} 35 | Sys.getenv("OPENBAHN_USER_AGENT") 36 | ``` 37 | 38 | ### Arrival and departure boards 39 | 40 | The timetable API returns arrival and departure boards for a given station on a specific date and time. Each station has an internal ID, which can be obtained from `locationNameApi()` which takes a character as input and returns a couple of stations matching the query: 41 | 42 | ```{r,echo=FALSE} 43 | library(openbahn) 44 | ``` 45 | 46 | ```{r,message=FALSE} 47 | openbahn_locations(query = "Mainz Hbf") 48 | ``` 49 | 50 | Along with the station name and ID, `openbahn_locations()` also returns the coordinates of the stations, which is handy for spatial applications. For later usage, we will store the station ID of _Mainz Hbf_ in a variable: 51 | 52 | ```{r,message=FALSE} 53 | station_id <- "008000240" 54 | ``` 55 | 56 | Now having the desired station ID, `openbahn_arrivals()` and `openbahn_departures()` can be used. To look for trains leaving _Mainz Hbf_ at 9 a.m., use `openbahn_departures()` as follows: 57 | 58 | ```{r,message=FALSE} 59 | date <- Sys.Date() + 1 60 | 61 | dep <- openbahn_departures(id = station_id, date = date, time = "09:00") 62 | dep 63 | ``` 64 | 65 | ### Journey details 66 | 67 | The API offers an additional endpoint, which returns details to every connection found by using `openbahn_arrivals()` or `openbahn_departures()`. Using `openbahn_journeys()` one can use the reference links in the arrival or departure boards to get further information such as name and order of all stops, arrival and departure times and geocoordinates of all stops. 68 | 69 | Every arrival or departure board has a column with reference links, which can be called with `openbahn_journeys()`: 70 | 71 | ```{r,message=FALSE} 72 | url <- dep$content$DepartureBoard$Departure$JourneyDetailRef$ref[1] 73 | 74 | journey <- openbahn_journeys(url) 75 | 76 | journey 77 | ``` 78 | 79 | The print method hides the geocoordinates, but they are present in the data.frame: 80 | 81 | ```{r,message=FALSE} 82 | str(journey$content$JourneyDetail$Stops$Stop) 83 | ``` 84 | 85 | Using them it is easy to plot the route of the train onto a map: 86 | 87 | ```{r,message=FALSE} 88 | library(dplyr) 89 | library(ggplot2) 90 | library(ggmap) 91 | 92 | germany <- get_map(c(10.140, 51.276), zoom = 6, maptype = "toner") 93 | 94 | data <- journey$content$JourneyDetail$Stops$Stop %>% 95 | mutate(lat = as.numeric(lat), 96 | lon = as.numeric(lon)) 97 | 98 | ggmap(germany) + 99 | geom_point(data = data, aes(x = lon, y = lat, group = 1)) + 100 | geom_path(data = data, aes(x = lon, y = lat, group = 1)) + 101 | coord_map() 102 | ``` 103 | 104 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | openbahn 4 | ======== 5 | 6 | [![CRAN\_Status\_Badge](http://www.r-pkg.org/badges/version/openbahn)](https://cran.r-project.org/package=openbahn) [![Travis-CI](https://api.travis-ci.org/ottlngr/openbahn.svg)](https://travis-ci.org/ottlngr/openbahn) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/ottlngr/openbahn?branch=master&svg=true)](https://ci.appveyor.com/project/ottlngr/openbahn) [![codecov](https://codecov.io/gh/ottlngr/openbahn/branch/master/graph/badge.svg)](https://codecov.io/gh/ottlngr/openbahn) [![](http://cranlogs.r-pkg.org/badges/openbahn)](http://cran.rstudio.com/web/packages/openbahn/index.html) 7 | 8 | `openbahn` provides functions to easily interact with the Timetable API, provided by the German railroad company *Deutsche Bahn* (DB). At the moment, the API does only provide timetable data for the German long-distance traffic. The following API endpoints exist and are covered by `openbahn`: 9 | 10 | - `openbahn_locations` to look up train stations 11 | - `openbahn_arrivals` to retrieve arrival boards 12 | - `openbahn_departures` to retrieve departure boards 13 | - `openbahn_jounreys` to retrieve detailed information for specific trains 14 | 15 | To interact with the API, an API key is required. 16 | 17 | API Key 18 | ------- 19 | 20 | To get an API key, one has to email to the [DB Open-Data-Team](mailto:DBOpenData@deutschebahn.com) and request a key for the timetable or *Fahrplan* API, respectively. 21 | 22 | Installation 23 | ------------ 24 | 25 | You can install openbahn from github with: 26 | 27 | ``` r 28 | # install.packages("devtools") 29 | devtools::install_github("ottlngr/openbahn") 30 | ``` 31 | 32 | Usage 33 | ----- 34 | 35 | First, `openbahn_auth()` can be used to store the API key in an environment variable all further `openbahn` functions will access: 36 | 37 | ``` r 38 | library(openbahn) 39 | ``` 40 | 41 | ``` r 42 | openbahn_auth("YOUR_API_KEY_HERE") 43 | ``` 44 | 45 | `openbahn_locations()` can be used to find a train station along with an internal ID and its coordinates: 46 | 47 | ``` r 48 | stations <- openbahn_locations(query = "Mainz Hbf") 49 | #> Using provided API key. 50 | stations 51 | #> < https://open-api.bahn.de/ > 52 | #> < bin/rest.exe/location.name > 53 | #> 54 | #> name lon lat id 55 | #> 1 Mainz Hbf 8.258723 50.001113 008000240 56 | #> 2 Frankfurt(Main)Hbf 8.663785 50.107149 008000105 57 | #> 3 Mailand Hbf 9.204828 45.487143 008300046 58 | #> 4 FRANKFURT(MAIN) 8.663785 50.107149 008096021 59 | #> 5 Frankfurt am Main Flughafen Fernbahnhof 8.570181 50.053169 008070003 60 | #> 6 Frankfurt(Main)Flugh 8.570972 50.051210 008000281 61 | #> 7 Linz/Donau main stat 14.292129 48.290178 008100013 62 | #> 8 Frankfurt(Main)Süd 8.686456 50.099365 008002041 63 | #> 9 Frankfurt(Main)West 8.639335 50.118862 008002042 64 | #> 10 Frankfurt am Main Flughafen Regiobahnhof 8.571250 50.051219 008070004 65 | #> 11 St.Pölten main stat 15.624672 48.208304 008100008 66 | #> 12 Vienna main station 16.375865 48.184923 008103000 67 | #> 13 Zurich Main Station 8.539204 47.378186 008503000 68 | #> 14 Verona Main Station 10.982742 45.428660 008300120 69 | #> 15 Bayerisch Gmain 12.895071 47.720379 008000831 70 | #> 16 Geneva Main Station 6.142122 46.210416 008501008 71 | #> 17 MAILAND 9.207597 45.462477 008396005 72 | ``` 73 | 74 | To retrieve arrival or departure boards, an `id` found in `stations` can be used. Furthermore, date and time the arrival or departure boards shall build on have to be provided: 75 | 76 | ``` r 77 | mainz_hbf <- stations$content$LocationList$StopLocation$id[1] 78 | 79 | departures <- openbahn_departures(id = mainz_hbf, date = Sys.Date() + 1, time = "12:00") 80 | #> Using provided API key. 81 | departures 82 | #> < https://open-api.bahn.de/ > 83 | #> < bin/rest.exe/departureBoard > 84 | #> 85 | #> date time name type stopid stop direction track 86 | #> 1 2018-06-04 12:20 IC 2024 IC 8000240 Mainz Hbf Hamburg-Altona 3a/b 87 | #> 2 2018-06-04 12:42 EC 9 EC 8000240 Mainz Hbf Zürich HB 5a/b 88 | #> 3 2018-06-04 12:43 ICE 1651 ICE 8000240 Mainz Hbf Dresden Hbf 4a/b 89 | #> 4 2018-06-04 13:12 IC 2013 IC 8000240 Mainz Hbf Oberstdorf 5a/b 90 | #> 5 2018-06-04 13:20 IC 2312 IC 8000240 Mainz Hbf Hamburg-Altona 3a/b 91 | #> 6 2018-06-04 13:22 ICE 1652 ICE 8000240 Mainz Hbf Wiesbaden Hbf 2a/b 92 | #> 7 2018-06-04 13:41 IC 2023 IC 8000240 Mainz Hbf Frankfurt(Main)Hbf 4a/b 93 | #> 8 2018-06-04 14:20 IC 2026 IC 8000240 Mainz Hbf Hamburg-Altona 3a/b 94 | #> 9 2018-06-04 14:42 IC 2313 IC 8000240 Mainz Hbf Offenburg 5a/b 95 | #> 10 2018-06-04 14:43 ICE 1653 ICE 8000240 Mainz Hbf Dresden Hbf 4a/b 96 | #> 11 2018-06-04 14:49 IC 2012 IC 8000240 Mainz Hbf Magdeburg Hbf 2a/b 97 | #> 12 2018-06-04 15:20 EC 8 EC 8000240 Mainz Hbf Hamburg-Altona 3a/b 98 | #> 13 2018-06-04 15:22 ICE 1650 ICE 8000240 Mainz Hbf Wiesbaden Hbf 2a/b 99 | #> 14 2018-06-04 15:41 IC 2025 IC 8000240 Mainz Hbf Frankfurt(Main)Hbf 4a/b 100 | #> 15 2018-06-04 16:20 IC 2022 IC 8000240 Mainz Hbf Hamburg-Altona 3a/b 101 | #> 16 2018-06-04 16:22 ICE 710 ICE 8000240 Mainz Hbf Köln Hbf 2a/b 102 | #> 17 2018-06-04 16:42 IC 2217 IC 8000240 Mainz Hbf Stuttgart Hbf 5a/b 103 | #> 18 2018-06-04 16:43 ICE 1655 ICE 8000240 Mainz Hbf Dresden Hbf 4a/b 104 | #> 19 2018-06-04 16:48 IC 118 IC 8000240 Mainz Hbf Münster(Westf)Hbf 1a/b 105 | #> 20 2018-06-04 17:12 IC 2011 IC 8000240 Mainz Hbf Tübingen Hbf 5a/b 106 | 107 | arrivals <- openbahn_arrivals(id = mainz_hbf, date = Sys.Date() + 1, time = "12:00") 108 | #> Using provided API key. 109 | arrivals 110 | #> < https://open-api.bahn.de/ > 111 | #> < bin/rest.exe/arrivalBoard > 112 | #> 113 | #> date time name type stopid stop origin track 114 | #> 1 2018-06-04 12:18 IC 2024 IC 8000240 Mainz Hbf Passau Hbf 3a/b 115 | #> 2 2018-06-04 12:36 ICE 1651 ICE 8000240 Mainz Hbf Wiesbaden Hbf 4a/b 116 | #> 3 2018-06-04 12:39 EC 9 EC 8000240 Mainz Hbf Hamburg-Altona 5a/b 117 | #> 4 2018-06-04 13:10 IC 2013 IC 8000240 Mainz Hbf Leipzig Hbf 5a/b 118 | #> 5 2018-06-04 13:15 ICE 1652 ICE 8000240 Mainz Hbf Dresden Hbf 2a/b 119 | #> 6 2018-06-04 13:18 IC 2312 IC 8000240 Mainz Hbf Stuttgart Hbf 3a/b 120 | #> 7 2018-06-04 13:39 IC 2023 IC 8000240 Mainz Hbf Hamburg-Altona 4a/b 121 | #> 8 2018-06-04 14:18 IC 2026 IC 8000240 Mainz Hbf Frankfurt(Main)Hbf 3a/b 122 | #> 9 2018-06-04 14:36 ICE 1653 ICE 8000240 Mainz Hbf Wiesbaden Hbf 4a/b 123 | #> 10 2018-06-04 14:39 IC 2313 IC 8000240 Mainz Hbf Hamburg-Altona 5a/b 124 | #> 11 2018-06-04 14:47 IC 2012 IC 8000240 Mainz Hbf Oberstdorf 2a/b 125 | #> 12 2018-06-04 15:15 ICE 1650 ICE 8000240 Mainz Hbf Dresden Hbf 2a/b 126 | #> 13 2018-06-04 15:18 EC 8 EC 8000240 Mainz Hbf Zürich HB 3a/b 127 | #> 14 2018-06-04 15:39 IC 2025 IC 8000240 Mainz Hbf Hamburg-Altona 4a/b 128 | #> 15 2018-06-04 16:16 ICE 710 ICE 8000240 Mainz Hbf Stuttgart Hbf 2a/b 129 | #> 16 2018-06-04 16:18 IC 2022 IC 8000240 Mainz Hbf Frankfurt(Main)Hbf 3a/b 130 | #> 17 2018-06-04 16:36 ICE 1655 ICE 8000240 Mainz Hbf Wiesbaden Hbf 4a/b 131 | #> 18 2018-06-04 16:39 IC 2217 IC 8000240 Mainz Hbf Hamburg-Altona 5a/b 132 | #> 19 2018-06-04 16:46 IC 118 IC 8000240 Mainz Hbf Innsbruck Hbf 1a/b 133 | #> 20 2018-06-04 17:10 IC 2011 IC 8000240 Mainz Hbf Düsseldorf Hbf 5a/b 134 | ``` 135 | 136 | For the particular trains in the arrival or departures board one can retrieve detailed information using `openbahn_journey()`. Therefor, the reference url of the desired train has to be looked up in the `JourneyDetailRef` data.frame: 137 | 138 | ``` r 139 | reference <- departures$content$DepartureBoard$Departure$JourneyDetailRef$ref[1] 140 | details <- openbahn_journeys(reference_url = reference) 141 | details 142 | #> < https://open-api.bahn.de/ > 143 | #> < bin/rest.exe/journeyDetail > 144 | #> 145 | #> routeIdx name id depDate depTime arrDate arrTime track 146 | #> 1 0 Passau Hbf 8000298 2018-06-04 07:17 2 147 | #> 2 1 Plattling 8000301 2018-06-04 07:50 2018-06-04 07:49 4 148 | #> 3 2 Straubing 8000095 2018-06-04 08:05 2018-06-04 08:04 5 149 | #> 4 3 Regensburg Hbf 8000309 2018-06-04 08:27 2018-06-04 08:25 5 150 | #> 5 4 Nürnberg Hbf 8000284 2018-06-04 09:30 2018-06-04 09:26 6 151 | #> 6 5 Würzburg Hbf 8000260 2018-06-04 10:24 2018-06-04 10:22 6 152 | #> 7 6 Hanau Hbf 8000150 2018-06-04 11:17 2018-06-04 11:15 102 153 | #> 8 7 Frankfurt(Main)Hbf 8000105 2018-06-04 11:42 2018-06-04 11:36 6 154 | #> 9 8 Frankfurt(M) Flughafen Fernbf 8070003 2018-06-04 11:58 2018-06-04 11:55 Fern 7 155 | #> 10 9 Mainz Hbf 8000240 2018-06-04 12:20 2018-06-04 12:18 3a/b 156 | #> 11 10 Koblenz Hbf 8000206 2018-06-04 13:13 2018-06-04 13:11 3 157 | #> 12 11 Bonn Hbf 8000044 2018-06-04 13:46 2018-06-04 13:44 2 158 | #> 13 12 Köln Hbf 8000207 2018-06-04 14:10 2018-06-04 14:05 4 159 | #> 14 13 Solingen Hbf 8000087 2018-06-04 14:31 2018-06-04 14:29 3 160 | #> 15 14 Wuppertal Hbf 8000266 2018-06-04 14:44 2018-06-04 14:42 2 161 | #> 16 15 Hagen Hbf 8000142 2018-06-04 15:02 2018-06-04 15:00 6/5 162 | #> 17 16 Dortmund Hbf 8000080 2018-06-04 15:25 2018-06-04 15:22 10 163 | #> 18 17 Münster(Westf)Hbf 8000263 2018-06-04 15:57 2018-06-04 15:55 12 164 | #> 19 18 Osnabrück Hbf 8000294 2018-06-04 16:23 2018-06-04 16:21 3 165 | #> 20 19 Bremen Hbf 8000050 2018-06-04 17:19 2018-06-04 17:16 10 166 | #> 21 20 Hamburg-Harburg 8000147 2018-06-04 18:04 2018-06-04 18:02 2 167 | #> 22 21 Hamburg Hbf 8002549 2018-06-04 18:17 2018-06-04 18:14 14 168 | #> 23 22 Hamburg Dammtor 8002548 2018-06-04 18:21 2018-06-04 18:20 3 169 | #> 24 23 Hamburg-Altona 8002553 2018-06-04 18:29 6 170 | ``` 171 | 172 | References 173 | ---------- 174 | 175 | For general information on the DB Timetable API visit (German). The data behind this API is licenced unter CC BY 4.0. 176 | 177 | Community Guidelines 178 | ==================== 179 | 180 | Please note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). By participating in this project you agree to abide by its terms. 181 | --------------------------------------------------------------------------------