├── .devcontainer └── devcontainer.json ├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ └── erweiterung.md └── workflows │ ├── add_path_suggestions.yml │ ├── check_content.yml │ ├── create_map.yml │ ├── eclint.yml │ ├── json_validate.yml │ └── project_coordinates.yml ├── .gitignore ├── .gitpod.Dockerfile ├── .gitpod.yml ├── .vscode └── tasks.json ├── CONTRIBUTING.md ├── Capacity.json ├── DelayModel.json ├── LICENSES-DATA.md ├── Network.json ├── Path.json ├── README.md ├── Station.json ├── TaskModel.json ├── Train.json ├── TrainEquipment.json ├── map_background.svg └── schemas ├── Capacity.json ├── DelayModel.json ├── Path.json ├── Station.json ├── TaskModel.json └── Train.json /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.241.1/containers/python-3 3 | { 4 | "name": "TrainCompany-Tools", 5 | "image": "ghcr.io/c1710/traincompany-tools:latest", 6 | 7 | // Configure tool-specific properties. 8 | "customizations": { 9 | // Configure properties specific to VS Code. 10 | "vscode": { 11 | // Set *default* container specific settings.json values on container create. 12 | "settings": { 13 | "python.defaultInterpreterPath": "/usr/local/bin/python", 14 | "python.linting.enabled": true, 15 | "python.linting.pylintEnabled": true, 16 | "python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8", 17 | "python.formatting.blackPath": "/usr/local/py-utils/bin/black", 18 | "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", 19 | "python.linting.banditPath": "/usr/local/py-utils/bin/bandit", 20 | "python.linting.flake8Path": "/usr/local/py-utils/bin/flake8", 21 | "python.linting.mypyPath": "/usr/local/py-utils/bin/mypy", 22 | "python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle", 23 | "python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle", 24 | "python.linting.pylintPath": "/usr/local/py-utils/bin/pylint" 25 | }, 26 | 27 | // Add the IDs of extensions you want installed when the container is created. 28 | "extensions": [ 29 | "ms-python.python", 30 | "ms-python.vscode-pylance", 31 | "mechatroner.rainbow-csv", 32 | "pinage404.git-extension-pack" 33 | ] 34 | } 35 | }, 36 | "containerEnv": { 37 | "TRAINCOMPANY_DATA": "${containerWorkspaceFolder}" 38 | } 39 | 40 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 41 | // "forwardPorts": [], 42 | 43 | // Use 'postCreateCommand' to run commands after the container is created. 44 | // "postCreateCommand": "pip3 install --user -r requirements.txt", 45 | 46 | // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. 47 | } 48 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = false 6 | charset = utf-8 7 | indent_style = tab 8 | tab_width = 4 9 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/erweiterung.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Erweiterung 3 | about: Erweiterung um eine Strecke/Zug/Task 4 | title: '' 5 | labels: extension 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Was wird hinzugefügt? 11 | 12 | ## Art der Erweiterung 13 | [ ] Strecke 14 | [ ] Zug 15 | [ ] Aufgabe 16 | [ ] Ladungsart 17 | [ ] Verspätung 18 | 19 | ## Weitere Details 20 | -------------------------------------------------------------------------------- /.github/workflows/add_path_suggestions.yml: -------------------------------------------------------------------------------- 1 | name: Add pathSuggestions 2 | 3 | on: 4 | push: 5 | paths: 6 | - "TaskModel.json" 7 | workflow_dispatch: 8 | 9 | jobs: 10 | add_suggestions: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: actions/checkout@v3 15 | with: 16 | repository: 'C1710/TrainCompany-tools' 17 | path: 'tools' 18 | submodules: true 19 | - uses: actions/setup-python@v4 20 | with: 21 | python-version: '3.9' 22 | - name: Install requirements 23 | run: python -m pip install -r tools/requirements.txt 24 | - name: Project coordinates 25 | run: python tools/update_path_suggestions.py --auto-service --tc-dir=. 26 | - name: Commit and Push 27 | # https://stackoverflow.com/a/58393457 28 | run: | 29 | git config --global user.name 'TrainCompany' 30 | git config --global user.email 'train-company@c1710.de' 31 | git add Station.json && git commit -m "Added pathSuggestions" && git push 32 | continue-on-error: true 33 | -------------------------------------------------------------------------------- /.github/workflows/check_content.yml: -------------------------------------------------------------------------------- 1 | name: Check JSON content 2 | 3 | on: 4 | push: 5 | paths: 6 | - "Station.json" 7 | - "Path.json" 8 | - "Train.json" 9 | - "TrainEquipment.json" 10 | - "TaskModel.json" 11 | pull_request: 12 | paths: 13 | - "Station.json" 14 | - "Path.json" 15 | - "Train.json" 16 | - "TrainEquipment.json" 17 | - "TaskModel.json" 18 | workflow_dispatch: 19 | 20 | jobs: 21 | check: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v3 25 | - uses: actions/checkout@v3 26 | with: 27 | repository: 'C1710/TrainCompany-tools' 28 | path: 'tools' 29 | submodules: true 30 | - uses: actions/setup-python@v4 31 | with: 32 | python-version: '3.9' 33 | - name: Install requirements 34 | run: python -m pip install -r tools/requirements.txt 35 | - name: Check contents 36 | run: python tools/validate_files.py --tc_directory=. --data_directory=./tools/data --limit 3350 37 | -------------------------------------------------------------------------------- /.github/workflows/create_map.yml: -------------------------------------------------------------------------------- 1 | name: Render Map 2 | 3 | on: 4 | push: 5 | paths: 6 | - "Station.json" 7 | - "Path.json" 8 | pull_request: 9 | paths: 10 | - "Station.json" 11 | - "Path.json" 12 | workflow_dispatch: 13 | 14 | jobs: 15 | render: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v3 19 | - uses: actions/checkout@v3 20 | with: 21 | repository: 'C1710/TrainCompany-tools' 22 | path: 'tools' 23 | submodules: true 24 | - uses: actions/setup-python@v4 25 | with: 26 | python-version: '3.9' 27 | - name: Install matplotlib 28 | run: python -m pip install -r tools/requirements.txt 29 | - name: Render map 30 | run: python tools/plot.py 31 | - uses: actions/upload-artifact@v3 32 | with: 33 | name: map 34 | path: map_plot.svg 35 | retention-days: 2 36 | # comment: 37 | # if: github.event_name == 'pull_request' 38 | # runs-on: ubuntu-latest 39 | # steps: 40 | # - uses: actions/download-artifact@v3 41 | # with: 42 | # name: map 43 | # path: map.svg 44 | # - uses: actions/github-script@v6 45 | # with: 46 | # script: | 47 | # github.rest.issues.createComment({ 48 | # issue_number: context.issue.number, 49 | # owner: context.repo.owner, 50 | # repo: context.repo.repo, 51 | # body: 'Map: ![Map]()' 52 | # }) -------------------------------------------------------------------------------- /.github/workflows/eclint.yml: -------------------------------------------------------------------------------- 1 | name: JSONLint 2 | 3 | on: 4 | push: 5 | branches-ignore: [main] 6 | paths: 7 | - "**.json" 8 | pull_request: 9 | branches: [main] 10 | paths: 11 | - "**.json" 12 | 13 | jobs: 14 | build: 15 | name: Lint Code Base 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - name: Checkout Code 20 | uses: actions/checkout@v2 21 | with: 22 | # Full git history is needed to get a proper list of changed files within `super-linter` 23 | fetch-depth: 0 24 | 25 | - name: Lint Code Base 26 | uses: github/super-linter/slim@v4 27 | env: 28 | VALIDATE_ALL_CODEBASE: false 29 | # It sants tabs as indentation, which YAML does not allow 30 | VALIDATE_JSON: true 31 | DEFAULT_BRANCH: main 32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/json_validate.yml: -------------------------------------------------------------------------------- 1 | name: JSON-Validate 2 | 3 | on: 4 | push: 5 | paths: 6 | - "*.json" 7 | pull_request: 8 | paths: 9 | - "*.json" 10 | workflow_dispatch: 11 | 12 | jobs: 13 | validate_JSON: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: Validate Capacity.json 18 | uses: docker://orrosenblatt/validate-json-action:latest 19 | env: 20 | INPUT_SCHEMA: schemas/Capacity.json 21 | INPUT_JSONS: Capacity.json 22 | 23 | - name: Validate DelayModel.json 24 | uses: docker://orrosenblatt/validate-json-action:latest 25 | env: 26 | INPUT_SCHEMA: schemas/DelayModel.json 27 | INPUT_JSONS: DelayModel.json 28 | 29 | - name: Validate Path.json 30 | uses: docker://orrosenblatt/validate-json-action:latest 31 | env: 32 | INPUT_SCHEMA: schemas/Path.json 33 | INPUT_JSONS: Path.json 34 | 35 | - name: Validate Station.json 36 | uses: docker://orrosenblatt/validate-json-action:latest 37 | env: 38 | INPUT_SCHEMA: schemas/Station.json 39 | INPUT_JSONS: Station.json 40 | 41 | - name: Validate TaskModel.json 42 | uses: docker://orrosenblatt/validate-json-action:latest 43 | env: 44 | INPUT_SCHEMA: schemas/TaskModel.json 45 | INPUT_JSONS: TaskModel.json 46 | 47 | - name: Validate Train.json 48 | uses: docker://orrosenblatt/validate-json-action:latest 49 | env: 50 | INPUT_SCHEMA: schemas/Train.json 51 | INPUT_JSONS: Train.json -------------------------------------------------------------------------------- /.github/workflows/project_coordinates.yml: -------------------------------------------------------------------------------- 1 | name: Project coordinates 2 | 3 | on: 4 | push: 5 | paths: 6 | - "Station.json" 7 | workflow_dispatch: 8 | 9 | jobs: 10 | transform: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: actions/checkout@v3 15 | with: 16 | repository: 'C1710/TrainCompany-tools' 17 | path: 'tools' 18 | submodules: true 19 | - uses: actions/setup-python@v4 20 | with: 21 | python-version: '3.9' 22 | - name: Install requirements 23 | run: python -m pip install -r tools/requirements.txt 24 | - name: Project coordinates 25 | run: python tools/project_coordinates.py --tc-dir=. --projection-version=3 26 | - name: Commit and Push 27 | # https://stackoverflow.com/a/58393457 28 | run: | 29 | git config --global user.name 'TrainCompany' 30 | git config --global user.email 'train-company@c1710.de' 31 | git add Station.json && git commit -m "Projected coordinates" && git push 32 | continue-on-error: true 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /tools 2 | /.idea/ 3 | *.svg 4 | *.csv 5 | !map_background.svg 6 | *.gpx 7 | -------------------------------------------------------------------------------- /.gitpod.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ghcr.io/c1710/traincompany-tools:latest 2 | ENV TRAINCOMPANY_DATA /workspace/TrainCompany-Data -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | image: 2 | file: .gitpod.Dockerfile 3 | vscode: 4 | extensions: 5 | - ms-python.python 6 | - mechatroner.rainbow-csv 7 | - pinage404.git-extension-pack 8 | - ms-azuretools.vscode-docker 9 | - GitHub.vscode-pull-request-github 10 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "Trassenfinder importieren", 8 | "type": "shell", 9 | "command": "import_trassenfinder.py", 10 | "group": "build", 11 | "presentation": { 12 | "reveal": "always", 13 | "panel": "shared" 14 | }, 15 | "args": ["--annotate", "${file}"] 16 | }, 17 | { 18 | "label": "Haltestellen-Liste exportieren", 19 | "type": "shell", 20 | "command": "export_station_list.py", 21 | "presentation": { 22 | "reveal": "silent", 23 | "panel": "new" 24 | }, 25 | "args": ["${input:country}"] 26 | }, 27 | { 28 | "label": "Annotationen entfernen", 29 | "type": "shell", 30 | "presentation": { 31 | "reveal": "silent", 32 | "panel": "new" 33 | }, 34 | "command": "cleanup.py" 35 | }, 36 | { 37 | "label": "Map rendern", 38 | "type": "shell", 39 | "presentation": { 40 | "reveal": "silent", 41 | "panel": "new" 42 | }, 43 | "command": "plot.py" 44 | } 45 | ], 46 | "inputs": [ 47 | { 48 | "id": "country", 49 | "description": "Land (Kürzel):", 50 | "type": "pickString", 51 | "options": [ 52 | "AT", 53 | "BA", 54 | "BE", 55 | "BG", 56 | "CH", 57 | "CZ", 58 | "DK", 59 | "ES", 60 | "FI", 61 | "FR", 62 | "GB", 63 | "GR", 64 | "HU", 65 | "IT", 66 | "LU", 67 | "NL", 68 | "NO", 69 | "PL", 70 | "PT", 71 | "RO", 72 | "RS", 73 | "RU", 74 | "SE", 75 | "SI", 76 | "SK", 77 | "TR" 78 | ] 79 | } 80 | ] 81 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Wie neue Daten hinzugefügt werden können 2 | ## Erweiterungen vorschlagen 3 | Wenn du eine bestimmte Erweiterung haben oder selbst machen möchtest, ist es gut, wenn du zunächst ein Issue im Haupt-Repository (https://github.com/marhei/TrainCompany-Data) anlegst: 4 | ```Issues > New issue > Erweiterung/Get started``` 5 | Es muss dabei nicht zwingend alles ausgefüllt werden, es dient in erster Linie dazu um mehrere gleichzeitige Erweiterungen zu verhindern. 6 | Willst du die Erweiterung selbst machen, bzw. fängst damit an, kannst du das als Kommentar hinzufügen, damit niemand anderes auch damit anfängt. 7 | ## Vorbereitungen 8 | Wenn du eine Erweiterung selbst machen möchtest, solltest du einen Github-Fork erstellen, auf dem du dann die Änderungen/Ergänzungen machen kannst.. 9 | Das geht ganz einfach über den "Fork"-Button oben rechts und muss (und kann) nur ein Mal gemacht werden. 10 | ## Das allgemeine Vorgehen 11 | 1. Zunächst einmal solltest du deinen Datenstand mit dem Haupt-Repository abgleichen, was z.B. über die "Sync fork"-Option von GitHub geht oder die Pull-Funktion in einem Code-Editor o.Ä. 12 | 2. Falls möglich, solltest du einen Branch erstellen und darauf arbeiten. Das kannst du bspw. auf GitHub machen, wenn du eine Datei bearbeitest. In Visual Studio Code (oder github.dev oder Gitpod) geht das, indem du unten links auf den aktuellen Branch-Namen klickst (der zunächst `main` heißen wird) und dann oben "create new branch" auswählst. 13 | 3. Nun kannst du die Dateien bearbeiten, auf Github direkt, mit github.dev, mit Gitpod, lokal, usw. 14 | 4. Bist du soweit, musst du ggf. einen Git-Commit mit den geänderten Dateien erstellen (und benennen) und den in deinen Fork `Push`en. 15 | 5. Du kannst dann eine Pull Request erstellen mit den Änderungen, die du hinzufügen willst. Das geht von deinem Fork aus mit `Contribute > Open pull request` oder unter https://github.com/marhei/TrainCompany-Data/pulls > `New pull request` - wenn der Commit/Push gerade erst erstellt worden ist, wird es dir ggf. auch direkt angeboten. 16 | In der Ansicht kannst du dann Titel und Text bearbeiten (geht auch noch nachträglich) und (falls du noch nicht fertig bist) eine noch nicht fertigen/Draft-Pull Request erstellen 17 | 6. Ist die Pull-Request (PR) erstellt, laufen ein paar Tests und es kann dann darüber diskutiert werden usw., ist alles in Ordnung, kann die Pull Request gemergt werden und die Daten landen dann im Spiel. 18 | 19 | 20 | ## Tools zur Erstellung neuer Strecken 21 | Es gibt mehrere Tools, mit denen neue Strecken hinzugefügt werden können, die jeweils verschieden Vor- und Nachteile haben. 22 | 23 | Mit diesen Tools ist es vor allem leichter, neue Streckenerweiterungen und z.T. auch Ausschreibungen zu erstellen. 24 | ### tcroute (von @f2k1de) 25 | - Erlaubt es, innerdeutsche Strecken aus https://trassenfinder.de zu importieren 26 | - Web-basiert und zu finden auf https://tcroute.f2k1.de 27 | 28 | ### TrainCompany-Tools (von @c1710) 29 | - Mehrere Tools, die es erlauben, neue Stationen, Strecken, Aufgaben zu erstellen - in Deutschland auch mit trassenfinder.de-Exporten, international teilweise manuell 30 | - Kommandozeilen-Tools in Python entwickelt 31 | - Direkt verfügbar in GitPod (einer Online-basierten Entwicklungsumgebung basierend auf Visual Studio Code): 32 | https://gitpod.io/#https://github.com//TrainCompany-Data (Registrierung/Anmeldung erforderlich; beschränkt auf 30 Stunden Nutzung im Monat) 33 | - https://github.com/c1710/TrainCompany-tools -------------------------------------------------------------------------------- /Capacity.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/marhei/TrainCompany-Data/main/schemas/Capacity.json", 3 | "data": [ 4 | { 5 | "idString": "passengers", 6 | "name": "Fahrgäste", 7 | "needsPlatform": true, 8 | "unitMass": 0.07, 9 | "emoji": "👥", 10 | "exchangeFactor": 1 11 | }, 12 | { 13 | "idString": "bistroseats", 14 | "name": "Speiseplätze", 15 | "needsPlatform": true, 16 | "unitMass": 0.07, 17 | "emoji": "🍽", 18 | "exchangeFactor": 0.05 19 | }, 20 | { 21 | "idString": "pullman", 22 | "name": "Salonwagen", 23 | "needsPlatform": true, 24 | "unitMass": 0.07, 25 | "emoji": "🎩", 26 | "exchangeFactor": 0.05 27 | }, 28 | { 29 | "idString": "beds", 30 | "name": "Betten", 31 | "needsPlatform": true, 32 | "unitMass": 0.07, 33 | "emoji": "🛌", 34 | "exchangeFactor": 0.35 35 | }, 36 | { 37 | "idString": "wood", 38 | "name": "Holz", 39 | "needsPlatform": false, 40 | "unit": "t", 41 | "unitMass": 1, 42 | "emoji": "🪵" 43 | }, 44 | { 45 | "idString": "oil", 46 | "name": "Öl", 47 | "needsPlatform": false, 48 | "unit": "t", 49 | "unitMass": 1, 50 | "emoji": "🛢" 51 | }, 52 | { 53 | "idString": "coal", 54 | "name": "Kohle", 55 | "needsPlatform": false, 56 | "unit": "t", 57 | "unitMass": 1, 58 | "emoji": "🪨" 59 | }, 60 | { 61 | "idString": "cars", 62 | "name": "Autos", 63 | "needsPlatform": false, 64 | "unitMass": 1.7, 65 | "emoji": "🚙", 66 | "exchangeFactor": 0.2 67 | }, 68 | { 69 | "idString": "containers", 70 | "name": "Container", 71 | "needsPlatform": false, 72 | "unitMass": 35, 73 | "emoji": "🚛" 74 | }, 75 | { 76 | "idString": "castor", 77 | "name": "Castor", 78 | "needsPlatform": false, 79 | "unitMass": 135, 80 | "emoji": "☢️" 81 | } 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /DelayModel.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/marhei/TrainCompany-Data/main/schemas/DelayModel.json", 3 | "data": [ 4 | { 5 | "type": 0, 6 | "objects" : [ 7 | { 8 | "name": "Der Zug ist aufgrund eines Antriebsschaden stehen geblieben.", 9 | "delay": 1000 10 | }, 11 | { 12 | "name": "Aufgrund einer Bremsstörung musste eine Druckluftbremse augeschaltet werden.", 13 | "delay": 1000 14 | }, 15 | { 16 | "name": "Es fand eine Zugtrennung auf freier Strecke statt.", 17 | "delay": 1200 18 | }, 19 | { 20 | "name": "Die Vmax ist auf Grund einer technischen Störung reduziert.", 21 | "delay": 400 22 | }, 23 | { 24 | "name": "Die Klimaanlage im Führerstand ist ausgefallen, der Lokführer hat eine Drehfahrt beantragt.", 25 | "delay": 1200 26 | }, 27 | { 28 | "name": "Am Triebfahrzeug musste ein Batteriereset durchgeführt werden.", 29 | "delay": 1000 30 | }, 31 | { 32 | "name": "Der letzte Vorbereitungsdienst wurde am Tfz vor über 36 Stunden durchgeführt. Der Lokführer musste diesen nachholen.", 33 | "delay": 900 34 | }, 35 | { 36 | "name": "Die Brandmeldeanlage hat angeschlagen. Es musste nach dem Grund geschaut werden", 37 | "delay": 400 38 | } 39 | ] 40 | }, 41 | { 42 | "type": 1, 43 | "objects" : [ 44 | { 45 | "name": "Der Lokführer hat einen Magendarminfekt und musste einen Toilettenaufenthalt einlegen.", 46 | "delay": 300 47 | }, 48 | { 49 | "name": "Der Lokführer hat eine PZB-Zwangsbremsung an einem Hauptsignal erhalten. Weiterfahrt nach Befehlsübermittlung.", 50 | "delay": 300 51 | }, 52 | { 53 | "name": "Das EBA hat bei einer Stichprobenkontrolle fehlende Streckenkunde beim Lokführer festgestellt.", 54 | "delay": 1000 55 | }, 56 | { 57 | "name": "Der Zugbegleiter ist beim Abfertigen am Bahnsteig stehen geblieben und musste mit dem Taxi nachgeschickt werden.", 58 | "delay": 1000 59 | }, 60 | { 61 | "name": "Der Lokführer ist über seine Arbeitszeit gekommen und musste abgelöst werden.", 62 | "delay": 1000 63 | }, 64 | { 65 | "name": "Wegen Personalmangel konnte nicht rechtzeitig ein Ablöse-Lokführer auftrieben werden.", 66 | "delay": 1000 67 | }, 68 | { 69 | "name": "Aufgrund einer Signalverfehlung musste der Lokführer abgelöst werden.", 70 | "delay": 1000 71 | }, 72 | { 73 | "name": "Der Fahrdienstleiter hat Kaffee über das Stellpult geschüttet, deswegen musste die Weiterfahrt auf Sicht erfolgen.", 74 | "delay": 1000 75 | }, 76 | { 77 | "name": "Es kam zu einer Fehlleitung und der Lokführer musste den Zug zurücksetzen.", 78 | "delay": 1000 79 | }, 80 | { 81 | "name": "Der Zug musste eine Umleitung fahren, da nicht genügend arbeitsfähiges Personal für das NBÜ-Ersatzkonzept zur Verfügung stand.", 82 | "delay": 1000 83 | }, 84 | { 85 | "name": "Der ausgeliehene Lokführer ist mit der PZB nicht vertraut und hat diese deaktiviert.", 86 | "delay": 1000 87 | }, 88 | { 89 | "name": "Der Lokführer hatte sich bei einem Toilettengang während eines Betriebshaltes aus dem Führerstand ausgeschlossen und musste das Schloss mit einem Schotterstein aufbrechen.", 90 | "delay": 800 91 | } 92 | ] 93 | }, 94 | { 95 | "type": 2, 96 | "capacity": "passengers", 97 | "delay": 900, 98 | "objects" : [ 99 | { 100 | "name": "Ein Fahrgast hat auf der Toilette geraucht.", 101 | "delay": 300 102 | }, 103 | { 104 | "name": "Ein Fahrgast hat sich mit seinem 9 €-Ticket geweigert die 1. Klasse zu räumen." 105 | }, 106 | { 107 | "name": "Ein Fahrgast hat im Ruheabteil mit seinem Handy telefoniert und einen Aufstand gemacht." 108 | }, 109 | { 110 | "name": "Ein Fahrgast hat einen Aufstand angezettelt, weil ihm sein bahn.comfort-Platz nicht freigemacht wurde." 111 | }, 112 | { 113 | "name": "Die Klimaanlage ist in einem Wagen ausgefallen und das Zugpersonal musste an alle Fahrgäste kostenloses Eis verteilen." 114 | }, 115 | { 116 | "name": "Es wurden von der bayrischen Polizei eine verdachtsunabhängige Kontrolle durchgeführt." 117 | }, 118 | { 119 | "name": "Ein nichtzugeordnetes Gepäckstück musste gesprengt werden." 120 | }, 121 | { 122 | "name": "Ein Politiker hat sich in der Toilette eingeschlossen um der Kontrolle zu entgehen." 123 | }, 124 | { 125 | "name": "Ein Fahrgast hat sich mit seiner Luftmatratze in einem Abteil eingeschlossen." 126 | }, 127 | { 128 | "name": "Ein Fahrgast wurde beim Klauen von Zuglaufschildern erwischt und der Polizei übergeben." 129 | }, 130 | { 131 | "name": "Ein Fahrgast ist einen Zugbegleiter angegangen, nachdem der Seifenspender in der Toilette angeblich schief auf seine Hose gespritzt hatte. Seine BahnCard 100 wurde sichergestellt." 132 | }, 133 | { 134 | "name": "Die Notbremse wurde gezogen, weil ein Fahrgast aussteigen wollte.", 135 | "delay": 600 136 | }, 137 | { 138 | "name": "Ein Fahrgast hat die Notbremse mit einem Haltegriff verwechselt.", 139 | "delay": 600 140 | }, 141 | { 142 | "name": "Alle Toiletten im Zug sind unbenutzbar, Betriebshalt am nächsten McDonald's um die Fahrgäste pinkeln zu lassen.", 143 | "delay": 800 144 | }, 145 | { 146 | "name": "Ein Fahrgast ist während eines Betriebshaltes ausgestiegen und hat in eine Hecke gepinkelt. Der Zug ist währenddessen losgefahren." 147 | }, 148 | { 149 | "name": "Ein prominenter Fahrgast wollte nicht einsehen, dass die Beförderungsbedingungen für alle Fahrgäste gelten, und musste nach kurzer Diskussion mit einen Zugbegleiter am nächsten Bahnhof von der Bundespolizei aus dem Zug geholt werden." 150 | }, 151 | { 152 | "name": "In einen Wagen ist die Heizung ausgefallen." 153 | } 154 | ] 155 | }, 156 | { 157 | "type": 2, 158 | "capacity": "bistroseats", 159 | "objects": [ 160 | { 161 | "name": "Die Kaffeemaschine im Speisewagen ist ausgefallen.", 162 | "delay": 300 163 | }, 164 | { 165 | "name": "Im Speisewagen ist das Bier ausgegangen! Es wurde am nächsten Bahnsteig ein Betriebshalt eingelegt und das Zugpersonal hat im lokalen Getränkeladen ein neues Fass gekauft.", 166 | "delay": 600 167 | }, 168 | { 169 | "name": "Nachdem der Zugführer per Durchsage kostenloses Eis im Speisewagen versprochen hatte kam es zu Tumulten.", 170 | "delay": 600 171 | }, 172 | { 173 | "name": "Ein Fahrgast hat angefangen zu randalieren, weil im Speisewagen die Currywurst schon wieder leer war.", 174 | "delay": 600 175 | }, 176 | { 177 | "name": "Es gibt Tumulte im Speisewagen, da es nur noch alkoholische Getränke und das Wasser von Gin Tonic gibt.", 178 | "delay": 300 179 | } 180 | ] 181 | }, 182 | { 183 | "type": 2, 184 | "capacity": "beds", 185 | "objects": [ 186 | { 187 | "name": "Bei einer Zwangsbremsung sind 3 Fahrgäste aus ihren Betten gefallen und mussten verarztet werden.", 188 | "delay": 600 189 | }, 190 | { 191 | "name": "Bei einem Betriebshalt wurden mehrere Schlafabteile aufgebrochen und die Wertsachen entnommen.", 192 | "delay": 600 193 | }, 194 | { 195 | "name": "Während der Fahrt wurden vom Personal ungewöhnliche Geräusche wahrgenommen, deren Ursache sich bei einer Kontrolle als laut schnachenden Fahrgast feststellte.", 196 | "delay": 600 197 | } 198 | ] 199 | }, 200 | { 201 | "type": 2, 202 | "capacity": "wood", 203 | "objects" : [ 204 | { 205 | "name": "Es ist Holz vom Wagen gerutscht.", 206 | "delay": 1000 207 | }, 208 | { 209 | "name": "Ein mit Holz beladener Wagen hat angefangen zu brennen und musste gelöscht werden.", 210 | "delay": 2000 211 | } 212 | ] 213 | }, 214 | { 215 | "type": 2, 216 | "capacity": "cars", 217 | "objects" : [ 218 | { 219 | "name": "Während eines kurzen Betriebshalt wurden einige Autos aufgebrochen.", 220 | "delay": 1000 221 | }, 222 | { 223 | "name": "In einem Auto wurde ein blinder Passagier entdeckt, der von der Polizei abgeholt wurde.", 224 | "delay": 1000 225 | } 226 | ] 227 | }, 228 | { 229 | "type": 2, 230 | "capacity": "containers", 231 | "objects" : [ 232 | { 233 | "name": "Während eines kurzen Betriebshalt wurden einige Container aufgebrochen und DHL-Pakete entnommen.", 234 | "delay": 1000 235 | }, 236 | { 237 | "name": "Aus einem Container wurden während eines Betriebshalts komische Geräusche wahrgenommen. Nach einer Überprüfung wurde aber nur Druckerzubehör gefunden.", 238 | "delay": 1000 239 | } 240 | ] 241 | }, 242 | { 243 | "type": 2, 244 | "capacity": "castor", 245 | "objects" : [ 246 | { 247 | "name": "Demonstranten haben sich vor dem Zug an die Gleise gekettet.", 248 | "delay": 1000 249 | }, 250 | { 251 | "name": "An einem Wagen wurde eine erhöhte Strahlenbelastung festgestellt. Der Lokführer konnte das Problem mit Gaffa Tape lösen.", 252 | "delay": 1000 253 | } 254 | ] 255 | }, 256 | { 257 | "type": 2, 258 | "capacity": "oil", 259 | "objects" : [ 260 | { 261 | "name": "An einen Kesselwagen ist ein Leck gefunden worden, das mit Gaffa Tape abgedichtet werden konnte.", 262 | "delay": 1000 263 | }, 264 | { 265 | "name": "Kraftstoffdiebe haben während eines Betriebshaltes versucht, Kraftstoff aus einen Kesselwagen zu entnehmen, konnten allerdings vorher vertrieben werden.", 266 | "delay": 1000 267 | } 268 | ] 269 | }, 270 | { 271 | "type": 2, 272 | "capacity": "coal", 273 | "objects" : [ 274 | { 275 | "name": "Demonstranten haben sich vor dem Zug an die Gleise gekettet.", 276 | "delay": 1000 277 | }, 278 | { 279 | "name": "Es ist Kohle aus einigen Wagen gefallen, die wieder aufgeladen werden musste.", 280 | "delay": 1000 281 | } 282 | ] 283 | }, 284 | { 285 | "type": 2, 286 | "capacity": "pullman", 287 | "objects" : [ 288 | { 289 | "name": "Ein Fahrgast wollte trotz Rauchverbots rauchen.", 290 | "delay": 1000 291 | }, 292 | { 293 | "name": "Eine angeregte Diskussion zwischen mehreren Fahrgästen ist in einen Streit eskaliert, der erst mit einigen Anstrengungen beruhigt werden konnte.", 294 | "delay": 1000 295 | } 296 | ] 297 | } 298 | ] 299 | } 300 | -------------------------------------------------------------------------------- /LICENSES-DATA.md: -------------------------------------------------------------------------------- 1 | Es wurden Daten aus den folgenden Datensätzen verwendet: 2 | 3 | ## OpenStreetMap & OpenRailwayMap 4 | Streckengeschwindigkeiten/-informationen, Bahnhöfe (insbesondere mit O123456-Codes) und dazugehörige Informationen stammen u.a. aus [OpenStreetMap](openstreetmap.org) und [OpenRailwayMap](openrailwaymap.org). 5 | Lizenz: https://www.openstreetmap.org/copyright 6 | (c) OpenStreetMap contributors/Mitwirkende 7 | 8 | ## Trainline (international) 9 | - https://github.com/trainline-eu/stations 10 | - Lizenz: Open Database License - https://github.com/trainline-eu/stations/blob/master/LICENCE.txt 11 | 12 | ## DE 13 | License: 14 | > © 2016 Deutsche Bahn AG. Dieser Datensatz wird bereitgestellt unter der Lizenz Creative Commons Attribution 4.0 International (CC BY 4.0). Source: 15 | 16 | `bahnhoefe.csv`: 17 | - https://data.deutschebahn.com/dataset/data-stationsdaten.html 18 | `strecken.csv`: 19 | - https://data.deutschebahn.com/dataset/geo-strecke.html 20 | `betriebsstellen.csv`: 21 | - https://data.deutschebahn.com/dataset/geo-betriebsstelle.html 22 | `bahnsteige.csv`: 23 | - https://data.deutschebahn.com/dataset/data-bahnsteig.html 24 | `betriebsstellen_verzeichnis.csv`: 25 | - https://data.deutschebahn.com/dataset/data-betriebsstellen.html 26 | 27 | ## CH 28 | `sbb_didok.csv`: 29 | - License: https://opendata.swiss/de/dataset?q=haltestelle&organization=bundesamt-fur-verkehr-bav&res_rights=NonCommercialAllowed-CommercialAllowed-ReferenceRequired 30 | - Source: https://data.sbb.ch/explore/dataset/dienststellen-gemass-opentransportdataswiss/information/ 31 | 32 | `sbb_platforms.csv`: 33 | - License: https://data.sbb.ch/page/licence 34 | - Source: https://data.sbb.ch/explore/dataset/perron/information/ 35 | 36 | `sbb_bahnhofsbenutzer.csv`: 37 | - License: https://data.sbb.ch/page/licence 38 | - Source: https://data.sbb.ch/explore/dataset/anzahl-sbb-bahnhofbenutzer/information/ 39 | 40 | ## FR 41 | `fr_platforms.csv`: 42 | - License: https://data.sncf.com/pages/licence/#A1 43 | - Source: https://data.sncf.com/explore/dataset/liste-des-quais/information/ 44 | 45 | `fr_stations.csv`: 46 | - License: https://data.sncf.com/pages/licence/#A1 47 | - Source: https://data.sncf.com/explore/dataset/liste-des-gares/information/ 48 | 49 | `fr_acronyms.csv`: 50 | - License: https://data.sncf.com/pages/licence/#A1 51 | - Source: https://ressources.data.sncf.com/explore/dataset/lexique-des-acronymes-sncf/information/ 52 | 53 | ## UK 54 | - License: https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/ 55 | > Contains public sector information licensed under the Open Government Licence v3.0. 56 | 57 | `uk_stations`: 58 | - Source: https://datafeeds.networkrail.co.uk/ntrod/SupportingFileAuthenticate?type=CORPUS 59 | 60 | `uk_bplan.json`: 61 | - Source: https://wiki.openraildata.com/index.php?title=BPLAN_Geography_Data 62 | 63 | ## Kanada (Stationskürzel) 64 | - Quelle: https://github.com/baeuchle/ds100bot 65 | - Lizenz: https://github.com/baeuchle/ds100bot/blob/main/LICENSE 66 | > Der Quellcode dieses Bots ist unter der Apache Lizenz, Version 2.0, lizensiert. Siehe Datei LICENSE. 67 | > Die Datentabellen in sources stehen unter verschiedenen Lizenzen. Diese sind in data aufgeführt. 68 | > Wenn [der license-Eintrag] nicht vorhanden, bedeutet das, dass das Urheberrecht dieser Liste beim Autor des Bots [Bjørn Bäuchle] liegt und die Liste unter Apache Lizenz 2.0 veröffentlicht ist. 69 | 70 | Für die Datei existiert kein `license`-Eintrag. 71 | 72 | # Karte 73 | Die Hintergrund-Karte stammt von https://commons.wikimedia.org/wiki/File:BlankMap-World.svg und wurde hierfür angepasst (Skalierung, Farbgebung usw.). 74 | -------------------------------------------------------------------------------- /Network.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "idString": "europe-standard", 5 | "name": "Europa (Normalspur)", 6 | "default": true 7 | }, 8 | { 9 | "idString": "uk-standard", 10 | "name": "Großbritannien (Normalspur)" 11 | }, 12 | { 13 | "idString": "iberian-broad", 14 | "name": "Iberische Halbinsel (Breitspur)", 15 | "parent": "europe-standard", 16 | "forRandomTasks": false 17 | }, 18 | { 19 | "idString": "russian-broad", 20 | "name": "Osteuropa/Russland (Breitspur)" 21 | }, 22 | { 23 | "idString": "moldova-broad", 24 | "name": "Moldau (Breitspur)" 25 | }, 26 | { 27 | "idString": "usa-standard", 28 | "name": "USA (Normalspur)" 29 | }, 30 | { 31 | "idString": "north-africa-standard", 32 | "name": "Nordafrika (Normalspur)" 33 | }, 34 | { 35 | "idString": "special", 36 | "name": "Inselnetze", 37 | "forRandomTasks": false 38 | } 39 | ] 40 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Open in Remote - Containers](https://img.shields.io/static/v1?label=Remote%20-%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/marhei/TrainCompany-Data) [![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/marhei/TrainCompany-Data) 2 | 3 | ![Lint](https://github.com/marhei/Traincompany-Data/actions/workflows/eclint.yml/badge.svg) ![Validation](https://github.com/marhei/Traincompany-Data/actions/workflows/json_validate.yml/badge.svg) ![Check JSON content](https://github.com/marhei/Traincompany-Data/actions/workflows/check_content.yml/badge.svg) 4 | 5 | # TrainCompany Daten 6 | In diesem Repository finden sich die Daten, die von TrainCompany genutzt werden. Die Daten sind in JSON-Dateien gespeichert, die ein data-Objekt beinhalten. Um ähnliche Objekte zusammenzufassen gibt es einfache Vererbung: **"objects": []** führt dazu, dass alle Objekte, die zwischen den [] eingefügt werden automatische die Eigenschaften des Mutter-Objekts erhalten, wenn diese nicht überschrieben wurden. 7 | 8 | Eine Anleitung zum Erstellen neuer Erweiterungen usw. findet sich in [`Contributing.md`](CONTRIBUTING.md) 9 | 10 | ## Train.json 11 | Fahrzeuge, die in TC zur Verfügung stehen 12 | 13 | * **id** *(int)* Eindeutige ID jedes Fz 14 | * **group** *(int)* Art des Fahrzeuges 15 | * **0** Lokomotive 16 | * **1** Wagen 17 | * **2** Triebzug 18 | * **3** fixer Wagenverband 19 | * **service** *(int)* Zuordnung zu einer passenden Service-Klasse (siehe TaskModel.json) 20 | * **name** *(string)* Name des Fahrzeuges 21 | * **shortcut** *(string)* Baureihen/-art-Bezeichnung des Fahrzeuges *(optional)* 22 | * **speed** *(int)* Höchstgeschwindigkeit in km/h 23 | * **weight** *(int)* Gewicht in t 24 | * **force** *(int)* Anfahrzugkraft in kN 25 | * **length** *(int)* Länge in Metern 26 | * **drive** *(int)* Traktionsart 27 | * **0** Keine Traktion 28 | * **1** E-Traktion 29 | * **2** Diesel-Traktion 30 | * **3** Batterie 31 | * **4** Hybrid 32 | * **5** Wasserstoff 33 | * **6** Last Mile 34 | * **7** Dampf 35 | * **reliability** *(float)* Zuverlässigkeit in Prozent (0.8-1.0) 36 | * **cost** *(int)* Kosten in Plops 37 | * **maxConnectedUnits** *(int)* Maximale Anzahl der kuppelbaren Einheiten (bei Triebzügen, Nicht gesetzt = Unbegrenzt) 38 | * **operationCosts** *(int)* Betriebskosten pro km in Plops (Nur bei Fz mit Antrieb benutzen!) 39 | * **equipments** *(array)* Fahrzeugausstattung (siehe TrainEquipments.json) 40 | * **exchangeTime** *(int)* Aufenthaltsdauer bei Planhalten in Sekunden (Optional, Standard = 40) 41 | * **compatibleWith** *(array)* Für Triebzüge und Wagenverbände: Lässt sich zusätzlich mit den angegeben Fz kuppeln 42 | * **equivalentTo** *(int)* Nur für fixe Wagenverbände: Entspricht wie vielen Wagen? 43 | * **range** *(int)* Reichweite im Batteriebetrieb in km 44 | * **capacity** *(array)* Art der Beladung und Menge (optional, siehe Capacity.json) 45 | 46 | ## Capacity.json 47 | Art der Beladungen eines Fahrzeuges 48 | 49 | * **idString** *(int)* Eindeutige ID einer Capacity 50 | * **name** *(string)* Name der Capacity 51 | * **needsPlatform** *(bool)* Benötigt einen Bahnsteig? 52 | * **unit** *(string)* Einheit der Capacity 53 | * **unitMass** *(float)* Eine Einheit entspricht wie viel t Gewicht? 54 | * **emoji** *(string)* Emoji der Einheit 55 | * **exchangeFactor** *(float)* Faktor für automatischen Zustieg: 1 ist normale Fahrgäste (optional) 56 | 57 | 58 | ## DelayModel.json 59 | Modelle für Verspätungen 60 | 61 | * **type** *(int)* Art der Verspätung 62 | * **0** Fahrzeugstörung 63 | * **1** Personal 64 | * **2** Ladung 65 | * **3** Streckenstörung (noch nicht implementiert) 66 | * **4** Fahrplan 67 | * **name** *(string)* Verspätungstext 68 | * **delay** *(int)* Erzeugte Verspätung in Sekunden (+/-5 %) 69 | * **capacity** *(string)* In Kombination mit **type**/**2** wird eine ladungssbezifische Störung angegeben 70 | 71 | ## Path.json 72 | Verbindungen zwischen zwei Bahnhöfen 73 | 74 | * **name** *(string)* Streckenname (optional) 75 | * **group** *(int)* Art der Strecke (optional, Standard = 0) 76 | * **0** Hauptbahn 77 | * **1** Nebenbahn 78 | * **2** SFS 79 | * **3** Fähre 80 | * **start** *(string)* Ril100 des Startbahnhofs 81 | * **end** *(string)* Ril100 des Endbahnhofs 82 | * **twistingFactor** *(float)* Angebe der Kurvigkeit von 0.0 bis 1.0 wobei 1.0 am kurvigsten ist 83 | * **lenght** *(int)* Länge der Strecke in km 84 | * **maxSpeed** *(int)* Höchstgeschwingkeit des Streckenabschnitts 85 | * **electrified** *(bool)* Elektrifiziert (optional, Standard = true) 86 | * **neededEquipments** *(array)* Benötigte Fahrzeugaustattung (siehe TrainEquipments.json, optional) 87 | 88 | ## Station.json 89 | Bahnhöfe 90 | 91 | * **name** *(string)* Bahnhofsname 92 | * **ril100** *(string)* Ril100 des Bf 93 | * **group** *(int)* Art des Bahnhofs 94 | * **0** Knotenbahnhof 95 | * **1** Hauptbahnhof 96 | * **2** kleiner Bahnhof 97 | * **3** Betriebsbahnhof 98 | * **4** Abzweigstelle 99 | * **5** Haltepunkt (Wird nicht auf der Karte gerendert) 100 | * **6** Wegpunkt (Wird nicht auf der Karte gerendert) 101 | * **x** *(int)* x-Position auf Karte 102 | * **y** *(int)* y-Position auf Karte 103 | * **platformLength** *(int)* maximale Bahnsteiglänge (optional, Standard = 0) 104 | * **platforms** *(int)* Bahnsteiganzahl (optional, Standard = 0) 105 | * **network** *(string)* (optional, Standard = default Network) 106 | * **forRandomTasks** *(bool)* (optional, Standard = true) 107 | 108 | ## TaskModel.json 109 | Modelle für Aufträge, aus denen automatisch neue Aufträge erstellt werden 110 | 111 | * **group** *(int)* Art des Auftrags 112 | * **0** Direktvergabe 113 | * **1** Ausschreibung 114 | * **name** *(string)* Name des Auftrags 115 | * **service** *(int)* Servicelevel zur automatischen Berechnung des Gewinns 116 | * **0** HGV 117 | * **1** IC 118 | * **2** Regionalverkehr 119 | * **3** kurzer Regionalverkehr 120 | * **4** Sonderzug 121 | * **5** Nachtzug 122 | * **10** wichtiger Güterzug 123 | * **11** Güterzug 124 | * **descriptions** *(array)* Array mit mehreren Strings für die Ausschreibung 125 | * **stations** *(array)* Ril100 aller Bahnhöfe, die angefahren sollen in der richtigen Reihenfolge, wenn keine angegeben wurden, dann werden zwei zufällige gewählt (optional) 126 | * **pathSuggestions** *(array)* Ril100 aller Bahnhöfe, die standardmäßig mit oder ohne Halt angefahren werden sollen in der richtigen Reihenfolge. 127 | * **stopsEverywhere** *(bool)* Wenn true dann wird auch automatisch ein Halt an allen Bahnhöfen, die zwischen den oben angegeben Bahnhöfen eingeplant (optional) 128 | * **neededCapacity** *array* Art der Beladung und Menge, wenn die Menge weggelassen wird führt es zu automatischer Beladung, wenn von Capacity unterstützt (siehe Capacity.json) -------------------------------------------------------------------------------- /TrainEquipment.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "type": 2, 5 | "objects": [ 6 | { 7 | "idString": "1435mm", 8 | "name": "Normalspur", 9 | "default": true 10 | }, 11 | { 12 | "idString": "750mm", 13 | "name": "Schmalspur (750mm)", 14 | "forRandomTasks": false, 15 | "network": "special" 16 | }, 17 | { 18 | "idString": "1000mm", 19 | "name": "Meterspur", 20 | "forRandomTasks": false, 21 | "network": "special" 22 | }, 23 | { 24 | "idString": "1668mm", 25 | "name": "Iberische Breitspur", 26 | "network": "iberian-broad" 27 | }, 28 | { 29 | "idString": "1520mm", 30 | "name": "Russische Breitspur", 31 | "network": "russian-broad" 32 | } 33 | ] 34 | }, 35 | { 36 | "type": 0, 37 | "objects": [ 38 | { 39 | "idString": "DE", 40 | "emoji": "🇩🇪", 41 | "name": "Deutschland", 42 | "default": true 43 | }, 44 | { 45 | "idString": "AL", 46 | "emoji": "🇦🇱", 47 | "name": "Albanien" 48 | }, 49 | { 50 | "idString": "BY", 51 | "emoji": "🇧🇾", 52 | "name": "Belarus" 53 | }, 54 | { 55 | "idString": "BE", 56 | "emoji": "🇧🇪", 57 | "name": "Belgien" 58 | }, 59 | { 60 | "idString": "BA", 61 | "emoji": "🇧🇦", 62 | "name": "Bosnien" 63 | }, 64 | { 65 | "idString": "BG", 66 | "emoji": "🇧🇬", 67 | "name": "Bulgarien" 68 | }, 69 | { 70 | "idString": "DK", 71 | "emoji": "🇩🇰", 72 | "name": "Dänemark" 73 | }, 74 | { 75 | "idString": "EE", 76 | "emoji": "🇪🇪", 77 | "name": "Estland" 78 | }, 79 | { 80 | "idString": "FI", 81 | "emoji": "🇫🇮", 82 | "name": "Finnland" 83 | }, 84 | { 85 | "idString": "FR", 86 | "emoji": "🇫🇷", 87 | "name": "Frankreich" 88 | }, 89 | { 90 | "idString": "GR", 91 | "emoji": "🇬🇷", 92 | "name": "Griechenland" 93 | }, 94 | { 95 | "idString": "GB", 96 | "emoji": "🇬🇧", 97 | "name": "Großbritannien", 98 | "network": "uk-standard" 99 | }, 100 | { 101 | "idString": "IT", 102 | "emoji": "🇮🇹", 103 | "name": "Italien" 104 | }, 105 | { 106 | "idString": "CA", 107 | "emoji": "🇨🇦", 108 | "name": "Kanada", 109 | "network": "usa-standard" 110 | }, 111 | { 112 | "idString": "HR", 113 | "emoji": "🇭🇷", 114 | "name": "Kroatien" 115 | }, 116 | { 117 | "idString": "LV", 118 | "emoji": "🇱🇻", 119 | "name": "Lettland" 120 | }, 121 | { 122 | "idString": "LT", 123 | "emoji": "🇱🇹", 124 | "name": "Litauen" 125 | }, 126 | { 127 | "idString": "LU", 128 | "emoji": "🇱🇺", 129 | "name": "Luxemburg" 130 | }, 131 | { 132 | "idString": "MA", 133 | "emoji": "🇲🇦", 134 | "name": "Marokko", 135 | "network": "north-africa-standard" 136 | }, 137 | { 138 | "idString": "MD", 139 | "emoji": "🇲🇩", 140 | "name": "Moldau", 141 | "network": "moldova-broad" 142 | }, 143 | { 144 | "idString": "ME", 145 | "emoji": "🇲🇪", 146 | "name": "Montenegro" 147 | }, 148 | { 149 | "idString": "NL", 150 | "emoji": "🇳🇱", 151 | "name": "Niederlande" 152 | }, 153 | { 154 | "idString": "MK", 155 | "emoji": "🇲🇰", 156 | "name": "Nordmazedonien" 157 | }, 158 | { 159 | "idString": "NO", 160 | "emoji": "🇳🇴", 161 | "name": "Norwegen" 162 | }, 163 | { 164 | "idString": "AT", 165 | "emoji": "🇦🇹", 166 | "name": "Österreich" 167 | }, 168 | { 169 | "idString": "PL", 170 | "emoji": "🇵🇱", 171 | "name": "Polen" 172 | }, 173 | { 174 | "idString": "PT", 175 | "emoji": "🇵🇹", 176 | "name": "Portugal" 177 | }, 178 | { 179 | "idString": "RO", 180 | "emoji": "🇷🇴", 181 | "name": "Rumänien" 182 | }, 183 | { 184 | "idString": "RU", 185 | "emoji": "🇷🇺", 186 | "name": "Russland" 187 | }, 188 | { 189 | "idString": "SE", 190 | "emoji": "🇸🇪", 191 | "name": "Schweden" 192 | }, 193 | { 194 | "idString": "CH", 195 | "emoji": "🇨🇭", 196 | "name": "Schweiz" 197 | }, 198 | { 199 | "idString": "RS", 200 | "emoji": "🇷🇸", 201 | "name": "Serbien" 202 | }, 203 | { 204 | "idString": "SK", 205 | "emoji": "🇸🇰", 206 | "name": "Slowakei" 207 | }, 208 | { 209 | "idString": "SI", 210 | "emoji": "🇸🇮", 211 | "name": "Slowenien" 212 | }, 213 | { 214 | "idString": "ES", 215 | "emoji": "🇪🇸", 216 | "name": "Spanien" 217 | }, 218 | { 219 | "idString": "CZ", 220 | "emoji": "🇨🇿", 221 | "name": "Tschechien" 222 | }, 223 | { 224 | "idString": "TR", 225 | "emoji": "🇹🇷", 226 | "name": "Türkei" 227 | }, 228 | { 229 | "idString": "UA", 230 | "emoji": "🇺🇦", 231 | "name": "Ukraine" 232 | }, 233 | { 234 | "idString": "HU", 235 | "emoji": "🇭🇺", 236 | "name": "Ungarn" 237 | }, 238 | { 239 | "idString": "US", 240 | "emoji": "🇺🇸", 241 | "name": "USA", 242 | "network": "usa-standard" 243 | } 244 | ] 245 | }, 246 | { 247 | "type": 1, 248 | "objects": [ 249 | { 250 | "idString": "ETCS", 251 | "name": "ETCS" 252 | }, 253 | { 254 | "idString": "KRM", 255 | "name": "KRM", 256 | "forRandomTasks": false 257 | }, 258 | { 259 | "idString": "bostrab", 260 | "name": "BOStrab", 261 | "forRandomTasks": false 262 | }, 263 | { 264 | "idString": "TVM", 265 | "name": "TVM", 266 | "forRandomTasks": false 267 | }, 268 | { 269 | "idString": "Eurotunnel", 270 | "name": "Eurotunnel", 271 | "forRandomTasks": false 272 | } 273 | ] 274 | } 275 | ] 276 | } 277 | -------------------------------------------------------------------------------- /schemas/Capacity.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://raw.githubusercontent.com/marhei/TrainCompany-Data/main/schemas/Capacity.json", 4 | "title": "Art der Beladungen eines Fahrzeugs", 5 | "type": "object", 6 | "properties": { 7 | "data": { 8 | "type": "array", 9 | "items": { 10 | "allOf": [ 11 | {"$ref": "#/$defs/capacity"}, 12 | { 13 | "anyOf": [ 14 | { 15 | "required": ["idString"] 16 | }, 17 | { 18 | "properties": { 19 | "objects": { 20 | "items": { 21 | "required": ["idString"] 22 | } 23 | } 24 | }, 25 | "required": ["objects"] 26 | } 27 | ] 28 | }, 29 | { 30 | "anyOf": [ 31 | { 32 | "required": ["name"] 33 | }, 34 | { 35 | "properties": { 36 | "objects": { 37 | "items": { 38 | "required": ["name"] 39 | } 40 | } 41 | }, 42 | "required": ["objects"] 43 | } 44 | ] 45 | }, 46 | { 47 | "anyOf": [ 48 | { 49 | "required": ["needsPlatform"] 50 | }, 51 | { 52 | "properties": { 53 | "objects": { 54 | "items": { 55 | "required": ["needsPlatform"] 56 | } 57 | } 58 | }, 59 | "required": ["objects"] 60 | } 61 | ] 62 | }, 63 | { 64 | "anyOf": [ 65 | { 66 | "required": ["unitMass"] 67 | }, 68 | { 69 | "properties": { 70 | "objects": { 71 | "items": { 72 | "required": ["unitMass"] 73 | } 74 | } 75 | }, 76 | "required": ["objects"] 77 | } 78 | ] 79 | }, 80 | { 81 | "anyOf": [ 82 | { 83 | "required": ["emoji"] 84 | }, 85 | { 86 | "properties": { 87 | "objects": { 88 | "items": { 89 | "required": ["emoji"] 90 | } 91 | } 92 | }, 93 | "required": ["objects"] 94 | } 95 | ] 96 | } 97 | ] 98 | }, 99 | "uniqueItems": true 100 | } 101 | }, 102 | "$defs": { 103 | "capacity": { 104 | "type": "object", 105 | "properties": { 106 | "idString": { 107 | "description": "Eindeutige ID einer Capacity", 108 | "type": "string", 109 | "minimum": 0 110 | }, 111 | "name": { 112 | "description": "Name der Capacity", 113 | "type": "string" 114 | }, 115 | "needsPlatform": { 116 | "description": "Benötigt einen bahnsteig?", 117 | "type": "boolean" 118 | }, 119 | "unit": { 120 | "description": "Einheit der Capacity", 121 | "type": "string" 122 | }, 123 | "unitMass": { 124 | "description": "Masse einer Einheit in t", 125 | "type": "number", 126 | "minimum": 0 127 | }, 128 | "emoji": { 129 | "description": "Emoji der Einheit", 130 | "type": "string" 131 | }, 132 | "exchangeFactor": { 133 | "description": "Faktor für automatischen Zustieg: 1 ist normale Fahrgäste", 134 | "type": "number", 135 | "minimum": 0, 136 | "maximum": 5 137 | }, 138 | "objects": { 139 | "description": "Sub-Ladungsarten, die ihre nicht definierten Eigenschaften von der darüberliegenden Ebene erben.", 140 | "type": "array", 141 | "items": { 142 | "$ref": "#/$defs/capacity" 143 | } 144 | } 145 | } 146 | } 147 | } 148 | } -------------------------------------------------------------------------------- /schemas/DelayModel.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://raw.githubusercontent.com/marhei/TrainCompany-Data/main/schemas/DelayModel.json", 4 | "title": "Modelle für Verspätungen", 5 | "type": "object", 6 | "properties": { 7 | "data": { 8 | "type": "array", 9 | "items": { 10 | "allOf": [ 11 | {"$ref": "#/$defs/delay"}, 12 | { 13 | "anyOf": [ 14 | { 15 | "required": ["type"] 16 | }, 17 | { 18 | "properties": { 19 | "objects": { 20 | "items": { 21 | "required": ["type"] 22 | } 23 | } 24 | }, 25 | "required": ["objects"] 26 | } 27 | ] 28 | }, 29 | { 30 | "anyOf": [ 31 | { 32 | "required": ["name"] 33 | }, 34 | { 35 | "properties": { 36 | "objects": { 37 | "items": { 38 | "required": ["name"] 39 | } 40 | } 41 | }, 42 | "required": ["objects"] 43 | } 44 | ] 45 | }, 46 | { 47 | "anyOf": [ 48 | { 49 | "required": ["delay"] 50 | }, 51 | { 52 | "properties": { 53 | "objects": { 54 | "items": { 55 | "required": ["delay"] 56 | } 57 | } 58 | }, 59 | "required": ["objects"] 60 | } 61 | ] 62 | } 63 | ] 64 | }, 65 | "uniqueItems": true 66 | } 67 | }, 68 | "$defs": { 69 | "delay": { 70 | "type": "object", 71 | "properties": { 72 | "type": { 73 | "description": "Art der Verspätung", 74 | "type": "integer", 75 | "oneOf": [ 76 | {"const": 0, "description": "Fahrzeugstörung"}, 77 | {"const": 1, "description": "Personal"}, 78 | {"const": 2, "description": "Ladung"}, 79 | {"const": 3, "description": "Streckenstörung (noch nicht implementiert)"}, 80 | {"const": 4, "description": "Fahrplan"}, 81 | {"const": 5, "description": "Haltezeitüberschreitung"} 82 | ] 83 | }, 84 | "name": { 85 | "description": "Verspätungstext", 86 | "type": "string" 87 | }, 88 | "delay": { 89 | "description": "Erzeugte Verspätung in Sekunden (+/-5%)", 90 | "type": "integer" 91 | }, 92 | "objects": { 93 | "description": "Sub-Verspätungen, die ihre nicht definierten Eigenschaften von der darüberliegenden Ebene erben.", 94 | "type": "array", 95 | "items": { 96 | "$ref": "#/$defs/delay" 97 | } 98 | } 99 | }, 100 | "if": { 101 | "properties": { 102 | "type": { 103 | "const": 2 104 | } 105 | } 106 | }, 107 | "then": { 108 | "properties": { 109 | "capacity": { 110 | "description": "Die Ladungsart, für die die Störung gilt", 111 | "type": "string" 112 | } 113 | } 114 | } 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /schemas/Path.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://raw.githubusercontent.com/marhei/TrainCompany-Data/main/schemas/Path.json", 4 | "title": "Verbindungen zwischen zwei Bahnhöfen", 5 | "type": "object", 6 | "properties": { 7 | "data": { 8 | "type": "array", 9 | "items": { 10 | "allOf": [ 11 | {"$ref": "#/$defs/path"}, 12 | { 13 | "anyOf": [ 14 | { 15 | "required": ["start"] 16 | }, 17 | { 18 | "properties": { 19 | "objects": { 20 | "items": { 21 | "required": ["start"] 22 | } 23 | } 24 | }, 25 | "required": ["objects"] 26 | } 27 | ] 28 | }, 29 | { 30 | "anyOf": [ 31 | { 32 | "required": ["end"] 33 | }, 34 | { 35 | "properties": { 36 | "objects": { 37 | "items": { 38 | "required": ["end"] 39 | } 40 | } 41 | }, 42 | "required": ["objects"] 43 | } 44 | ] 45 | }, 46 | { 47 | "anyOf": [ 48 | { 49 | "required": ["twistingFactor"] 50 | }, 51 | { 52 | "properties": { 53 | "objects": { 54 | "items": { 55 | "required": ["twistingFactor"] 56 | } 57 | } 58 | }, 59 | "required": ["objects"] 60 | } 61 | ] 62 | }, 63 | { 64 | "anyOf": [ 65 | { 66 | "required": ["length"] 67 | }, 68 | { 69 | "properties": { 70 | "objects": { 71 | "items": { 72 | "required": ["length"] 73 | } 74 | } 75 | }, 76 | "required": ["objects"] 77 | } 78 | ] 79 | }, 80 | { 81 | "anyOf": [ 82 | { 83 | "required": ["maxSpeed"] 84 | }, 85 | { 86 | "properties": { 87 | "objects": { 88 | "items": { 89 | "required": ["maxSpeed"] 90 | } 91 | } 92 | }, 93 | "required": ["objects"] 94 | } 95 | ] 96 | } 97 | ] 98 | }, 99 | "uniqueItems": true 100 | } 101 | }, 102 | "$defs": { 103 | "path": { 104 | "type": "object", 105 | "properties": { 106 | "name": { 107 | "description": "Streckenname", 108 | "type": "string" 109 | }, 110 | "group": { 111 | "description": "Art der Strecke", 112 | "type": "integer", 113 | "oneOf": [ 114 | {"const": 0, "description": "Hauptbahn"}, 115 | {"const": 1, "description": "Nebenbahn"}, 116 | {"const": 2, "description": "SFS"}, 117 | {"const": 3, "description": "Fähre"} 118 | ], 119 | "default": 0 120 | }, 121 | "start": { 122 | "description": "Ril100 des Startbahnhofs", 123 | "type": "string", 124 | "minLength": 2, 125 | "maxLength": 20 126 | }, 127 | "end": { 128 | "description": "Ril100 des Endbahnhofs", 129 | "type": "string", 130 | "minLength": 2, 131 | "maxLength": 20 132 | }, 133 | "twistingFactor": { 134 | "description": "Kurvigkeit. 1 ist am kurvigsten", 135 | "type": "number", 136 | "minimum": 0, 137 | "maximum": 0.8 138 | }, 139 | "maxSpeed": { 140 | "description": "Höchstgeschwindigkeit des Streckenabschnitts", 141 | "type": "integer", 142 | "minimum": 10, 143 | "maximum": 360 144 | }, 145 | "electrified": { 146 | "description": "Elektrifiziert", 147 | "type": "boolean", 148 | "default": true 149 | }, 150 | "neededEquipments": { 151 | "description": "Benötigte Fahrzeugausstattung", 152 | "type": "array", 153 | "items": { 154 | "type": "string", 155 | "examples": [ 156 | "ETCS", 157 | "KRM", 158 | "FR", 159 | "TVM", 160 | "Eurotunnel", 161 | "bostrab", 162 | "AT", 163 | "BE", 164 | "BG", 165 | "CH", 166 | "CZ", 167 | "DK", 168 | "ES", 169 | "FR", 170 | "GB", 171 | "GR", 172 | "HR", 173 | "HU", 174 | "IT", 175 | "LU", 176 | "NL", 177 | "PL", 178 | "RS", 179 | "SE", 180 | "SI", 181 | "TR", 182 | "US" 183 | ] 184 | } 185 | }, 186 | "objects": { 187 | "description": "Sub-Routen, die ihre nicht definierten Eigenschaften von der darüberliegenden Ebene erben.", 188 | "type": "array", 189 | "items": { 190 | "$ref": "#/$defs/path" 191 | } 192 | } 193 | }, 194 | "if": { 195 | "properties": { 196 | "group": { 197 | "const": 3 198 | } 199 | } 200 | }, 201 | "then": { 202 | "properties": { 203 | "length": { 204 | "description": "Länge der Strecke", 205 | "type": "integer", 206 | "minimum": 1 207 | } 208 | } 209 | }, 210 | "else": { 211 | "properties": { 212 | "length": { 213 | "description": "Länge der Strecke", 214 | "type": "integer", 215 | "minimum": 1, 216 | "maximum": 300 217 | } 218 | } 219 | } 220 | } 221 | } 222 | } -------------------------------------------------------------------------------- /schemas/Station.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://raw.githubusercontent.com/marhei/TrainCompany-Data/main/schemas/Station.json", 4 | "title": "Bahnhöfe", 5 | "type": "object", 6 | "properties": { 7 | "data": { 8 | "type": "array", 9 | "items": { 10 | "allOf": [ 11 | { "$ref": "#/$defs/station" }, 12 | { 13 | "anyOf": [ 14 | { "required": ["name"] }, 15 | { 16 | "properties": { 17 | "objects": { 18 | "items": { "required": ["name"] } 19 | } 20 | }, 21 | "required": ["objects"] 22 | } 23 | ] 24 | }, 25 | { 26 | "anyOf": [ 27 | { "required": ["ril100"] }, 28 | { 29 | "properties": { 30 | "objects": { 31 | "items": { "required": ["ril100"] } 32 | } 33 | }, 34 | "required": ["objects"] 35 | } 36 | ] 37 | }, 38 | { 39 | "anyOf": [ 40 | { "required": ["group"] }, 41 | { 42 | "properties": { 43 | "objects": { 44 | "items": { "required": ["group"] } 45 | } 46 | }, 47 | "required": ["objects"] 48 | } 49 | ] 50 | }, 51 | { 52 | "anyOf": [ 53 | { "required": ["x"] }, 54 | { 55 | "properties": { 56 | "objects": { 57 | "items": { "required": ["x"] } 58 | } 59 | }, 60 | "required": ["objects"] 61 | } 62 | ] 63 | }, 64 | { 65 | "anyOf": [ 66 | { "required": ["y"] }, 67 | { 68 | "properties": { 69 | "objects": { 70 | "items": { "required": ["y"] } 71 | } 72 | }, 73 | "required": ["objects"] 74 | } 75 | ] 76 | } 77 | ] 78 | }, 79 | "uniqueItems": true 80 | } 81 | }, 82 | "$defs": { 83 | "station": { 84 | "type": "object", 85 | "properties": { 86 | "name": { 87 | "description": "Bahnhofsname", 88 | "type": "string" 89 | }, 90 | "ril100": { 91 | "description": "Ril100 des Bf", 92 | "type": "string", 93 | "minLength": 2, 94 | "maxLength": 20 95 | }, 96 | "group": { 97 | "description": "Art des Bahnhofs", 98 | "type": "integer", 99 | "oneOf": [ 100 | {"const": 0, "description": "Knotenbahnhof"}, 101 | {"const": 1, "description": "Hauptbahnhof"}, 102 | {"const": 2, "description": "kleiner Bahnhof"}, 103 | {"const": 3, "description": "Betriebsbahnhof"}, 104 | {"const": 4, "description": "Abzweigstelle"}, 105 | {"const": 5, "description": "Haltepunkt"}, 106 | {"const": 6, "description": "Wegpunkt"} 107 | ] 108 | }, 109 | "x": { 110 | "description": "x-Position auf Karte", 111 | "type": "integer" 112 | }, 113 | "y": { 114 | "description": "y-Position auf Karte", 115 | "type": "integer" 116 | }, 117 | "platformLength": { 118 | "description": "maximale Bahnsteiglänge", 119 | "type": "integer", 120 | "minimum": 0, 121 | "default": 0 122 | }, 123 | "platforms": { 124 | "description": "Bahnsteiganzahl", 125 | "type": "integer", 126 | "minimum": 0, 127 | "default": 0 128 | }, 129 | "forRandomTasks": { 130 | "description": "Wenn false wird die Station niemals für zufällige Tasks genutzt.", 131 | "type": "boolean", 132 | "default": true 133 | }, 134 | "network": { 135 | "description": "Zufällige Ausschreibungen werden nur innerhalb eines Netzwerks generiert.", 136 | "type": "string", 137 | "default": null 138 | }, 139 | "inDefaultRectangle": { 140 | "description": "Zur Defination des Standard-Zoom-Rechtecks der Karte. Bitte nicht selbst setzen!", 141 | "type": "boolean", 142 | "default": false 143 | }, 144 | "objects": { 145 | "description": "Sub-Stationen, die ihre nicht definierten Eigenschaften von der darüberliegenden Ebene erben.", 146 | "type": "array", 147 | "items": { 148 | "$ref": "#/$defs/station" 149 | } 150 | } 151 | } 152 | } 153 | } 154 | } -------------------------------------------------------------------------------- /schemas/TaskModel.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://raw.githubusercontent.com/marhei/TrainCompany-Data/main/schemas/TaskModel.json", 4 | "title": "Modelle für Aufträge, aus denen automatisch neue Aufträge erstellt werden", 5 | "type": "object", 6 | "properties": { 7 | "data": { 8 | "type": "array", 9 | "items": { 10 | "allOf": [ 11 | {"$ref": "#/$defs/task"}, 12 | { 13 | "anyOf": [ 14 | { "required": ["group"] }, 15 | { 16 | "properties": { 17 | "objects": { 18 | "items": { "required": ["group"] } 19 | } 20 | }, 21 | "required": ["objects"] 22 | } 23 | ] 24 | }, 25 | { 26 | "anyOf": [ 27 | { "required": ["name"] }, 28 | { 29 | "properties": { 30 | "objects": { 31 | "items": { "required": ["name"] } 32 | } 33 | }, 34 | "required": ["objects"] 35 | } 36 | ] 37 | }, 38 | { 39 | "anyOf": [ 40 | { "required": ["descriptions"] }, 41 | { 42 | "properties": { 43 | "objects": { 44 | "items": { "required": ["descriptions"] } 45 | } 46 | }, 47 | "required": ["objects"] 48 | } 49 | ] 50 | }, 51 | { 52 | "anyOf": [ 53 | { "required": ["neededCapacity"] }, 54 | { 55 | "properties": { 56 | "objects": { 57 | "items": { "required": ["neededCapacity"] } 58 | } 59 | }, 60 | "required": ["objects"] 61 | } 62 | ] 63 | }, 64 | { 65 | "anyOf": [ 66 | { "required": ["service"] }, 67 | { 68 | "properties": { 69 | "objects": { 70 | "items": { "required": ["service"] } 71 | } 72 | }, 73 | "required": ["objects"] 74 | } 75 | ] 76 | } 77 | ] 78 | }, 79 | "uniqueItems": true 80 | } 81 | }, 82 | "$defs": { 83 | "task": { 84 | "type": "object", 85 | "properties": { 86 | "group": { 87 | "description": "Art des Auftrags", 88 | "type": "integer", 89 | "oneOf": [ 90 | {"const": 0, "description": "Direktvergabe"}, 91 | {"const": 1, "description": "Ausschreibung"} 92 | ] 93 | }, 94 | "name": { 95 | "description": "Name des Auftrags\n%s als Platzhalter für Start/Ziel", 96 | "type": "string" 97 | }, 98 | "service": { 99 | "description": "Servicelevel", 100 | "type": "integer", 101 | "oneOf": [ 102 | {"const": 0, "description": "HGV"}, 103 | {"const": 1, "description": "IC"}, 104 | {"const": 2, "description": "Regionalverkehr"}, 105 | {"const": 3, "description": "kurzer Regionalverkehr"}, 106 | {"const": 4, "description": "Sonderzug"}, 107 | {"const": 5, "description": "Nachtzug"}, 108 | {"const": 10, "description": "wichtiger Güterzug"}, 109 | {"const": 11, "description": "Güterzug"} 110 | ] 111 | }, 112 | "descriptions": { 113 | "description": "Beschreibung(en) der Ausschreibung", 114 | "type": "array", 115 | "items": { 116 | "type": "string", 117 | "description": "%s als Platzhalter für Start/Ziel" 118 | } 119 | }, 120 | "stations": { 121 | "description": "Ril100 aller Bahnhöfe, die angefahren werden sollen in der richtigen Reihenfolge.\nWird keiner angegeben, werden zwei zufällige gewählt.", 122 | "type": "array", 123 | "items": { 124 | "oneOf": [ 125 | { 126 | "type": "string", 127 | "minLength": 2, 128 | "maxLength": 20 129 | }, 130 | { 131 | "type": "null" 132 | } 133 | ] 134 | } 135 | }, 136 | "pathSuggestion": { 137 | "description": "Ril100 aller Bahnhöfe, die standardmäßig mit oder ohne Halt angefahren werden sollen in der richtigen Reihenfolge.", 138 | "type": "array", 139 | "items": { 140 | "type": "string", 141 | "minLength": 2, 142 | "maxLength": 20 143 | } 144 | }, 145 | "stopsEverywhere": { 146 | "description": "Wenn true dann wird auch automatisch ein Halt an allen Bahnhöfen, die zwischen den oben angegeben Bahnhöfen eingeplant", 147 | "type": "boolean", 148 | "default": false 149 | }, 150 | "neededCapacity": { 151 | "description": "Art der Beladung und Menge.", 152 | "type": "array", 153 | "items": { 154 | "type": "object", 155 | "properties": { 156 | "name": { 157 | "description": "Art der Ladung", 158 | "type": "string", 159 | "examples": [ 160 | "passengers", 161 | "beds", 162 | "wood", 163 | "oil", 164 | "cars", 165 | "containers", 166 | "castor", 167 | "beds", 168 | "bistroseats", 169 | "pullman" 170 | ] 171 | } 172 | }, 173 | "value": { 174 | "description": "Menge der Ladung", 175 | "type": "integer", 176 | "minimum": 1 177 | } 178 | } 179 | }, 180 | "objects": { 181 | "description": "Sub-Aufgaben, die ihre nicht definierten Eigenschaften von der darüberliegenden Ebene erben.", 182 | "type": "array", 183 | "items": { 184 | "$ref": "#/$defs/task" 185 | } 186 | } 187 | } 188 | } 189 | } 190 | } -------------------------------------------------------------------------------- /schemas/Train.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://raw.githubusercontent.com/marhei/TrainCompany-Data/main/schemas/Train.json", 4 | "title": "Liste der Zug-Baureihen", 5 | "type": "object", 6 | "properties": { 7 | "data" : { 8 | "description": "Die Züge, die in TrainCompany zur Verfügung stehen", 9 | "type": "array", 10 | "items": { 11 | "allOf": [ 12 | {"$ref": "#/$defs/train"}, 13 | { 14 | "anyOf": [ 15 | { "required": ["id"] }, 16 | { 17 | "properties": { 18 | "objects": { 19 | "items": { "required": ["id"] } 20 | } 21 | }, 22 | "required": ["objects"] 23 | } 24 | ] 25 | }, 26 | { 27 | "anyOf": [ 28 | { "required": ["group"] }, 29 | { 30 | "properties": { 31 | "objects": { 32 | "items": { "required": ["group"] } 33 | } 34 | }, 35 | "required": ["objects"] 36 | } 37 | ] 38 | }, 39 | { 40 | "anyOf": [ 41 | { "required": ["name"] }, 42 | { 43 | "properties": { 44 | "objects": { 45 | "items": { "required": ["name"] } 46 | } 47 | }, 48 | "required": ["objects"] 49 | } 50 | ] 51 | }, 52 | { 53 | "anyOf": [ 54 | { "required": ["speed"] }, 55 | { 56 | "properties": { 57 | "objects": { 58 | "items": { "required": ["speed"] } 59 | } 60 | }, 61 | "required": ["objects"] 62 | } 63 | ] 64 | }, 65 | { 66 | "anyOf": [ 67 | { "required": ["weight"] }, 68 | { 69 | "properties": { 70 | "objects": { 71 | "items": { "required": ["weight"] } 72 | } 73 | }, 74 | "required": ["objects"] 75 | } 76 | ] 77 | }, 78 | { 79 | "anyOf": [ 80 | { "required": ["force"] }, 81 | { 82 | "properties": { 83 | "objects": { 84 | "items": { "required": ["force"] } 85 | } 86 | }, 87 | "required": ["objects"] 88 | } 89 | ] 90 | }, 91 | { 92 | "anyOf": [ 93 | { "required": ["length"] }, 94 | { 95 | "properties": { 96 | "objects": { 97 | "items": { "required": ["length"] } 98 | } 99 | }, 100 | "required": ["objects"] 101 | } 102 | ] 103 | }, 104 | { 105 | "anyOf": [ 106 | { "required": ["drive"] }, 107 | { 108 | "properties": { 109 | "objects": { 110 | "items": { "required": ["drive"] } 111 | } 112 | }, 113 | "required": ["objects"] 114 | } 115 | ] 116 | }, 117 | { 118 | "anyOf": [ 119 | { "required": ["reliability"] }, 120 | { 121 | "properties": { 122 | "objects": { 123 | "items": { "required": ["reliability"] } 124 | } 125 | }, 126 | "required": ["objects"] 127 | } 128 | ] 129 | }, 130 | { 131 | "anyOf": [ 132 | { "required": ["cost"] }, 133 | { 134 | "properties": { 135 | "objects": { 136 | "items": { "required": ["cost"] } 137 | } 138 | }, 139 | "required": ["objects"] 140 | } 141 | ] 142 | } 143 | ] 144 | }, 145 | "uniqueItems": true 146 | } 147 | }, 148 | "$defs": { 149 | "train": { 150 | "type": "object", 151 | "properties": { 152 | "id": { 153 | "description": "Eindeutige ID des Fz", 154 | "type": "integer", 155 | "minimum": 0 156 | }, 157 | "group": { 158 | "description": "Art des Fahrzeugs", 159 | "type": "integer", 160 | "oneOf": [ 161 | {"const": 0, "description": "Lokomotive"}, 162 | {"const": 1, "description": "Wagen"}, 163 | {"const": 2, "description": "Triebzug"}, 164 | {"const": 3, "description": "fixer Wagenverband"} 165 | ] 166 | }, 167 | "service": { 168 | "description": "Servicelevel", 169 | "type": "integer", 170 | "oneOf": [ 171 | {"const": 0, "description": "HGV"}, 172 | {"const": 1, "description": "IC"}, 173 | {"const": 2, "description": "Regionalverkehr"}, 174 | {"const": 3, "description": "kurzer Regionalverkehr"}, 175 | {"const": 4, "description": "Sonderzug"}, 176 | {"const": 5, "description": "Nachtzug"}, 177 | {"const": 10, "description": "wichtiger Güterzug"}, 178 | {"const": 11, "description": "Güterzug"} 179 | ] 180 | }, 181 | "name": { 182 | "description": "Name des Fahrzeugs", 183 | "type": "string" 184 | }, 185 | "shortcut": { 186 | "description": "Baureihen/-art-Bezeichnung des Fahrzeugs", 187 | "type": "string" 188 | }, 189 | "speed": { 190 | "description": "Höchstgeschwindigkeit in km/h", 191 | "type": "integer", 192 | "minimum": 0 193 | }, 194 | "weight": { 195 | "description": "Gewicht in t", 196 | "type": "integer", 197 | "minimum": 0 198 | }, 199 | "force": { 200 | "description": "Anfahrzugkraft in kN", 201 | "type": "integer", 202 | "minimum": 0 203 | }, 204 | "length": { 205 | "description": "Länge in m", 206 | "type": "integer", 207 | "minimum": 0 208 | }, 209 | "drive": { 210 | "description": "Traktionsart", 211 | "type": "integer", 212 | "oneOf": [ 213 | {"const": 0, "description": "Keine Traktion"}, 214 | {"const": 1, "description": "E-Traktion"}, 215 | {"const": 2, "description": "Diesel-Traktion"}, 216 | {"const": 3, "description": "Batterie"}, 217 | {"const": 4, "description": "Hybrid"}, 218 | {"const": 5, "description": "Wasserstoff"}, 219 | {"const": 6, "description": "Last Mile"}, 220 | {"const": 7, "description": "Dampf"} 221 | ] 222 | }, 223 | "range": { 224 | "description": "Reichweite im Batterie-Betrieb", 225 | "type": "integer", 226 | "minimum": 0, 227 | "default": 0 228 | }, 229 | "reliability": { 230 | "description": "Zuverlässigkeit in Prozent", 231 | "type": "number", 232 | "minimum": 0.8, 233 | "maximum": 1 234 | }, 235 | "cost": { 236 | "description": "Kosten in Plops", 237 | "type": "integer", 238 | "minimum": 0 239 | }, 240 | "operationCosts": { 241 | "description": "Betriebskosten pro km in Plops", 242 | "type": "integer", 243 | "minimum": 0 244 | }, 245 | "equipments": { 246 | "description": "Fahrzeugausstattung", 247 | "type": "array", 248 | "items": { 249 | "type": "string", 250 | "examples": [ 251 | "ETCS", 252 | "KRM", 253 | "FR", 254 | "TVM", 255 | "Eurotunnel", 256 | "bostrab", 257 | "AT", 258 | "BE", 259 | "BG", 260 | "CH", 261 | "CZ", 262 | "DK", 263 | "ES", 264 | "FR", 265 | "GB", 266 | "GR", 267 | "HR", 268 | "HU", 269 | "IT", 270 | "LU", 271 | "NL", 272 | "PL", 273 | "RS", 274 | "SE", 275 | "SI", 276 | "TR", 277 | "US" 278 | ] 279 | }, 280 | "uniqueItems": true 281 | }, 282 | "exchangeTime": { 283 | "description": "Aufenthaltsdauer bei Planhalten in Sekunden", 284 | "type": "integer", 285 | "minimum": 0, 286 | "default": 40 287 | }, 288 | "capacity": { 289 | "description": "Art der Beladung und Menge", 290 | "type": "array", 291 | "items": { 292 | "type": "object", 293 | "properties": { 294 | "name": { 295 | "description": "Art der Beladung", 296 | "type": "string", 297 | "examples": [ 298 | "passengers", 299 | "wood", 300 | "oil", 301 | "cars", 302 | "containers", 303 | "castor", 304 | "coal", 305 | "beds", 306 | "bistroseats", 307 | "pullman" 308 | ] 309 | }, 310 | "value": { 311 | "description": "Menge der Beladung", 312 | "type": "integer", 313 | "minimum": 1 314 | } 315 | }, 316 | "required": [ 317 | "name", 318 | "value" 319 | ], 320 | "uniqueItems": true 321 | } 322 | }, 323 | "objects": { 324 | "description": "Sub-Baureihen, die ihre nicht definierten Eigenschaften von der darüberliegenden Ebene erben.", 325 | "type": "array", 326 | "items": { 327 | "$ref": "#/$defs/train" 328 | } 329 | } 330 | }, 331 | "allOf": [ 332 | { 333 | "if": { 334 | "properties": { 335 | "group": { 336 | "minimum": 2, 337 | "maximum": 3 338 | } 339 | } 340 | }, 341 | "then": { 342 | "properties": { 343 | "maxConnectedUnits": { 344 | "description": "Maximale Anzahl der kuppelbaren Einheiten", 345 | "type": "integer", 346 | "oneOf": [ 347 | {"const": 0, "description": "unbegrenzt"}, 348 | {"minimum": 1} 349 | ], 350 | "default": 0 351 | }, 352 | "compatibleWith": { 353 | "description": "Lässt sich zusätzlich mit den angegebenen Fz kuppeln", 354 | "type": "array", 355 | "items": { 356 | "type": "integer", 357 | "minimum": 0 358 | } 359 | } 360 | } 361 | } 362 | }, 363 | { 364 | "if": { 365 | "properties": { 366 | "group": { 367 | "const": 3 368 | } 369 | } 370 | }, 371 | "then": { 372 | "properties": { 373 | "equivalentTo": { 374 | "description": "Entspricht wie vielen Wagen?", 375 | "type": "integer", 376 | "minimum": 1 377 | } 378 | } 379 | } 380 | } 381 | ] 382 | } 383 | } 384 | } --------------------------------------------------------------------------------