Skip to content

Add least-cost corridor analysis to proximity module #965

@brendancol

Description

@brendancol

Author of Proposal:

Reason or Problem

The library has cost_distance (accumulated cost from sources) and A* pathfinding (least-cost path between two points), but no corridor analysis. Corridors identify zones of low cumulative cost between two locations. Unlike a single-cell path, a corridor shows all cells within a cost threshold of the optimal route.

The typical use case is connecting two habitat patches or protected areas through the cheapest terrain, but it's also used for infrastructure routing (roads, pipelines) and conservation land-parcel prioritization.

Proposal

Design:
A least-cost corridor is computed by summing two cost-distance surfaces (one from source A, one from source B) and normalizing by the minimum corridor cost. Cells where cost_A + cost_B - min_corridor <= threshold form the corridor.

The function builds on existing cost_distance:

corridor = cost_distance(cost_surface, source_a) + cost_distance(cost_surface, source_b)
corridor_normalized = corridor - corridor.min()

The implementation:

  • NumPy/CuPy: call cost_distance twice, add the results, subtract the minimum. Simple array arithmetic that all backends already handle.
  • Dask: cost_distance already has a Dask backend. Adding two Dask arrays and finding the min is native xarray/dask.
  • Dask+CuPy: same as Dask, dispatched through existing infrastructure.

New file: xrspatial/corridor.py

The function would also support multi-corridor analysis (N sources, pairwise corridors) and an optional width parameter that thresholds the normalized corridor surface into a binary mask.

Usage:

from xrspatial import least_cost_corridor

# basic corridor between two points
corridor = least_cost_corridor(cost_surface, source_a, source_b)

# binary corridor mask within 10% of optimal cost
mask = least_cost_corridor(cost_surface, source_a, source_b,
                           threshold=0.10, relative=True)

# multi-source corridor network
corridors = least_cost_corridor(cost_surface,
                                sources=[point_a, point_b, point_c],
                                pairwise=True)

Value: Corridor analysis is a standard GIS operation, available in ArcGIS Pro and QGIS. Since cost_distance already exists here, this function is mostly arithmetic on its output, so implementation cost is low.

Stakeholders and Impacts

Conservation biologists, transportation planners, landscape ecologists. Builds on existing cost_distance. No changes to existing code, just a new function that calls existing ones.

Drawbacks

  • Calls cost_distance twice, meaning two full Dijkstra passes. For large rasters this doubles the computation time. Caching is left to the user.
  • Corridor width is controlled by a cost threshold, not a physical distance. Users need to understand what "10% of optimal cost" means for their particular cost surface.

Alternatives

  • Users can compute corridors manually: cost_distance(A) + cost_distance(B). This function wraps that with normalization, thresholding, and multi-source support.
  • A* pathfinding plus a buffer around the resulting path. Gives a fixed-width corridor but ignores cost variation within the buffer.

Unresolved Questions

  • Should the function accept pre-computed cost-distance surfaces to avoid redundant computation?
  • Should threshold be absolute (cost units) or relative (fraction of minimum), or support both?
  • Should multi-source corridor output be a single combined surface or separate per-pair surfaces?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestproximity toolsProximity, allocation, direction, cost distance

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions