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
--osrm-urlflagDISTANCE_CLI_OSRM_URLenvironment variable- Probe
http://localhost:5000for a running local OSRM instance - Fall back to the public
router.project-osrm.orgdemo 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).
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.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file distance_calculation_cli-0.3.0.tar.gz.
File metadata
- Download URL: distance_calculation_cli-0.3.0.tar.gz
- Upload date:
- Size: 22.8 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c3e55621360f8fb7fa990d002061cf82fd658a1e5df2136cd3a7e4ad04d4e8c9
|
|
| MD5 |
7303f5c94b47633c3a29e744cf86e51a
|
|
| BLAKE2b-256 |
7fe247473bcb9707011f6a4b9b6e73abc3d4a7d122a113014a8845b2f3cbe105
|
File details
Details for the file distance_calculation_cli-0.3.0-py3-none-any.whl.
File metadata
- Download URL: distance_calculation_cli-0.3.0-py3-none-any.whl
- Upload date:
- Size: 29.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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
38ec179cc20a9b25ac835187d0fe1219fe472813caa937a377f120cc64d9ab9e
|
|
| MD5 |
02e4b91aeb7e6bcf50bdc0190a72d830
|
|
| BLAKE2b-256 |
8f0449b172770357531c597b72744c90c9701f284ea526e9b68ded45d376632e
|