Skip to main content

distance-calculation-cli

Compute drive distance and drive time between US addresses, one pair at a time or in bulk from a CSV of origin/destination pairs.

  • Geocoding: US Census Geocoder (free, keyless, TIGER-based), with OpenStreetMap Nominatim as a fallback for addresses Census can't match.
  • Routing: OSRM — the public demo server by default (politely throttled), or a self-hosted local containerized OSRM instance for large batch jobs.

Quickstart

uvx distance-calculation-cli "1 Campus Martius, Detroit, MI" "300 Ottawa Ave NW, Grand Rapids, MI"
Routing via: https://router.project-osrm.org (public demo server, throttled)
Origin matched: 1 CAMPUS MARTIUS, DETROIT, MI, 48226
Destination matched: 300 OTTAWA AVE NW, GRAND RAPIDS, MI, 49503
Distance: 157.5 miles
Drive time: 2h 56m

Batch mode:

uvx distance-calculation-cli --csv addresses.csv -o results.csv

Installation

uv tool install distance-calculation-cli
# or, one-off:
uvx distance-calculation-cli ...

CSV format

Input CSV must have (at minimum) an origin and destination address column, named origin_address / destination_address by default (override with --origin-col / --destination-col):

origin_address destination_address
1 Campus Martius, Detroit, MI 300 Ottawa Ave NW, Grand Rapids, MI
2 Woodward Ave, Detroit, MI 124 W Michigan Ave, Lansing, MI

Any other input columns are preserved as-is. The output CSV adds:

column meaning
matched_origin_address Address as matched by the geocoder
origin_lat, origin_lon Geocoded origin coordinates
matched_destination_address Address as matched by the geocoder
destination_lat, destination_lon Geocoded destination coordinates
distance_miles Drive distance
drive_time_minutes Drive time
status See status reference below
error_detail Human-readable failure reason, if any
routing_server OSRM server used for this row

Rows are written incrementally as they complete (crash-safe, bounded memory), with a progress bar when running in a terminal. Failed rows are flagged, never dropped.

Status reference

status meaning
ok Geocoded and routed successfully
geocode_failed_origin Could not geocode the origin address
geocode_failed_destination Could not geocode the destination address
geocode_failed_both Could not geocode either address
route_failed Both addresses geocoded, but OSRM found no route
invalid_input_row Row was missing an origin or destination value

Options

option env var default meaning
--osrm-url DISTANCE_CLI_OSRM_URL (auto-resolved) OSRM server to route against
--osrm-rps (server-dependent) Override the OSRM requests/second cap
--geocoder-url DISTANCE_CLI_GEOCODER_URL (auto-resolved) Self-hosted Nominatim to use as the primary geocoder
--no-throttle off Disable OSRM rate limiting entirely
--concurrency 20 Max concurrent geocode/route requests
--origin-col / --destination-col origin_address / destination_address CSV column names
--units miles miles or km
--no-fallback off Disable the Nominatim fallback geocoder
--nominatim-user-agent DISTANCE_CLI_NOMINATIM_UA Required to enable Nominatim fallback
--retries 3 Retry attempts for transient errors
--timeout 15s Per-request timeout
--cache-dir Enable a persistent SQLite geocode cache (90-day TTL)
--dry-run off Parse + dedupe the input only; no network calls
--resume off Skip rows already ok in an existing output file
--public off Force the public OSRM server even if local OSRM is running
--no-probe off Skip probing for local OSRM/Nominatim instances
--yes off Skip confirmation prompts (for scripts)

Routing server resolution order

  1. --osrm-url flag
  2. DISTANCE_CLI_OSRM_URL environment variable
  3. Probe http://localhost:5000 for a running local OSRM instance
  4. Fall back to the public router.project-osrm.org demo server

A loopback server is used unthrottled; the public server is capped at 1 request/second; any other custom URL is throttled by default (use --no-throttle if you know it can take more). The CLI prints which server it's using at startup, e.g. Routing via: http://localhost:5000 (local OSRM, unthrottled).

Agent skill (Claude Code)

To teach a coding agent how to drive this CLI — command reference, server resolution behavior, resource requirements, and common failure modes — install the bundled skill:

distance-calculation-cli skill install            # ~/.claude/skills (all sessions)
distance-calculation-cli skill install --project  # ./.claude/skills (this repo only)
distance-calculation-cli skill show               # preview the content
distance-calculation-cli skill uninstall

New Claude Code sessions pick the skill up automatically; use --force to overwrite after upgrading the CLI.

Rate-limit etiquette

