Pure Go CLI for pavement data ingestion, hex-grid coverage analysis, PCI decay forecasting, and MapLibre visualization.
- No CGO — pure Go SQLite and geometry
- Single SQLite database, multi-city
- WASM interactive forecast in the browser
- Static site export or live server
Live showcase: https://joncrussell.com/solvent-streets/ — metro areas rendered from the configs in examples/, plus a 50-largest-US-cities national sample.
pvmt is not in any Linux distribution's package repositories. Pick one of the three options below.
Download the .deb for your architecture from the latest release, then install it:
sudo apt install ./pvmt_<version>_linux_amd64.deb
The package installs pvmt to /usr/bin and ships shell completions and manpages.
Download the tarball for your architecture from the latest release, extract it, and move the binary onto your PATH:
tar -xzf pvmt_<version>_linux_amd64.tar.gz
sudo mv pvmt /usr/local/bin/
Requires Go 1.26+ (see CONTRIBUTING.md for prerequisites).
git clone https://github.com/jcrussell/solvent-streets
cd solvent-streets
make build
The binary is written to the repo root; copy it onto your PATH as above.
Create pvmt.toml:
[[cities]]
name = "Alameda, CA"
overpass = trueLive view of a single resource:
pvmt roads ingest
pvmt roads compute
pvmt serve
Open http://localhost:8080.
Full pipeline — all resources, forecast, and a deployable static site:
pvmt all ingest
pvmt all compute
pvmt forecast
pvmt export -o ./site
./site is a self-contained folder you can deploy to GitHub Pages or any static host.
Use pvmt --help and pvmt <command> --help for full usage.
See examples/ for ready-to-use configs covering several US metro areas and a 50-largest-US-cities national sample.
| Document | Description |
|---|---|
| Architecture | Data pipeline, DI, geometry, schema, design decisions |
| Configuration | Config discovery, resolution, env vars, multi-city, forecast tuning |
| Troubleshooting | Common errors and remediation hints |
| CLI Reference | Per-subcommand reference generated from pvmt --help |
| Examples | Ready-to-use configs for several US metro areas and a 50-city national sample |
| Contributing | Prerequisites, build/test loop, commit-message style, issue tracking |
BSD-3-Clause. See LICENSE.
See CONTRIBUTING.md for prerequisites, the build/test/lint loop, and commit-message style.
Push a v* tag. GoReleaser builds Linux/macOS (amd64/arm64) and publishes to GitHub Releases.
The site at https://joncrussell.com/solvent-streets/ is a single consolidated dashboard: one pvmt export run from examples/all/, whose [[include]] blocks union every other example into one config (277 cities) and tag each one at the include site. Cities are browsed by tag rather than by example, and the Compare and Aggregate tabs can be scoped to a tag. See docs/configuration.md for tags and [[include]].
Ingest/compute/forecast cannot run in CI (the source SQLite DB is ~1 GB and Overpass/ArcGIS pulls are slow and rate-limited), so the publish runs from a developer machine that already has data in ~/.local/share/pvmt/pvmt.db. The combined config covers every example's cities, so they must all have data first — but it does not need its own ingest: a city reached through [[include]] keeps the identity of the file that declared it, so examples/all reads exactly the rows and snapshots each example's own ingest/compute wrote.
cd examples/<name> && pvmt all ingest && pvmt all compute # per example; hours, only when data is stale
make site # renders ./site/ from your local DB
make deploy # force-pushes ./site/ to the gh-pages branch
Running ingest or compute from examples/all is supported and writes into those same per-example namespaces — which means it replaces their data rather than sandboxing it. Prefer running per example unless you specifically mean to refresh everything.
GitHub Pages picks up the new commit on the next sync. The site auto-routes to /solvent-streets/ under the joncrussell.com CNAME owned by the user-pages repo.