From e11a6062d11f490bf8f5340efbdb4712f64885af Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Jul 2026 22:26:11 +0000 Subject: [PATCH] Index long rural road segments instead of dropping them The route-speed spatial index skipped any OSM way segment whose bounding box spanned more than 8 cells (~3.5 km). Sparsely-noded rural highways can legitimately run much farther between geometry nodes, so those stretches were dropped from the index and silently fell back to average route pacing instead of their real speed limit. Raise the guard to 128 cells (~57 km at the equator), which still catches genuinely broken data such as antimeridian jumps (~90,000 cells) while keeping realistic long segments in the index. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_013DNqCsHShA4yNqgZ6ZZQy3 --- StikDebug/Views/MapSelectionView.swift | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/StikDebug/Views/MapSelectionView.swift b/StikDebug/Views/MapSelectionView.swift index 54f9009..d4f54f7 100644 --- a/StikDebug/Views/MapSelectionView.swift +++ b/StikDebug/Views/MapSelectionView.swift @@ -579,10 +579,16 @@ private struct RouteSpeedIndex { let maxX = Int(floor(max(wayStart.longitude, wayEnd.longitude) / cellSize)) let minY = Int(floor(min(wayStart.latitude, wayEnd.latitude) / cellSize)) let maxY = Int(floor(max(wayStart.latitude, wayEnd.latitude) / cellSize)) - // A real road segment spans at most a couple of cells; a huge - // span means broken data (e.g. antimeridian jump) — skip it - // rather than flooding the index. - guard maxX - minX <= 8, maxY - minY <= 8 else { continue } + // Most road segments span a cell or two, but sparsely-noded + // rural highways can legitimately run tens of km between OSM + // geometry points, so allow a generous span (~57 km at the + // equator). Anything larger is broken data — e.g. an + // antimeridian jump spans ~90,000 cells — and is skipped rather + // than flooding the index. The earlier ≤8-cell cap (~3.5 km) + // silently dropped those long segments, so those stretches lost + // their real speed limit and fell back to average pacing. + let maxCellSpan = 128 + guard maxX - minX <= maxCellSpan, maxY - minY <= maxCellSpan else { continue } for x in minX...maxX { for y in minY...maxY { waySegments[SpatialCellKey(x: x, y: y), default: []].append(segment)