The Census geocoder and the public OSRM demo server are free, shared, keyless services — please be a good citizen. For a few one-off lookups the defaults are fine. For tens of thousands of pairs, run a local OSRM instance (see below) and consider a --cache-dir for geocoding.

Nominatim's usage policy requires a descriptive User-Agent identifying your application; without one (--nominatim-user-agent or DISTANCE_CLI_NOMINATIM_UA), the Nominatim fallback is disabled and a warning is printed — Census-only results still work, just with a lower match rate.

Local OSRM (for large batches)

For workloads of tens of thousands of pairs, run OSRM locally instead of hammering the public server:

distance-calculation-cli osrm setup us/michigan   # download + process (one-time)
distance-calculation-cli osrm start us/michigan   # runs osrm-routed in a container
distance-calculation-cli "..." "..."              # auto-detects localhost:5000
distance-calculation-cli osrm status
distance-calculation-cli osrm stop

REGION is a Geofabrik path fragment, e.g. us/michigan. Michigan is a good first example — small, fast to process. us-latest (the whole US) needs 64GB+ of RAM to process and requires --yes to proceed. Requires a container engine — Podman is preferred if installed, otherwise Docker (override with --engine or DISTANCE_CLI_CONTAINER_ENGINE). Data is stored under ~/.local/share/distance-calculation-cli/osrm/.

Once a local OSRM instance is running, it's auto-detected via a health probe of localhost:5000 — no extra flags needed.

Local geocoding (fully offline batches)

Routing locally removes one bottleneck, but geocoding still runs at 1–5 requests/second against shared public services. To go fully local, run a self-hosted Nominatim for the same region:

distance-calculation-cli geocoder start us/michigan  # first start imports the data
distance-calculation-cli "..." "..."                 # auto-detects localhost:8080
distance-calculation-cli geocoder status
distance-calculation-cli geocoder stop               # imported data is kept
distance-calculation-cli geocoder purge us/michigan  # delete the imported data

The region's .osm.pbf download is shared with osrm setup. On the first start, Nominatim imports the extract into PostgreSQL inside the container — for a state-sized region this takes 15–60+ minutes, needs 8GB+ of RAM, and uses ~10–20GB of disk (kept in a named container volume so later starts are fast). Progress and the current import stage are shown while it runs.

When a local Nominatim is running (or --geocoder-url / DISTANCE_CLI_GEOCODER_URL points at one), it becomes the primary geocoder, unthrottled, with the Census geocoder as fallback — no User-Agent required. Resolution order mirrors routing: flag → env var → probe localhost:8080 → default Census-first behavior.

Note that OSM address coverage is thinner than the Census TIGER data in some US areas; keeping the Census fallback (the default) gives the best match rate.

Geocode-only mode

To resolve addresses to coordinates without routing:

distance-calculation-cli geocode "800 W Main St, Midland, MI"
distance-calculation-cli geocode "800 W Main St, Midland, MI" --json
distance-calculation-cli geocode --csv addresses.csv -o geocoded.csv

Batch mode reads an address column (override with --address-col), dedupes, and writes the input columns plus status, matched_address, lat, lon, and source. It uses the same geocoder resolution as the distance command (local Nominatim auto-detected, Census otherwise, same --cache-dir cache) and exits nonzero if any address failed.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

distance_calculation_cli-0.5.0.tar.gz (27.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

distance_calculation_cli-0.5.0-py3-none-any.whl (35.6 kB view details)

Uploaded Python 3

File details

Details for the file distance_calculation_cli-0.5.0.tar.gz.

File metadata

  • Download URL: distance_calculation_cli-0.5.0.tar.gz
  • Upload date:
  • Size: 27.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for distance_calculation_cli-0.5.0.tar.gz
Algorithm Hash digest
SHA256 53a39c5bf918b8338929660ae792cd4bd857db81ca310b78e3aea7d3ef0cf9c1
MD5 a1111f707d4310897a3c83f3744e26d7
BLAKE2b-256 d65a34b520058495ac91bfed0cdc684f050f145614f5313e3208e5889f296629

See more details on using hashes here.

File details

Details for the file distance_calculation_cli-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: distance_calculation_cli-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 35.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for distance_calculation_cli-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9c3fd52cc5eea304f769be6b3028641a6cca93c0c245bc60451d8bf586e1c15f
MD5 54f3b4d63da0b5e0c1b61b737b22a3cb
BLAKE2b-256 659d74ad74f0b5d74624d51c8dd65fca16d9c4b8a06756bc9f66f85a6a3a42b3

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 files

0.4.0

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page