An SVG-based tool to visualize public transport journeys retrieved from a HAFAS system

Time-Space Train Planner

An SVG-based tool to visualize public transport journeys retrieved from a HAFAS system, in order to see all possible connections and possibly find faster connections.

Example Diagram

Often, the HAFAS routing system will not show the fastest routes, because it deems the transfer times too short or because there are just too many possibilities. This tool will display all direct connections between a given set of stations and will help you find the fastest connection and any backup connections that might be good to know about. You can click on individual connections to show the shortest route to the destination from that connection (with a minimum transfer time of zero minutes).

TSTP is currently in an early alpha stage. I.e. it is unstable, does very little error handling and is not very user-friendly yet.

Running TSTP

The server-side part is written in Go, there is also a small client-side JavaScript part. You will have to run your own server to use this software.

TSTP relies on an adapted HAFAS API provided by hafas-client, more specifically, db-rest. You need to run your own instance of this API adapter separately from TSTP, or use a publicly available one (e.g. https://v5.db.transport.rest/).

In addition, you should run an aggressive HTTP cache in between TSTP and this API, because TSTP itself is stateless and will repeatedly issue identical requests for the same resources while gathering data. In deployments/nginx-cache.example.conf, you find an example of how to configure Nginx as an HTTP cache. Please note that this configuration will cache for a very long time. You will not be able to get updated live information for a particular request.

The steps to run TSTP itself are:

  1. Copy deployments/conf.example.env to deployments/conf.env and fill in the host name of your HTTP cache (API_CACHE_HOST) and, if your setup is not exactly mirroring db-rest, the path prefix (HAFAS_API_CACHE_PREFIX). If you run the cache locally (e.g. in another Docker container), you probably want to adjust the API_CACHE_SCHEME to http. The DB Open API and thus the respective environment variables are currently not used anymore.
  2. Copy res/conf.example.js to res/conf.js and fill in the complete URL to the /stations endpoint of your db-rest instance (preferably cached as well). Obviously, since this will be used by the browser for autocompletion, this URL needs to be accessible from the outside (i.e. no Docker hostname).
  3. Start TSTP using the docker-compose.yaml (add a port mapping if you need to) or, if you have installed all Go dependencies, without Docker using start.sh. The default port is 3000.
  4. You should now be able to access TSTP at your selected port under /tstp in your browser.
  5. If something goes wrong, consider looking into TSTP's stdout logs.
Comments
  • FeatureRequest nginx in docker-compose

    FeatureRequest nginx in docker-compose

    Hello nice project.

    I have a suggestion is it possible to add another docker compose file with a nginx container as cache so that the setup is easier? Or just add the nginx to the default compose file.

    Kind regards, Finn

  • Getting started

    Getting started

    Hi,

    thanks for your tool. It looks amazing and should be exactly what I need.

    I just wanted to try it out, but can't get it to run. I built the Docker Image and started the Container with Port Forwarding of the Port 3000. Unfortunately nothing is served on the / endpoint.

    So my questions are:

    • Do I have to set configuration variables? (I saw the deployments/conf.example.env. Can you explain the different entries in there?)
    • On which endpoint is the frontend application served?

    Thanks already in advance! ~ Moritz

  • Displayed time span too short

    Displayed time span too short

    Example: https://tespace.traines.eu/tstp?from=8011160&to=8000096&vias=8010101&vias=8000244&vias=0&vias=0&vias=0&vias=0&vias=0&vias=0&vias=0&vias=0&datetime=2022-11-07T23%3A48

    Screenshot_20221107-235158

    It shows many lines but no connection that ever arrives at the destination station. Btw: The Vias where added by the app. I just searched for Berlin - Stuttgart.

  • Properly handle upstream API errors

    Properly handle upstream API errors

    Currently just showing "Error 502: Failed requesting timetable data.".

    HTTP 502 Connection not found (too far in the past) e.g. /journeys?departure=2022-09-19T08%3A00%3A00.000%2B02%3A00&from=692415&to=895914

    {
    	"isHafasError": true,
    	"request": "{\"lang\":\"en\",\"svcReqL\":[{\"cfg\":{\"polyEnc\":\"GPA\",\"rtMode\":\"HYBRID\"},\"meth\":\"TripSearch\",\"req\":{\"getPasslist\":false,\"maxChg\":-1,\"minChgTime\":0,\"depLocL\":[{\"type\":\"S\",\"lid\":\"A=1@L=692415@\"}],\"viaLocL\":[],\"arrLocL\":[{\"type\":\"S\",\"lid\":\"A=1@L=895914@\"}],\"jnyFltrL\":[{\"type\":\"PROD\",\"mode\":\"INC\",\"value\":\"1023\"},{\"type\":\"META\",\"mode\":\"INC\",\"meta\":\"notBarrierfree\"}],\"gisFltrL\":[],\"getTariff\":false,\"ushrp\":true,\"getPT\":true,\"getIV\":false,\"getPolyline\":false,\"outDate\":\"20220919\",\"outTime\":\"080000\",\"outFrwd\":true,\"trfReq\":{\"jnyCl\":2,\"tvlrProf\":[{\"type\":\"E\",\"redtnCard\":null}],\"cType\":\"PK\"}}}],\"client\":{\"type\":\"AND\",\"id\":\"DB\",\"v\":21120000,\"name\":\"DB Navigator\"},\"ext\":\"DB.R21.12.a\",\"ver\":\"1.34\",\"auth\":{\"type\":\"AID\",\"aid\":\"n91dB8Z77MLdoR0K\"}}",
    	"url": "https://reiseauskunft.bahn.de/bin/mgate.exe?checksum=3cfb0da25d0e81e49aa943346f120265",
    	"statusCode": 404,
    	"isClient": true,
    	"code": "NOT_FOUND",
    	"message": "journeys search unsuccessful",
    	"hafasErrorCode": "H890",
    	"hafasErrorMessage": "HAFAS Kernel: No connection found",
    	"error": true,
    	"msg": "HAFAS error: journeys search unsuccessful"
    }
    

    HTTP 502 Date outside timetable period e.g. /journeys?departure=2022-12-17T06%3A30%3A00.000%2B01%3A00&from=8000244&to=8702383

    {
    	"isHafasError": true,
    	"request": "{\"lang\":\"en\",\"svcReqL\":[{\"cfg\":{\"polyEnc\":\"GPA\",\"rtMode\":\"HYBRID\"},\"meth\":\"TripSearch\",\"req\":{\"getPasslist\":false,\"maxChg\":-1,\"minChgTime\":0,\"depLocL\":[{\"type\":\"S\",\"lid\":\"A=1@L=8000244@\"}],\"viaLocL\":[],\"arrLocL\":[{\"type\":\"S\",\"lid\":\"A=1@L=8702383@\"}],\"jnyFltrL\":[{\"type\":\"PROD\",\"mode\":\"INC\",\"value\":\"1023\"},{\"type\":\"META\",\"mode\":\"INC\",\"meta\":\"notBarrierfree\"}],\"gisFltrL\":[],\"getTariff\":false,\"ushrp\":true,\"getPT\":true,\"getIV\":false,\"getPolyline\":false,\"outDate\":\"20221217\",\"outTime\":\"063000\",\"outFrwd\":true,\"trfReq\":{\"jnyCl\":2,\"tvlrProf\":[{\"type\":\"E\",\"redtnCard\":null}],\"cType\":\"PK\"}}}],\"client\":{\"type\":\"AND\",\"id\":\"DB\",\"v\":21120000,\"name\":\"DB Navigator\"},\"ext\":\"DB.R21.12.a\",\"ver\":\"1.34\",\"auth\":{\"type\":\"AID\",\"aid\":\"n91dB8Z77MLdoR0K\"}}",
    	"url": "https://reiseauskunft.bahn.de/bin/mgate.exe?checksum=8186ee987934e7f8a2f9cd5d207c97ae",
    	"statusCode": 400,
    	"isClient": true,
    	"code": "INVALID_REQUEST",
    	"message": "journeys search: invalid date/time",
    	"hafasErrorCode": "H9360",
    	"hafasErrorMessage": "HAFAS Kernel: Date outside of the timetable period.",
    	"error": true,
    	"msg": "HAFAS error: journeys search: invalid date/time"
    }
    
  • Improve automatic interchange station finding

    Improve automatic interchange station finding

    Currently, some interchange stations are retrieved from HAFAS journeys, the rest is up to the user. Interchange stations should be collected from additional sources, e.g.

    • Intermediate stops from journeys
    • Geographically relevant stations
    • Stations where different lines and modes call
    • Precalculation on offline timetable from GTFS download with negative transfer time Dijkstras etc to find relevant stations?
  • Better usage and display of HAFAS-recommended journeys

    Better usage and display of HAFAS-recommended journeys

    • Show warning if HAFAS finds journey not found by TSTP
    • Display HAFAS-recommended journeys only when selecting them (just as TSTP-recommended journeys). Currently, it's difficult to tell, which red line belongs to which journey.
  • More efficient API requests

    More efficient API requests

    To save bandwidth and processing at HAFAS. Idea: Only request local transport (buses, trams...) if there are other nearby stations selected. More intelligent time window, especially for longer journeys.

  • Better detection of redundant connections

    Better detection of redundant connections

    Some connections that might be reachable are marked as redundant. Some that are superfluous are not marked as redundant. Also relevant for foot connections, which are not shown at all, if deemed redundant (for performance reasons).

    Idea: Calculate Dijkstra for different transfer times (-15, -5, 0, 5, 15, etc)

Ltree Visualizer - A golang library to visualize postgres ltree type data using DOT language and Graphviz
Ltree Visualizer - A golang library to visualize postgres ltree type data using DOT language and Graphviz

Ltree Visualizer A golang library to visualize postgres ltree type data using DOT language and Graphviz What is Ltree? Ltree is a data type which is u

Jun 12, 2022
Plot 3D math equation z=f(x, y) with SVG format.
Plot 3D math equation z=f(x, y) with SVG format.

plot-function-svg Plot 3D math equation z=f(x, y) with SVG format. Some codes are referred from https://github.com/adonovan/gopl.io licensed under a C

Dec 30, 2021
Create beautiful system diagrams with Go
Create beautiful system diagrams with Go

Go-Diagrams Fast and easy application diagrams Go-Diagrams is a loose port of diagrams. Contents Features Usage Features Turn this: d, err := diagram.

Jan 7, 2023
Gfx - Golang file system extension library
Gfx - Golang file system extension library

gfx Golang文件操作扩展库,包含工作和生活中关于文件操作的各种有用的使用方法,包括 更友好的API 文件创建 文件删除 文件复制 一切皆可配置 文件名

Mar 10, 2022
Tool that can parse Go files into an abstract syntax tree and translate it to several programming languages.
Tool that can parse Go files into an abstract syntax tree and translate it to several programming languages.

GoDMT GoDMT, the one and only Go Data Model Translator. The goal of this project is to provide a tool that can parse Go files that include var, const,

Nov 28, 2022
gosivy - Another visualization tool for Go process metrics
gosivy - Another visualization tool for Go process metrics

gosivy Another visualization tool for Go process metrics. Gosivy tracks Go process's metrics and plot their evolution over time right into your termin

Nov 27, 2022
Interactive dependency graph visualization tool for golang
Interactive dependency graph visualization tool for golang

Interactive dependency graph visualization tool for golang using the awesome cytoscape graph visualizer.

Sep 1, 2022
Helm : a tool for managing Charts

Helm is a tool for managing Charts. Charts are packages of pre-configured Kubernetes resources.

Aug 25, 2022
Real-time Map displays real-time positions of public transport vehicles in Helsinki
Real-time Map displays real-time positions of public transport vehicles in Helsinki

Real-time Map Real-time Map displays real-time positions of public transport vehicles in Helsinki. It's a showcase for Proto.Actor - an ultra-fast dis

Nov 30, 2022
A simple API written in Go that creates badges in SVG format, based on the requested route.

A simple API written in Go that creates badges in SVG format, based on the requested route. Those graphics can be used to style README.md files, or to add tags to webpages.

Jul 2, 2021
depth is tool to retrieve and visualize Go source code dependency trees.

depth is tool to retrieve and visualize Go source code dependency trees. Install Download the appropriate binary for your platform from the Rele

Dec 30, 2022
Tool to visualize the graph of embedded structs in Go projects
Tool to visualize the graph of embedded structs in Go projects

Visualize a hierarchy of embedded Go structs This tool scans a directory of Go source code files to create a visualization of struct embedding in the

Nov 27, 2022
A command-line tool to visualize a JWT token's content, written in Go

jat A command-line tool to visualize a JWT token's content, written in Go. Usage jat <some-jwt> Install Navigate to the Releases page; Download the co

Jan 6, 2022
Goimportcycle - a tool to visualize Go imports resolved to the file level
Goimportcycle - a tool to visualize Go imports resolved to the file level

Go Import Cycle goimportcycle is a tool to visualize Go imports resolved to the

Dec 8, 2022
Sixmap - Tool to visualize the SIX (Seattle Internet Exchange) route server coverage

Mapping the SIX route server This program generates an IPv4 map. In particular,

Nov 9, 2022
Parse and demux MPEG Transport Streams (.ts) natively in GO

This is a Golang library to natively parse and demux MPEG Transport Streams (ts) in GO. WARNING: this library is not yet production ready. Use at your

Jan 9, 2023
UDP Transport: compress, encrypt and send any data reliably over unreliable UDP connections

udpt UDP Transport Compresses, encrypts and transfers data between a sender and receiver using UDP protocol. Features and Design Aims: Avoid the overh

Nov 5, 2022
NATS HTTP Round Tripper - This is a Golang http.RoundTripper that uses NATS as a transport.

This is a Golang http.RoundTripper that uses NATS as a transport. Included is a http.RoundTripper for clients, a server that uses normal HTTP Handlers and any existing http handler mux and a Caddy Server transport.

Dec 6, 2022
OCI transport plugin for apt-get (i.e., apt-get over ghcr.io)

apt-transport-oci: OCI transport plugin for apt-get (i.e., apt-get over ghcr.io) apt-transport-oci is an apt-get plugin to support distributing *.deb

Nov 1, 2022
Transport to allow go-libp2p applications to natively use i2p for communication

I2P Transport for go-libp2p This library can be used to build go-libp2p applications using the i2p network. Look at transport_test.go for example usag

Sep 15, 2022