diff --git a/data/stops_at.csv.gz b/data/stops_at.csv.gz index 1fc2bb2..03bfef0 100644 Binary files a/data/stops_at.csv.gz and b/data/stops_at.csv.gz differ diff --git a/models.py b/models.py index caebe87..e9e1d08 100644 --- a/models.py +++ b/models.py @@ -57,7 +57,8 @@ class Stop(db.Model): longitude = db.Column(db.Float, nullable=False) # ";"-joined line refs serving this stop (e.g. "693" or "S2;U4;WLB"), from # OSM route relations; empty when unknown. Used by the "Linie" autocomplete. - lines = db.Column(db.String(255), nullable=False, default="") + # Text, not String(n): big interchanges (Linz Hbf) exceed a few hundred chars. + lines = db.Column(db.Text, nullable=False, default="") def line_list(self) -> list[str]: return [ref for ref in self.lines.split(";") if ref] diff --git a/scripts/fetch_stops.py b/scripts/fetch_stops.py index 9e59a0d..13060c0 100644 --- a/scripts/fetch_stops.py +++ b/scripts/fetch_stops.py @@ -17,6 +17,7 @@ import csv import gzip import json import math +import re import sys import time import unicodedata @@ -227,12 +228,17 @@ def fetch_route_members() -> tuple[list[tuple[str, int]], dict[int, tuple[str, f if el["id"] in seen_rel: continue seen_rel.add(el["id"]) - ref = (el.get("tags", {}).get("ref") or "").strip() - if not ref: + # A few relations pack several numbers into one ref ("407, 413"). + refs = [r.strip() for r in re.split(r"[;,]", el["tags"]["ref"]) if r.strip()] + if not refs: continue - for m in el.get("members", []): - if m["type"] == "node" and m["role"] in STOP_ROLES: - ref_members.append((ref, m["ref"])) + members = [ + m["ref"] for m in el.get("members", []) + if m["type"] == "node" and m["role"] in STOP_ROLES + ] + for ref in refs: + for node_id in members: + ref_members.append((ref, node_id)) del payload print(f" {len(seen_rel)} routes, {len(ref_members)} stop memberships", file=sys.stderr)