Preserve OSM one-way direction during generation - #105
Open
FrogAi wants to merge 1 commit into
Open
Conversation
FrogAi
force-pushed
the
codex/preserve-one-way-generation
branch
from
August 10, 2026 03:03
a249fc9 to
c8769f6
Compare
FrogAi
force-pushed
the
codex/preserve-one-way-generation
branch
from
August 10, 2026 03:21
c8769f6 to
def5848
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Developer summary
Offline generation currently treats only the literal
oneway=yesas one-way. That loses fixed reverse direction (-1), legacy1, and the standard roundabout/motorway implications. Because the stored format represents direction as a Boolean plus node order, simply marking-1true would invert the permitted direction and its directional speed metadata.This canonicalizes supported fixed directions during generation: reverse ways are stored in the permitted order with both forward/backward speed pairs swapped. It also resolves the repeated-endpoint ambiguity for closed one-way ways. No schema change is needed.
Verification
yes,1,-1,no,0, missing tags, explicit overrides, roundabout/motorway inference, non-inferred lookalikes, both directional speed pairs, and open/closed runtime classification.Compatibility
IDs, boxes, non-directional metadata, schemas, settings, and APIs are unchanged. Existing tiles are not rewritten; corrected behavior appears after regeneration. Dynamic/conditional/mode-specific direction remains outside this fixed-direction representation.
Engineering record and audit trail
Root cause
Current generation sets
OneWayonly when the raw OSM value is exactlyyes, then copies source node order and directional speed fields unchanged. Runtime treats stored-forward as the permitted direction whenever the Boolean is true.That representation cannot store
oneway=-1directly: traffic is permitted opposite the source node order. Canonicalizing it requires reversing the stored nodes and moving every direction-dependent value with the real travel direction. Otherwise runtime would reject the legal direction and select the wrong forward/backward speed fields.Closed OSM ways repeat their first node at the end. The existing endpoint check therefore classifies a closed way at that shared junction as backward. Once a closed roundabout is correctly marked one-way, ordinary direction checks would reject its stored-forward direction.
Implementation
yesand legacy1remain in source order and are stored one-way.-1is stored one-way with reversed nodes, swapped numeric forward/backward speeds, and swapped forward/backward conditional strings.onewayvalue implies forward direction only forjunction=roundaboutandhighway=motorway.no,0,reversible, andalternatingsuppress those implications.IsForwardFromtreats a closed one-way match at its exact repeated endpoint as stored-forward.Generator behavior
oneway=yesoneway=1oneway=-1onewaynoor0on implied featuresjunction=circularName, ref, hazard, lanes, ID, highway class, bounding box, general speed, advisory speed, and general conditional speed remain unchanged.
Runtime direction classification
The closed-way branch uses the exact repeated endpoints already used by matching; it does not add interior-node roundabout connectivity.
Evidence
The implementation boundary follows the current OSM Wiki documentation for
oneway, closed ways,motorway_link, andjunction=circular: fixedyes/no/-1, deprecated1/0, ordered closed geometry, and the limited roundabout/motorway implication boundary.The external candidate matrix executes the production normalization helper and generated
offline.Wayruntime accessor. It passes 100 repetitions, followed by:go test ./...go test -race ./...go vet ./...go build ./...git diff --checkRollout and scope limits
The offline Cap'n Proto schema remains wire-compatible, but generator and runtime behavior are version-coupled for closed ways. Deploy the runtime before distributing regenerated tiles to older clients. Existing tiles remain unchanged until regenerated.
This does not implement reversible, alternating, conditional, or mode-specific restrictions; infer motorway links; add interior roundabout connections; validate turn-restriction relations; or measure production prevalence. Current main's separate legal-candidate fallback correction is unchanged by this diff.