Warszawa metro and tram stations — tram stops from the official ZTM GTFS #60
No reviewers
Labels
No labels
claude-wip
map-report
map:is
map:se
needs-review
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
art/ismap!60
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "night/issue-24-warsaw-stations"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #24
#24: Warszawa metro and tram stations — tram stops from the official ZTM GTFS
Warsaw finally has a stations layer. The source is the official ZTM Warszawa
GTFS (https://gtfs.ztm.waw.pl/last — the "always newest" feed on ZTM's own
server, Apache-2.0 terms, no credentials; announced on the Dane rozkładowe
page), fetched by the importer through a new
downloads:entry like anyother dataset — no curl, no manual download.
The feed covers tram stops only. Its route types are 0 (tram, 208 routes),
2 (rail — WKD/KM/SKM suburban lines) and 3 (bus); ZTM's public GTFS export
carries no metro routes, so Poland's
stationspartition has no metro rowsand the style's M icon stays unused for now. That is the honest, official
answer to the issue's metro ask: the M glyph exists and renders automatically
for any
mode='metro'feature, but there is no official metro stop source tofeed it yet. The extension paths (City of Warsaw API metro-entrances WFS with
a free key; the community-built mkuran.pl/gtfs/warsaw.zip) are documented in
the config and docs, not imported.
The commuter rail behind route type 2 is deliberately not imported either —
a scope decision, tracked as issue #63. The feed's 245 rail routes are
WKD/KM/SKM, reaching well beyond Warsaw across Mazovia, and the loader's
per-type
agencies:narrowing (the mechanism Sweden uses for pendeltåg)could scope them to SKM's S-lines without any style change — the J badge and
the
station_iconscommuter filter already exist. The config, country-polandand workstream-a all record this now, so the "available but not imported yet"
state is documented the same way metro's absence is.
Implementation follows the Sweden pattern: a GTFS staging table
(
pl_gtfs_stops,feature: stops, route_types [0]) and astationspartition of the shared map_stations tables. Two Warsaw-specific wrinkles:
per direction. The partition collapses same-named poles within 150 m
(ST_ClusterDBSCAN, partitioned by name) to the cluster centroid: 596 served
poles → 324 stop points. Without the collapse every przystanek would render
twice with two labels.
importanceis 1 for every stop (the tram rung, same as Sweden's), soWarsaw's stops appear from z12 — the same zoom Stockholm trams do. The
repeated names in the output (Rondo ONZ, Okopowa, …) are genuinely separate
przystanki on different streets, verified pairwise 280–600 m apart.
No style change was needed: tram stops render as the established purple-ringed
dot plus label (the style has badge icons only for metro M and commuter J —
the issue's "do trams have a standard icon?" answer is that the map's
convention is the dot, matching Stockholm).
Verified against the live DB: 324 station rows at z14 (all mode=tram, no NULL
geom/name/mode), partitions at every zoom z9–z14, decoded z14 tile
(9146/5394) carries 20 station features with name/mode/importance, real
browser render over CDP shows dots+labels at z12–z15 (z12: 229 dots; z11: 0 —
floor correct), local vision model confirms clean single rendering. make
build, go test ./... (importer, mapsrv) pass.
Docs: country-poland.md gains a Stations section; workstream-a.md gains the
GTFS row and drops the "only country without a stations partition" claim.
Review round (PR #60): cluster-comment attribution corrected, the metro
UNION-ALL note covers the staging
route_types:too, the freshness signal(Content-Length only) stated, and the commuter-rail deferral documented
everywhere (issue #63).
Review — #60 (Warszawa stations, issue #24)
Builds clean,
go vetandgo testpass (onlyTestDumpGlyphPNGfails, which cannotwrite
/tmp/glyph_g.pngin this sandbox and fails identically on every branch includingmain).A single commit on top of
origin/main, config and docs only, no Go changes — and the#51 review points were already folded in upstream (
a104f61), so this one reviews clean.Good to see it not stacked on the open generalization PRs.
I re-fetched the feed and every measurable claim in the body holds. From
https://gtfs.ztm.waw.pl/lasttoday:208 tram routes exactly as stated, no
route_type1, no M1/M2 under any type, and nofrequencies.txtin the archive where a metro service could be hiding. "ZTM's publicGTFS export carries no metro routes" is correct, and the absent
Last-Modifiedheaderis confirmed too. That is the honest answer to the issue's metro ask and it is the right
call to ship trams rather than reach for the community feed.
The DB agrees with the body as well:
pl_gtfs_stopsholds 596 poles across 260 distinctnames, collapsing to 324 station rows at z14 — and z12 324 / z11 0 / z9 0, so the
importance floor behaves.
gtfsModealready maps basic0 → tramand1 → metro(
importer/gtfs.go:359), so the "the day an official feed carries metro stops" claim isreal and needs no code.
The same feed already carries commuter rail, and the J badge is waiting for it
This is the one substantive gap. The body treats metro as the only missing mode and
documents two extension paths for it, but says nothing about
route_type2 — the 245suburban rail routes it names in passing as "WKD/KM/SKM". Those map to an existing mode
and an existing sprite with no style change at all:
commuteris already in that filter, the J sprite already exists, and Sweden alreadypopulates it (
se|commuter|3|30,se|commuter|2|25). So Warsaw's commuter stops are oneroute_types: [0, 2]away plus acommuterbranch in the query — the data is alreadydownloaded and staged.
It also fixes a gap this PR leaves behind. Poland's z9–z11 station levels are empty
(verified above), because every tram stop is importance 1. Sweden fills those levels with
metro and commuter. Once #57 lands and Warsaw's tram lines chain down to z9, Poland will
render transit lines at z9–z11 with no stations on them at all, where Stockholm shows both.
Commuter stops at importance 2/3 are exactly what fills that band.
One caveat that makes this a follow-up rather than a one-liner: 245 KM/RE routes reach well
beyond Warsaw across Mazovia, so importing them wholesale would scatter stations over a much
larger area than "Warszawa stations". The loader already supports the per-type
agencies:narrowing that Sweden uses for the same problem (
importer/gtfs.go:166, 206), so themechanism exists — it just needs a decision about how far out the map wants to go.
At minimum the config comment and
docs/workstream-a.mdshould say that commuter rail isavailable in the feed and deliberately not imported yet, the same way metro's absence is
documented. Right now workstream-a's Poland work list mentions only that a metro source
"would light up the style's M icon" and does not mention that the J icon could be lit up
from a file already on disk.
Smaller notes
in different towns can never merge". That attributes the guarantee to the wrong half of
the expression:
PARTITION BY nameis what stops differently-named poles merging, andthe 150 m eps is what keeps two same-named groups apart. Both are load-bearing and the
behaviour is right — the sentence just explains the wrong one.
staging entry's
route_types: [0]would need the new type too, otherwise the rows neverreach the query.
Last-Modified(Iconfirmed that). "A new timetable re-downloads on the next import" is therefore true only
when the byte count changes — effectively certain at 47 MB, but worth the half-sentence
since the sidecar's usual two-signal contract is documented elsewhere.
WHERE mode = 'tram'in theservedCTE is redundant givenroute_types: [0]. Harmlessand arguably good defensive practice if the staging entry ever grows a type; no change
needed, just noting it is not doing anything today.
the right check to run — that is the one thing the 150 m cluster could plausibly have got
wrong, and it is good that it is recorded.
All review items addressed on the branch (
ed067ca, pushed).Commuter rail (the substantive gap) — not imported, but now documented as deliberately deferred, with the scope question filed as issue #63. The config's
pl_gtfs_stopscomment andstationscomment, country-poland.md and workstream-a.md all record that the feed's route type 2 (245 routes of WKD/KM/SKM) is available, that the loader'sagencies:narrowing can scope it to SKM's S-lines (agency_id 2 — the S1–S4/S40 routes filed under ZTM itself), and that the J badge +station_iconscommuter filter already exist, so no style change would be needed. The PR body now says the same, replacing the "metro is the only missing mode" framing. Issue #63 carries the concrete implementation path for when the reach question is settled.Smaller notes — all fixed in conf/plmap.yaml, or left as advised:
PARTITION BY namestops differently-named poles merging; the 150 m eps keeps same-named groups apart;route_types:must gain the new type too, or the rows never reach the query;WHERE mode = 'tram'in theservedCTE: left as-is per your note — harmless defensive practice.Config/docs only, no Go changes, so no reimport and the live tables are untouched.