From a16816bf73e886c94f40c078cf9b390d09f2422f Mon Sep 17 00:00:00 2001 From: marvin Date: Fri, 18 Sep 2026 00:24:37 +0200 Subject: [PATCH] Add bus whitelist, route exclusions, crow-fly shape filter, and KML export MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - modes.yaml: bus_whitelist (A-buses + selected refs) and exclude list (Snälltåget 083 night train — sparse crow-fly stubs) - prepare.py: drop degenerate crow-fly shapes below 0.05 pts/km; apply bus whitelist and route exclusions from modes.yaml - export_google_mymaps.py: new script — master.gpkg -> KML for Google My Maps import (stops, routes, boundary, coastline layers) - coastline.kml: reference coastline layer for the KML export - .gitignore: also ignore generated output/*.kml --- .gitignore | 3 +- copenhagen/config/coastline.kml | 251 ++++++++++++++++++++ copenhagen/config/modes.yaml | 17 ++ copenhagen/scripts/export_google_mymaps.py | 257 +++++++++++++++++++++ copenhagen/scripts/prepare.py | 87 ++++++- 5 files changed, 611 insertions(+), 4 deletions(-) create mode 100644 copenhagen/config/coastline.kml create mode 100644 copenhagen/scripts/export_google_mymaps.py diff --git a/.gitignore b/.gitignore index 7294790..a6690c8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,10 +4,11 @@ copenhagen/data/processed/** !copenhagen/data/raw/.gitkeep !copenhagen/data/processed/.gitkeep -# Generated map outputs (regenerable via render.py) +# Generated map outputs (regenerable via render.py / export_google_mymaps.py) copenhagen/output/*.png copenhagen/output/*.svg copenhagen/output/*.pdf +copenhagen/output/*.kml # Python .venv/ diff --git a/copenhagen/config/coastline.kml b/copenhagen/config/coastline.kml new file mode 100644 index 0000000..133cf61 --- /dev/null +++ b/copenhagen/config/coastline.kml @@ -0,0 +1,251 @@ + + + + Coastline (from Hide+Seek Copenhagen City Pass map) + + + normal + #line-01579B-3131-nodesc-normal + + + highlight + #line-01579B-3131-nodesc-highlight + + + + + + Coastline + + Coastline + #line-01579B-3131-nodesc + + 1 + + 12.5843171,55.7397957,0 + 12.5827293,55.7360025,0 + 12.5824718,55.7315324,0 + 12.5817422,55.731484,0 + 12.5813989,55.7304449,0 + 12.5821284,55.7290433,0 + 12.5866346,55.7285359,0 + 12.5878509,55.7274296,0 + 12.5895354,55.7273934,0 + 12.5903811,55.7271523,0 + 12.6023887,55.7256926,0 + 12.6158183,55.7206703,0 + 12.620303,55.7236674,0 + 12.6216977,55.7241629,0 + 12.6243907,55.7247369,0 + 12.6262897,55.7249967,0 + 12.6284247,55.7251719,0 + 12.6303022,55.7251779,0 + 12.6324909,55.7250873,0 + 12.6324695,55.7249665,0 + 12.637909,55.7230934,0 + 12.6386434,55.7218282,0 + 12.6177346,55.7122447,0 + 12.6173913,55.7123233,0 + 12.6116943,55.709694,0 + 12.6113267,55.7091432,0 + 12.6115091,55.7090676,0 + 12.6128441,55.7077879,0 + 12.612709,55.7073944,0 + 12.612709,55.7065058,0 + 12.61295,55.7056923,0 + 12.6132772,55.7049427,0 + 12.6128646,55.7039017,0 + 12.6146831,55.7036991,0 + 12.6153002,55.7030916,0 + 12.6146212,55.7020159,0 + 12.6161983,55.7016803,0 + 12.6164274,55.6978865,0 + 12.619534,55.6980419,0 + 12.6289389,55.6973909,0 + 12.6295397,55.6974605,0 + 12.6305757,55.6946383,0 + 12.6328654,55.6905452,0 + 12.6359244,55.6877876,0 + 12.6341066,55.6871202,0 + 12.6367352,55.6835607,0 + 12.6369351,55.6835927,0 + 12.6370405,55.6835331,0 + 12.6387568,55.6845909,0 + 12.6386816,55.6846722,0 + 12.6388157,55.6847159,0 + 12.6392421,55.6843356,0 + 12.6390959,55.684283,0 + 12.6388532,55.6844572,0 + 12.637179,55.6834458,0 + 12.6372853,55.6833646,0 + 12.6370415,55.6832048,0 + 12.6391502,55.6804415,0 + 12.6397198,55.6804556,0 + 12.6407945,55.6788023,0 + 12.6446818,55.6791733,0 + 12.6481294,55.6760777,0 + 12.6477002,55.6758901,0 + 12.6482367,55.6754545,0 + 12.6482152,55.6750794,0 + 12.6465406,55.6743208,0 + 12.6448562,55.6719189,0 + 12.6458325,55.6714712,0 + 12.6459398,55.6711989,0 + 12.6457537,55.6708966,0 + 12.6449598,55.6705669,0 + 12.6441852,55.6693045,0 + 12.6439062,55.6691804,0 + 12.6432464,55.6691078,0 + 12.6420252,55.6671961,0 + 12.6419078,55.6671067,0 + 12.6416769,55.6670523,0 + 12.639605,55.6655071,0 + 12.6396426,55.6652772,0 + 12.639571,55.6651256,0 + 12.6388107,55.6643574,0 + 12.6389868,55.6640928,0 + 12.6392577,55.6638084,0 + 12.6395473,55.6635557,0 + 12.6396974,55.6632324,0 + 12.6397753,55.6629964,0 + 12.6398423,55.6628557,0 + 12.6403183,55.6622263,0 + 12.6404072,55.6620556,0 + 12.6406298,55.6617788,0 + 12.6408639,55.661419,0 + 12.6409444,55.6613494,0 + 12.641049,55.6611951,0 + 12.641113,55.6611449,0 + 12.6415267,55.6606773,0 + 12.641626,55.6606054,0 + 12.6417306,55.6604957,0 + 12.641803,55.6604564,0 + 12.6422784,55.6599927,0 + 12.6423696,55.6599458,0 + 12.6427853,55.6595902,0 + 12.642856,55.6594981,0 + 12.6431243,55.659318,0 + 12.6436914,55.6588662,0 + 12.6438497,55.6587679,0 + 12.6444571,55.658322,0 + 12.6446935,55.658102,0 + 12.6448129,55.6580369,0 + 12.6450637,55.6578107,0 + 12.6452367,55.657732,0 + 12.6454375,55.6575592,0 + 12.6456441,55.6574465,0 + 12.6457118,55.657381,0 + 12.6459499,55.6572384,0 + 12.6464378,55.6568159,0 + 12.6469394,55.6565511,0 + 12.6473741,55.656235,0 + 12.6476763,55.6560435,0 + 12.6478747,55.6559391,0 + 12.6480178,55.6558298,0 + 12.6483299,55.6556358,0 + 12.6484803,55.6555661,0 + 12.648821,55.6554397,0 + 12.6492219,55.655188,0 + 12.649856,55.6547974,0 + 12.6500907,55.6547195,0 + 12.6504703,55.654637,0 + 12.6520371,55.6546291,0 + 12.6520451,55.6545564,0 + 12.6505229,55.6545288,0 + 12.6500079,55.6543775,0 + 12.6497504,55.6541565,0 + 12.6493642,55.6540082,0 + 12.6488855,55.6534695,0 + 12.6485422,55.6528339,0 + 12.6482847,55.6525433,0 + 12.6480272,55.652053,0 + 12.6481384,55.6512885,0 + 12.647838,55.6509979,0 + 12.6479453,55.6507679,0 + 12.6480847,55.6506529,0 + 12.6482242,55.6503804,0 + 12.6481906,55.649885,0 + 12.6482577,55.649549,0 + 12.6485414,55.6491014,0 + 12.6486309,55.6489064,0 + 12.6488052,55.6486401,0 + 12.6489045,55.6485477,0 + 12.6490386,55.648516,0 + 12.6491539,55.6484191,0 + 12.6502279,55.6483093,0 + 12.6504773,55.6482442,0 + 12.6506651,55.648161,0 + 12.6507885,55.6480263,0 + 12.6508232,55.6478915,0 + 12.6507293,55.6476554,0 + 12.6506341,55.6475652,0 + 12.650433,55.6474623,0 + 12.6502318,55.6474138,0 + 12.6499394,55.6474002,0 + 12.6485447,55.6475591,0 + 12.6483221,55.6473064,0 + 12.6480517,55.6467941,0 + 12.6479123,55.6463279,0 + 12.6478908,55.6459889,0 + 12.6481054,55.6455166,0 + 12.6484007,55.6451585,0 + 12.6485601,55.6447979,0 + 12.6488874,55.6444679,0 + 12.6500944,55.6444286,0 + 12.6505128,55.6443408,0 + 12.6507434,55.6441894,0 + 12.651591,55.6432419,0 + 12.6525459,55.6434296,0 + 12.6531499,55.6433718,0 + 12.6534396,55.643172,0 + 12.6549523,55.6415493,0 + 12.6548772,55.6413071,0 + 12.6533607,55.640507,0 + 12.6547246,55.6390978,0 + 12.6564626,55.6388799,0 + 12.6574282,55.6382682,0 + 12.6566614,55.6368416,0 + 12.6569832,55.6364147,0 + 12.657974,55.6358075,0 + 12.6578238,55.6355471,0 + 12.6568636,55.6353685,0 + 12.6570406,55.6350324,0 + 12.6568199,55.6344235,0 + 12.6570774,55.6340874,0 + 12.657882,55.6340419,0 + 12.6596845,55.6338481,0 + 12.661562,55.6338179,0 + 12.6637722,55.6339874,0 + 12.6649201,55.6340419,0 + 12.6671088,55.6340359,0 + 12.6694657,55.6338899,0 + 12.6714935,55.6336659,0 + 12.6735105,55.6333267,0 + 12.6766638,55.6325319,0 + 12.677919,55.6320049,0 + 12.6793996,55.6310904,0 + 12.6805918,55.6297217,0 + 12.6809995,55.6286073,0 + 12.6811927,55.6248094,0 + + + + + + \ No newline at end of file diff --git a/copenhagen/config/modes.yaml b/copenhagen/config/modes.yaml index 84d0f65..00151b8 100644 --- a/copenhagen/config/modes.yaml +++ b/copenhagen/config/modes.yaml @@ -13,6 +13,23 @@ # ORDER MATTERS: the styles listed here are also the priority order when a # pole is served by several modes (e.g. S-tog and regional trains share # platforms at hub stations — the higher style wins). +# Hard exclusions: specific routes to drop entirely, keyed by (agency, +# short name) — the pairing rule used everywhere else in this feed. +# 083 (Snälltåget night train, Malmö-Stockholm): its in-area shapes are +# sparse crow-fly stubs that draw as straight cuts across the map; the +# long-distance train is not relevant for the city game, so skip it. +# Bus whitelist: only these buses are included — there are far more city +# bus routes than the game scale needs. Match on bus category (per +# styling.yaml bus_filters) or on specific refs. Remove this section to +# include all buses; with empty lists no buses are included. +bus_whitelist: + categories: [A] # all "A" city buses (1A, 2A, 4A, 6A, 9A, ...) + refs: ["21", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "68", "77"] + +exclude: + - agency: Snälltåget AB + ref: "083" + modes: metro: agencies: [Metroselskabet] diff --git a/copenhagen/scripts/export_google_mymaps.py b/copenhagen/scripts/export_google_mymaps.py new file mode 100644 index 0000000..3ce8c05 --- /dev/null +++ b/copenhagen/scripts/export_google_mymaps.py @@ -0,0 +1,257 @@ +#!/usr/bin/env python3 +"""Export the master GeoPackage to a Google My Maps-importable KML. + +Reads (from data/processed): master.gpkg (lines, stops, stations), area.gpkg +Read (from config): coastline.kml — the coastline layer extracted verbatim +from the reference map +(https://www.google.com/maps/d/u/0/kml?mid=17T6ZDYbGz72h_eteL-CxdkiaXcgDLEA&forcekml=1) + +Writes: output/copenhagen-mymaps.kml + +My Maps turns each top-level KML Folder into a layer on import. We emit: + + Bus stops / Bus routes + Train stations / Train routes (metro + S-tog + light rail + regional) + Ferry stops / Ferry routes + City Pass boundary (outline + faint fill) + Coastline (verbatim from the reference map's layer) + +Colours match the PNG map: routes use colour_final from prepare.py; stop +icons use styling.yaml palette defaults (train stations match the reference +map's red pin). Import manually in Google My Maps: +Create map → Import → upload the .kml. +""" +import re +import sys +import xml.etree.ElementTree as ET + +import geopandas as gpd +import yaml + +from _common import CONFIG, OUTPUT, PROCESSED + +KML = "http://www.opengis.net/kml/2.2" +ET.register_namespace("", KML) + +# My Maps stock pin (same as the reference map uses); tinted via IconStyle. +ICON_HREF = "https://www.gstatic.com/mapspro/images/stock/503-wht-blank_maps.png" +ICON_SCALE = 1.0 + +TRAIN_STATION_COLOR = "#C2185B" # reference map's station-pin red +TRAIN_STYLES = ["metro", "s_tog", "light_rail", "regional"] + +# route line widths in pixels, per style +LINE_WIDTH = { + "metro": 4.5, + "s_tog": 4.25, + "light_rail": 4.25, + "regional": 3.5, + "ferry": 3.75, + "bus": 2.75, +} + +BOUNDARY_COLOR = "#006064" +BOUNDARY_LINE_WIDTH = 3.0 +BOUNDARY_FILL_ALPHA = 0x54 # ~33 % + + +class Styles: + """Registry of unique (kind, color, width) -> KML