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.
This commit is contained in:
Claude 2026-07-14 05:55:32 +00:00
parent 8ea835e291
commit 3e3fc5ebc5
No known key found for this signature in database

View file

@ -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)