From 86ccbb05151dd3165dd0f1a7fcea804ea5013465 Mon Sep 17 00:00:00 2001 From: marvin Date: Sun, 13 Sep 2026 23:23:14 +0200 Subject: [PATCH] Per-mode stop clustering thresholds Rail stations get generous thresholds to merge all platform/entrance duplicates; bus stays conservative: metro: 200m -> 91 stops -> 44 markers (0 duplicates) s_tog: 400m -> 76 stops -> 30 markers (0 duplicates) regional: 500m -> 27 stops -> 9 markers (0 duplicates) bus: 100m -> 1610 stops -> 781 markers stop_cluster_m is now a dict keyed by mode in styling.yaml. --- copenhagen/config/styling.yaml | 6 +++++- copenhagen/scripts/render.py | 8 +++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/copenhagen/config/styling.yaml b/copenhagen/config/styling.yaml index e318b5c..da1276e 100644 --- a/copenhagen/config/styling.yaml +++ b/copenhagen/config/styling.yaml @@ -73,7 +73,11 @@ basemap: stations: show: true # draw station markers (symbols without text) styles: [metro, s_tog, regional, bus] - stop_cluster_m: 50 # merge same-name stops within this distance (opposite sides of road) + stop_cluster_m: # merge same-name stops within this distance (per mode) + metro: 200 # covers platform/entrance spread (~170m max) + s_tog: 400 # covers platform/entrance spread (~380m max) + regional: 500 # covers platform spread (~475m max) + bus: 100 # opposite sides of road, wide boulevards marker: shape: circle # circle | square fill: white diff --git a/copenhagen/scripts/render.py b/copenhagen/scripts/render.py index 79dd3ff..b48e202 100644 --- a/copenhagen/scripts/render.py +++ b/copenhagen/scripts/render.py @@ -196,7 +196,7 @@ def plot_stations(ax, stations, styling, active_styles): if not cfg.get("show", True): return marker_styles = set(cfg.get("styles", ["metro", "s_tog", "regional"])) - cluster_m = cfg.get("stop_cluster_m", 50) + cluster_cfg = cfg.get("stop_cluster_m", {}) mk = cfg.get("marker", {}) sizes = mk.get("size", {}) shape = mk.get("shape", "circle") @@ -220,11 +220,12 @@ def plot_stations(ax, stations, styling, active_styles): zord = styling["zorder"] top_z = max(zord.values()) + 1 # all markers above all lines for s in sorted(pts_by_style, key=lambda k: zord.get(k, 0)): + threshold = cluster_cfg.get(s, 50) if isinstance(cluster_cfg, dict) else cluster_cfg # cluster same-name stations to one marker; keep unnamed as-is centroids = [] for name, coords in names_by_style[s].items(): if name and len(coords) > 1: - centroids.extend(cluster_stops(coords, cluster_m)) + centroids.extend(cluster_stops(coords, threshold)) else: centroids.extend(coords) sz = sizes.get(s, 3.0) @@ -244,7 +245,8 @@ def plot_bus_stops(ax, stops, styling, active_styles): if bus.empty: return - cluster_m = cfg.get("stop_cluster_m", 50) + cluster_cfg = cfg.get("stop_cluster_m", {}) + cluster_m = cluster_cfg.get("bus", 50) if isinstance(cluster_cfg, dict) else cluster_cfg mk = cfg.get("marker", {}) sizes = mk.get("size", {}) sz = sizes.get("bus", 1.5)