Anisotropic least-cost path, corridor (LCC), From-Everywhere-To-Everywhere (FETE), stochastic (probabilistic) paths and Path Deviation Index (PDI) validation for QGIS — built for archaeological movement modelling.
No external pip packages required: the numerics use numpy and scipy, both bundled with QGIS. Raster I/O uses GDAL (also bundled).
| Component | Form | Status |
|---|---|---|
| Slope cost surface (accumulated) | Processing | working |
| Friction cost surface (accumulated) | Processing | working |
| Least-cost path | Processing | working |
| Stochastic LCP (probabilistic corridor) | Processing | working |
| Least-cost corridor (LCC) | Processing | working |
| FETE | Processing | working |
| PDI validation | Processing | working |
| Resample DEM (block mean) | Processing | working |
| Interactive two-click LCP | Toolbar tool | working (cost fn + neighbourhood selectable) |
Each cell becomes a graph node; edges connect neighbouring cells (4/8/16).
Edge weight is a directional cost function (slope = rise/run signed by
travel direction), so the conductance matrix is asymmetric = true
anisotropy. Paths are solved with scipy.sparse.csgraph.dijkstra.
- Corridor: sum of two accumulated surfaces — one from the origin, one from the destination grown on the reversed graph (correct for anisotropy).
- FETE: all pairwise LCPs, traversal frequency per cell (White & Barber 2012). Cost scales ~O(n²) in the number of points.
- PDI: area between modelled and reference polyline / reference length = mean deviation in map units.
- Friction: a cost-per-metre raster (vegetation, wadis, geology) drives the surface directly (isotropic), or — with an optional DEM — acts as a dimensionless multiplier on the anisotropic slope cost (combined mode).
- Barrier / multiplier: an optional raster on the slope-based algorithms (slope cost surface, LCP, LCC, FETE) scales edge cost by the mean of its two cells (>1 discourages, <1 prefers known roads); NoData/≤0 cells are impassable (cliffs, deep wadis).
- Stochastic LCP (Lewis 2021): N Monte-Carlo realisations adding a spatially-correlated DEM error (RMSE-scaled) and/or randomly dropping edges, accumulating how often each cell lies on the least-cost path → a probabilistic corridor in [0, 1]. Set a seed for reproducibility.
Cost functions included: Tobler (on/off-path), Herzog, Naismith, Llobera &
Sluckin. Add your own in core/cost_functions.py and register it in the
COST_FUNCTIONS dict + labels list.
- User manual — concepts, per-algorithm guide with parameters, a worked example, performance/memory notes and troubleshooting.
- References / references.bib — the literature behind each cost function and method.
- Python library — the GUI-free numerics are also on PyPI
(
pip install itinera); seeREADME-pypi.md.
- Zip the
itinerafolder (or use the provided zip). - QGIS → Plugins → Manage and Install Plugins → Install from ZIP.
- Enable Itinera – Least-Cost Pathways.
- Algorithms appear in the Processing Toolbox under Itinera – Least-Cost Pathways. The interactive tool and its settings appear as two buttons on the Plugins toolbar (View → Toolbars → Plugins Toolbar if it's hidden) and also under Plugins → Itinera.
Requires QGIS ≥ 3.28 and runs on QGIS 4.0 (Qt6) as well — Qt access goes
through the qgis.PyQt compatibility layer. Use a projected CRS in metres
(e.g. EPSG:32637 / EPSG:28191) for DEM and points so slope and distance are
metric.
The GUI-free core/ numerics have a pytest suite that runs outside QGIS (no
qgis/GDAL needed):
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
pytestIt gates on the project invariants — the conductance matrix stays asymmetric,
edge/path costs are finite and positive, friction-only surfaces are symmetric,
and the corridor's transpose contract holds. CI runs the same suite
(.github/workflows/tests.yml).
- The interactive map tool's cost function and neighbourhood are set via the "Interactive LCP settings…" button on the Plugins toolbar (or Plugins → Itinera); defaults are Tobler, 8-neighbour.
- The full conductance matrix is held in memory (~
cells × neighboursedges). The graph algorithms warn above ~4M cells; for very large DEMs, clip or run Resample DEM (block mean) first (cuts cells byfactor²). A true tiled builder with cross-tile path stitching is out of scope for now. - 16-neighbour reduces grid metric distortion but quadruples edge count.
- FETE on many points is expensive; start small.
The original roadmap is complete. Possible future directions — built as needed and in response to user feedback, not committed milestones:
- a true tiled conductance builder with cross-tile path stitching (for DEMs too large to hold in memory);
- a FETE-style stochastic network (probabilistic all-pairs corridors);
- additional cost functions.
Have a use case that needs one of these, or something else? Please open an issue — priorities follow demand.
Versions follow Semantic Versioning; metadata.txt
version= is the single source of truth. Release notes live in
CHANGELOG.md.
Licensed under the MIT License — see LICENSE.