From 3e3fc5ebc56a312ce21da2638270f1fe479897da Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Jul 2026 05:55:32 +0000 Subject: [PATCH] Catch bus stops mapped with the public_transport schema Previously only OSM nodes tagged highway=bus_stop were fetched and drawn, which misses most stops in regions that use the newer public_transport schema (platform / stop_position with bus=yes). Query and decode all of these tag combinations so bus mode surfaces the full set of stops instead of the sparse few tagged the legacy way. --- StikDebug/Views/MapSelectionView.swift | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/StikDebug/Views/MapSelectionView.swift b/StikDebug/Views/MapSelectionView.swift index 7cede05..deeab33 100644 --- a/StikDebug/Views/MapSelectionView.swift +++ b/StikDebug/Views/MapSelectionView.swift @@ -373,7 +373,16 @@ private func overpassQuery(for coordinates: [CLLocationCoordinate2D], includeBus let bbox = String(format: "%.6f,%.6f,%.6f,%.6f", south, west, north, east) - let busStopClause = includeBusStops ? "\n node(\(bbox))[highway=bus_stop];" : "" + // Bus stops are mapped inconsistently in OSM: the legacy `highway=bus_stop` + // tag, and the newer public_transport schema (platform / stop_position with + // `bus=yes`). Query all of them so we don't miss most stops in areas that use + // the modern tagging. + let busStopClause = includeBusStops ? """ + + node(\(bbox))[highway=bus_stop]; + node(\(bbox))[public_transport=platform][bus=yes]; + node(\(bbox))[public_transport=stop_position][bus=yes]; + """ : "" return """ [out:json][timeout:20]; @@ -386,6 +395,17 @@ private func overpassQuery(for coordinates: [CLLocationCoordinate2D], includeBus """ } +private func tagsDescribeBusStop(_ tags: [String: String]) -> Bool { + if tags["highway"] == "bus_stop" { + return true + } + let publicTransport = tags["public_transport"] + if publicTransport == "platform" || publicTransport == "stop_position" { + return tags["bus"] == "yes" + } + return false +} + private func fetchRouteSpeedContext( for coordinates: [CLLocationCoordinate2D], includeBusStops: Bool @@ -427,7 +447,8 @@ private func fetchRouteSpeedContext( let busStops: [CLLocationCoordinate2D] = decoded.elements.compactMap { element in guard let lat = element.lat, let lon = element.lon, - element.tags?["highway"] == "bus_stop" else { + let tags = element.tags, + tagsDescribeBusStop(tags) else { return nil } return CLLocationCoordinate2D(latitude: lat, longitude: lon)