Plzeň trolleybuses (PMDP)
Published at https://claude.ai/artifact/B9vVcHutYdXdg4sscpA1gR (republish to the same URL after a rebuild). Maintained by session simutrans-timetable-a2.
The Plzeň trolleybus sheet is built from stored raw data by the scripts in this folder. The shared rules are in ../README.md. The same scripts also build the Plzeň bus sheet (../plzen-bus, run with --base ../../plzen-bus), and the raw data both sheets use is stored here once.
| State file | Network | Vehicles | Output (project root) |
|---|---|---|---|
states/2026-09-29.json |
Tue 29 Sep 2026 (GTFS service day 29 Sep) | Fri 18 Sep 2026 | Plzeň Trolleybus Peak Fleet.html |
cd pipeline/plzen-trolleybus/scripts
python run.py --state 2026-09-29
Python 3, standard library only. Built by session simutrans-timetable-a2 on 29 Sep 2026. Not published yet (the user reviews and publishes).
Imports, read only (never modified here):
../plzen/scripts/common.py(Plzeň tram pipeline, session simutrans-timetable-3a):fetch,gtfs_trips,cycle_need,runfit,best_offset,loop_shift.../brno-trolleybus/scripts/common.py:circuit_need,turnarounds,runfit_rate,mark_spares.- Page style:
../brno/assets/style.css.htmland../brno-trolleybus/assets/extra.css.html, plusassets/extra.css.htmlhere.
Sources
| What | URL | Stored in |
|---|---|---|
| Day overviews (which lines have records on which day; every car out that day) | https://seznam-autobusu.cz/vypravenost/mhd-plzen?datum=YYYY-MM-DD |
data/raw/vypravenost-days/ |
| Vehicle per kurz with notes, one list per line (trolleybus and bus lines) | https://seznam-autobusu.cz/vypravenost/mhd-plzen/vypis?datum=YYYY-MM-DD&linka=N |
data/raw/vypravenost/ |
| Line history (for designed vehicles) | …/mhd-plzen/vypis?linka=N&since=YYYY-MM-DD, pages &strana=N (50 records a page, newest first) |
data/raw/history/ |
| PMDP register (in service): trolleybuses, buses | https://seznam-autobusu.cz/seznam?iddopravce=71&trakce={trolejbus,autobus,elektrobus}&prov=1&vcetneSluzebnich=1&page=N |
data/raw/register/ |
| Timetable | https://jizdnirady.pmdp.cz/jr/gtfs (returns the zip directly). Trolleybus route_type 11, bus 3, tram 0. No shapes.txt, no blocks. The 29 Sep download is byte-identical to the tram pipeline's 28 Sep copy. |
data/raw/gtfs/2026-09-29/gtfs.zip |
| Overhead wire | Overpass: way["trolley_wire"="yes"] and way["railway"="trolleybus_wire"] in (49.68, 13.25, 49.80, 13.50), out geom; also the route=trolleybus relations (out of date, not used) |
data/raw/osm/2026-09-29/trolley_wire.json, trolleybus_routes.json |
| Battery-capable cars, battery stretches (cross-check) | cs.wikipedia: Škoda 26Tr, Škoda 27Tr, Trolejbusová doprava v Plzni | the state (battery_rules, diesel_rules, battery_text) |
| Pak objects | local pak128 checkouts (C:/Users/vojte/Developer/simutrans-custom-czech-pak128, -mhd), read only: no VZ-PMDP-trolleybus package exists |
assets/pak_map.json, pak_request.md |
- seznam-autobusu.cz: browser headers, 2 s between requests (
common.fetchfrom the tram pipeline). No personal data is sent. - Overpass answers 406 to a browser User-Agent:
01_fetch.py --osmsendssimutrans-timetable-pipeline/1.0andAccept: application/json. - Car ids are the key everywhere: PMDP trolleybus and bus numbers overlap (559 is a Škoda 26 Tr and a SOR NB 12). One register number carries a suffix (
634II); the parser keeps634.
Steps
01_fetch.py:--days,--vehicles,--lines … --history,--since --register trolejbus autobus,--operator(another operator's register, for subcontractors),--car,--gtfs,--osm.02_parse.py: per-line lists →vypravenost_; registers →.json vehicles_(by car id, with type, livery, garage, operator, year, state, traction); day overviews →.json day_counts.json; histories →history.json.03_timetable.py --state X [--base …]: network table, schedule fits and needs (see Decisions). Writes./data/derived/X/timetable.json 03b_offwire.py --state X: battery stretches per stop pattern (trolleybus only). Copied from../praha-trolleybus/scripts/03b_offwire.pyand changed from shape sampling to a per-stop test, because the PMDP GTFS has no shapes.04_fleet.py --state X [--base …]: afternoon vehicle per kurz, allocation to Simutrans lines, designed vehicles for shortfalls,mark_spares, and the battery check.04b_pak.py --state X [--base …]:assets/pak_map.jsonandpak_request.md.05_render.py --state X [--base …]: the HTML, into the project root.propose.py --route-type 11|3 --groups …(not inrun.py): the Brno bus helper, chaining trips FIFO to show which leg follows which. The circuits in the states come from its output.
Decisions
- Day. Vehicles from Fri 18 Sep 2026.
day_counts.json: 76–80 trolleybus and 124–130 bus records on every weekday 10–22 Sep, but 1 / 1 / 1 / 0 on 23 / 24 / 25 / 29 Sep (28 Sep was a holiday). 18 Sep is the latest complete Friday and the Plzeň tram sheet's day. Mon 21 and Tue 22 Sep are complete too (a fallback). Network: the GTFS service day Tue 29 Sep itself, because line 12 has a separate calendar from 1 Oct (every trip a minute later). - Lines. Every trolleybus route with afternoon service: 10, 11, 12, 13, 14, 15, 16, 18, 22, 49. seznam-autobusu.cz files 22 and 49 among the buses, but their cars are trolleybuses and the GTFS says route_type 11. 17 (3 trips in 15–18 h), 19 (none) and N7 are left out.
- Structure (from
propose.py):- 10 is one Simutrans line Tylova → Čechurov → Tylova → Černice (→ Tylova): the branches alternate (6 of 7, 4 of 6). Fitted every 24 per branch (
fit.overrides,auto= least-deviation offset), its real pattern; approximate, ±12 min. - 11 is one line Ústřední hřbitov → Křimice → Ústřední hřbitov → Malesice: the branches alternate (5 of 6 each way); exact every 30.
- 15N (Lobzy – Nová Hospoda) is a peak branch (4 + 3 trips in 15–18 h, a 16:xx departure, no depot): its own line, taking the highest 15 kurzy (11, 12). Its need is set to 2 in the state (
need, with the reason): the real branch trips wait almost an hour at Nová Hospoda, so the cycle gives 156 min. - 22 runs Malvíny → Koterov → Škoda VIII. brána in the 16:00 hour and returns empty to Malvíny (
empty_return, 5 min, a guess): no trip leaves Škoda VIII. brána after 15:22, and Koterov → Malvíny runs only outside the 16:00 hour. - 12 Letkov branch (5 trips a day, none 15–18 h) and 13 Černice short workings (2) are not peak trips, not modelled.
- Rates set in the state: 12 at 8 an hour, 13 at 5 (every 12, the real peak pattern). 22 Koterov fitted every 30 (
auto). - Hand-set 25 Oct 2026 (method check,
pipeline/brno/method-check-2026-10-25.md;fit.overrides, key): 12 every 15 with two slots at both ends (Nová Hospoda :00 :08, Božkov :00 :07; within 2 min of every 16:xx departure) and 16 Sídliště Bory every 6 (:00), replacing every-60 / every-45 / every-48 rows with 6–8 slots that matched the real minutes for one cycle only. A hand-set (not| | | auto) row that reproduces its first–last stretch exactly is shown as "partial, exact " (stretchin timetable.json; the Plzeň bus sheet uses it).
- 10 is one Simutrans line Tylova → Čechurov → Tylova → Černice (→ Tylova): the branches alternate (6 of 7, 4 of 6). Fitted every 24 per branch (
- Loop −1 everywhere (
all_loops), as on the other trolleybus sheets. - Line 18 (Škoda-shift line): three cars logged on 18 with no note also worked 10/6, 12/19 and 13/1. They are counted there (
fleet.secondary), and their 18 records are listed under Not counted. - Need = max(
circuit_needwith the timetable's own turnarounds, most on the road 16:00–16:59 per record line); the on-road rule adds one on 13, 16 and 22. Surplus logged →mark_spares(one of every type first; afternoon-only kurzy, then the highest kurz numbers dropped first; on a battery line a car without a battery goes first). On 18 Sep: 56 counted, 26 not needed, none short, none designed. - Battery sections. A stop more than 60 m from an OSM wire is off the wire (40 m put the CAN Husova terminus and a Tylova platform off the wire; 60 m matches Wikipedia's stretches). A lone terminus platform within 200 m of the wire is a turning loop. Results: 11 CAN Husova – Malesice / Křimice, 12 Božkov – Letkov (not modelled), 13 U Staré Kovárny – NC Černice, 22 Vodárna – Koterov, 49 U Práce – Areál FN. Wikipedia also lists 22 Tyršův most – Vodárna; OSM shows wire there.
- Battery-capable cars (
battery_rules): every Škoda 26 TrNU and 27 TrNU, and the Škoda 26 Tr 565–582. Auxiliary diesel (diesel_rules, shown but not battery): 26 Tr 551–552, 27 Tr 527–530 and 540. The check passes on 11, 13, 22 and 49. - Pak. No PMDP trolleybus objects exist, so all six types are "requested" in
VZ-PMDP-trolleybus:VZ-PMDP-, articulated-pmdpzelenobila- +(the Brno trolleybus convention). 26 Tr / 26 TrNU and 27 Tr / 27 TrNU are separate objects (Urbino III vs IV body). The request list is-B pak_request.md, for the user to send to the pak session (simutrans-custom-czech-pak128-bd). When the pak installs the objects,04b_pak.pyfinds the names in the checkout build and marks them installed.
How to update
python run.py --state 2026-09-29 --fetch: the day overviews of the last two weeks, the per-line lists of the state's vehicle day, the registers, the GTFS and the OSM wire, all dated today. It prints records per day (data/derived/day_counts.json).- Copy the state to
states/. Set.json vehicles_date(the latest complete weekday, preferably a Friday),register_date,gtfs_date,service_date,osm_date. Fetch the lists of the new day:python 01_fetch.py --vehicles.--lines 10 11 12 13 14 15 16 18 22 49 python 03_timetable.py --state: check the rates, the approximate entries andnot modelled. If a branch pattern changed, runpropose.py --route-type 11 --groups …and updatesimutrans_lines.python run.py --state. If a line is short,04_fleet.pydesigns vehicles fromdata/derived/history.json: fetch the line history first (01_fetch.py --history).--since - Update the texts (
texts,battery_text) for the new dates. Then do the bus sheet (../plzen-bus/README.md).