Add mapbox isochrone - #44
Open
mattpodwysocki wants to merge 2 commits into
Open
mattpodwysocki wants to merge 2 commits into
mattpodwysocki wants to merge 2 commits into
Conversation
This was referenced Sep 23, 2026
Second of the Navigation-category APIs with no prior CLI coverage. Same shape as mapbox directions route (#43): hand-authored into custom-openapi/ since openapi-specs has no spec for this API either, and reuses that PR's fix for a spec parameter named `profile` colliding with the global --profile flag (ARG_NAME_OVERRIDES gets a second row, not a second mechanism). `contours_minutes` and `contours_meters` are mutually exclusive but neither is individually required by this CLI's own validation — same "not enforced before the request goes out" precedent search category already uses for its own proximity/near/bbox/route disjunction. The API answers 422 if both or neither are given. Smoke-tested against production: real contour polygons and linestrings for driving and walking profiles, --polygons, --contours-minutes with multiple values, verified to return the documented GeoJSON shape. Also fixes a self-inflicted --help regression found while writing this: first_sentence() in src/main.rs cuts a --help line at the first '.', and several profile-scoped parameter descriptions in directions.yaml (already merged in this branch) led with a complete sentence before the substantive content, e.g. "`mapbox/driving` only." — eating everything after it in --help. isochrone.yaml's own `denoise` had the same shape ("0.0-1.0: ...") and would have rendered as literally "0". Both fixed by moving the qualifier to the end of the description instead of the front. 485 tests, fmt and clippy clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Cascades the fix already shipped on mapbox directions: isochrone's API also has exactly one operation, so mapbox isochrone <args> replaces mapbox isochrone contours <args>, the same shape mapbox usage already has (spec::FLATTENED_SERVICES). And isochrone's own profile path parameter had the same closed four-value enum, which would reject an OEM account's undocumented profiles client-side; it's now free-form and reaches the URL unescaped via UNESCAPED_PATH_PARAMS, same mechanism as directions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
mattpodwysocki
force-pushed
the
feat/isochrone-api
branch
from
September 25, 2026 14:52
bd00deb to
16e44ed
Compare
mattpodwysocki
added a commit
that referenced
this pull request
Sep 25, 2026
Third of the Navigation-category APIs with no prior CLI coverage. Same shape as directions/isochrone (#43, #44): hand-authored into custom-openapi/ since openapi-specs has no spec for this API either, reusing ARG_NAME_OVERRIDES for the same profile-vs-global-flag collision (third row, not a third mechanism). Excludes POST, for the same documented reason directions route does: this spec format can't express "GET or POST, caller's choice" for one operationId, and the API's own POST exists specifically for a trace too long for a URL (~8100 bytes) — a real gap, not a design choice. Smoke-tested against production: a three-point San Francisco trace returned a real match with legs/steps/geometry, including a null tracepoint for a point too far from the road network to match — the documented shape for that case, not a bug. 486 tests, fmt and clippy clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.
This reuses the flattening mechanism (
spec::FLATTENED_SERVICES),ARG_NAME_OVERRIDES, and thepath_segment_for/UNESCAPED_PATH_PARAMSfix #43 introduces, since both APIs'
profilepath parameter hits thesame global-flag collision and the same free-form-profile requirement.
Once #43 merges, this should be retargeted to
main(gh pr edit --base main) rather than reviewed against it as a diff. Everything below isscoped to what this PR actually adds on top of #43.
What
mapbox isochrone, the second Navigation-category API with no prior CLIcoverage. Same shape as #43: hand-authored into
custom-openapi/sinceopenapi-specs publishes no spec for this API either.
No subcommand: like
mapbox directions, this API has one operation, sothere's nothing a second word (the old
contours) would disambiguate.Same shape
mapbox usagealready has.How far you can get from a point in a given time or distance, for driving
(with or without live traffic), walking, or cycling, as GeoJSON polygons
or linestrings.
contours_minutesandcontours_metersare mutually exclusive but neitheris individually required by this CLI's own validation, the same "not
enforced before the request goes out" precedent
search categoryalreadyuses for its own proximity/near/bbox/route disjunction. The API answers 422
if both or neither are given.
Routing profile is free-form here too
Same fix as #43: an earlier version of this command validated
profileagainst the four documented values client-side, via a clap enum. Some OEM
accounts have additional profiles that aren't published, so that
validation would have broken this command for exactly the accounts that
most need it.
profileis now sent exactly as typed, and reaches the URLunescaped through
UNESCAPED_PATH_PARAMS(("isochrone", "profile"))rather than relying on the enum-implies-safe assumption that stopped
holding once the enum came off.
Also included
A fix for a
--helpregression found while writing this, in code #43already merged into this branch:
first_sentence()insrc/main.rscuts a--helpline at the first., and eight parameter descriptions indirections.yamlled with a complete sentence before the substantivecontent (
`mapbox/driving` only.etc.), eating everything after it.isochrone.yaml's owndenoisehad the same shape (0.0-1.0: ...) andwould have rendered as literally
0. Fixed all nine by moving thequalifier to the end of the description instead of the front.
--schemaand
docs/commands.mdwere never affected, since they show descriptions infull.
Verification
Smoke-tested against production: real contour polygons and linestrings for
mapbox/drivingandmapbox/walking,--polygons, and--contours-minuteswith multiple values, all verified to return thedocumented GeoJSON shape, plus the bare
mapbox isochronecommand shapeitself (no subcommand accepted,
--schemareflects the new name).488 tests,
cargo fmt --checkandcargo clippy --all-targets -- -D warningsboth clean.🤖 Generated with Claude Code