Skip to content

Grid distances

Distances and routes over a raster seen as a graph of neighbouring cells: each connection between two cells carries a conductance (how easily something moves from one to the other), from which come cost surfaces, least-cost distances and paths, and the distances and flows of random walks. They live in the ls.cost module.

The results are those of the R package gdistance, value for value: the connections are built with R's arithmetic, and on longitude/latitude grids the distances between cells are the ellipsoidal ones of the R package raster, to the last bit. Tutorial: routes on grids.

import numpy as np
import landschaft as ls

dem = ls.load_raster(ls.cost.example_data("maungawhau"))
slope = ls.cost.geo_correction(ls.cost.transition(dem, "diff", 8, symmetric=False))
speed = slope.map(lambda s: 6 * np.exp(-3.5 * np.abs(s + 0.05)), pairs="all")  # Tobler, m/s
conductance = ls.cost.geo_correction(speed)                                    # 1 / seconds per step

Transitions

transition

transition(
    x,
    function: str | Callable = "mean",
    directions: int = 8,
    symmetric: bool = True,
    *,
    extent=None,
    crs=None,
    band=None,
    nodata=None,
    breaks=None,
)

Transition matrix from a raster: gdistance's transition().

Connects every pair of neighbouring cells that both have a value with function of their two values.

Parameters:

Name Type Description Default
x

Raster: path, xarray.DataArray or 2-D array (NaN = missing); for "mahal" several layers (3-D or a multi-band raster).

required
function str | Callable

A built-in function, computed in C++ with R's arithmetic (so the values are gdistance's to the last bit): "mean", "min", "max", "sum", "prod", "harmonic" (1/mean(1/x)), "geometric" (exp(mean(log(x)))), "from" (x[1]), "to" (x[2]), "diff" (x[2] - x[1]); "mahal": the normalised reciprocal of the Mahalanobis distance between the cells' layers; "barriers" / "areas": lists of transitions, see barriers() and areas(); or a vectorised callable that receives x (2 x n: x[0] the first cell, x[1] the second) as gdistance's function receives c(x1, x2), e.g. lambda x: x[1] - x[0]. Values of 0 leave the cells unconnected. For a conductance from a resistance use 1 / transition(r, "mean").

'mean'
directions (4, 8, 16)

Rook, queen, or queen and knight moves.

4
symmetric bool

True: the pair's value, f(x[lower cell index], x[higher]); False: a value per direction, f(x[from], x[to]).

True
extent

(xmin, xmax, ymin, ymax) and CRS of an array (DataArrays and files carry their own). On a longitude/latitude grid spanning 360 degrees the columns wrap around, as in gdistance.

None
crs

(xmin, xmax, ymin, ymax) and CRS of an array (DataArrays and files carry their own). On a longitude/latitude grid spanning 360 degrees the columns wrap around, as in gdistance.

None
band

Band to read (1-based) and value to treat as missing.

None
nodata

Band to read (1-based) and value to treat as missing.

None
breaks

"barriers" only: the breaks of continuous values.

None

Returns:

Type Description
Transition, or a list of them for ``"barriers"`` and ``"areas"``

Examples:

>>> import landschaft as ls
>>> import numpy as np
>>> r = np.array([[1.0, 2.0, 4.0], [1.0, np.nan, 2.0]])
>>> tr = 1 / ls.cost.transition(r, "mean", 4)       # conductance = 1 / mean resistance
>>> tr
Transition(2 x 3 cells, 4 directions, symmetric, conductance, 8 connections)
>>> tr.to_sparse()[0, 1]                             # cells 0 and 1: 1 / mean(1, 2)
np.float64(0.6666666666666666)
>>> up = ls.cost.transition(r, lambda x: x[1] - x[0], 4, symmetric=False)
>>> float(up.to_sparse()[1, 2]), float(up.to_sparse()[2, 1])
(2.0, -2.0)

Transition

Transition(
    values: ndarray,
    grid: GridInfo,
    directions: int,
    symmetric: bool,
    matrix_values: str = "conductance",
    template=None,
)

A transition matrix on a raster grid: gdistance's TransitionLayer.

The connections between neighbouring cells (4, 8 or 16 directions) with a conductance (or resistance). Build one with transition(); combine them with *, +, -, scale them with numbers (1 / tr takes the reciprocal of every connection), change the values with map(), correct them for the distances between cells with geo_correction().

Attributes:

Name Type Description
values ndarray

(n_directions, n_cells): the value of the connection from each cell (row-major) in each direction of offsets; 0 = none. A symmetric transition keeps only the directions after (0, 0) (the pair's value), an asymmetric one all of them (from the cell to its neighbour).

directions int

4, 8 or 16.

symmetric bool
matrix_values str

"conductance" or "resistance" (gdistance's matrixValues).

shape property

shape: tuple[int, int]

Rows and columns of the raster.

lonlat property

lonlat: bool

True when the CRS is longitude/latitude.

offsets property

offsets: list[tuple[int, int]]

(row, column) offset of each direction of values.

n_connections property

n_connections: int

Number of non-zero entries of the matrix (both triangles when symmetric).

is_symmetric

is_symmetric() -> bool

Whether the matrix is symmetric (gdistance's isSymmetric): always for symmetric transitions, and for asymmetric ones whose values happen to be.

neighbours

neighbours() -> ndarray

The neighbour cell of each (direction, cell) of values, -1 where there is none.

to_sparse

to_sparse()

The n_cells x n_cells matrix (scipy CSC, both triangles when symmetric).

adjacency

adjacency() -> tuple[ndarray, ndarray]

Cells (from, to) of every connection (0-based), column by column.

gdistance's adjacencyFromTransition (which is 1-based).

to_raster

to_raster(reduce: str = 'NZcolMeans')

A raster summarising the connections of each cell (gdistance's raster()).

Parameters:

Name Type Description Default
reduce ('NZcolMeans', 'NZrowMeans', 'colSums', 'rowSums', 'colMeans', 'rowMeans')

Sums or means of the matrix's columns (connections into the cell) or rows (out of it); NZ: the mean over the connections only (NaN without any).

"NZcolMeans"

map

map(function: Callable | str, pairs: str = 'edges') -> 'Transition'

A transition with function applied to the values.

Parameters:

Name Type Description Default
function Callable | str

A vectorised function of an array of values, or "sqrt", "exp", "log" for R's (bit-identical) versions.

required
pairs ('edges', 'all')

"edges": the existing connections only; "all": every pair of neighbouring cells of the grid, also those without a connection (value 0) or with missing values, as gdistance's tr[adjacent(r, 1:ncell(r))] <- f(tr[...]).

"edges"

geo_correction

geo_correction(
    type: str = "c", *, factors: bool = False, scale: bool = False
) -> "Transition"

See geo_correction().

normalize

normalize(method: str = 'row') -> 'Transition'

See normalize().

geo_correction

geo_correction(
    x: Transition, type: str = "c", *, factors: bool = False, scale: bool = False
) -> Transition

Correct a transition for the distances between cell centres: gdistance's geoCorrection().

Conductances are divided by the distance between the centres of the two cells (resistances multiplied): needed with more than 4 directions and on longitude/latitude grids, where distances are great-circle ones on the WGS84 ellipsoid (the R package raster's, bit for bit).

Parameters:

Name Type Description Default
x Transition

A Transition.

required
type ('c', 'r')

On longitude/latitude grids: "c" for least-cost distances; "r" for random walks, which also scales north-south connections (conductances) by the cosine of their mean latitude.

"c"
factors bool

Return the correction factors instead of the corrected values (gdistance's multpl = TRUE).

False
scale bool

Divide the distances by the west-east distance of one cell at the centre of the grid, to keep values near 1 (scl = TRUE).

False

Returns:

Type Description
Transition

Examples:

>>> import landschaft as ls
>>> import numpy as np
>>> tr = ls.cost.transition(np.ones((3, 3)), "mean", 8, extent=(0, 30, 0, 30))
>>> g = ls.cost.geo_correction(tr)
>>> m = g.to_sparse()
>>> float(m[0, 1]), round(float(m[0, 4]), 6)       # 1/10 m across, 1/(10 sqrt 2) diagonally
(0.1, 0.070711)

normalize

normalize(x: Transition, method: str = 'row') -> Transition

Normalise a transition matrix: gdistance's normalize().

Parameters:

Name Type Description Default
x Transition

A Transition.

required
method ('row', 'col', 'symm')

"row": divide each row by its sum (transition probabilities of a random walk, asymmetric); "col": each column; "symm": divide by the square roots of the row and column sums (stays symmetric).

"row"

Returns:

Type Description
Transition

Examples:

>>> import landschaft as ls
>>> import numpy as np
>>> p = ls.cost.normalize(ls.cost.transition(np.ones((3, 3)), "mean", 4), "row")
>>> p.to_sparse()[4].toarray().round(2)            # the centre cell: 1/4 to each neighbour
array([[0.  , 0.25, 0.  , 0.25, 0.  , 0.25, 0.  , 0.25, 0.  ]])

sum_reciprocal

sum_reciprocal(x1: Transition, x2: Transition) -> Transition

Combine two transitions as resistances in series: gdistance's sumReciprocal().

Conductances are turned into resistances (1 / x), added, and the sum turned back into a conductance.

Examples:

>>> import landschaft as ls
>>> import numpy as np
>>> a = ls.cost.transition(np.full((2, 2), 2.0), "mean", 4)
>>> b = ls.cost.transition(np.full((2, 2), 3.0), "mean", 4)
>>> round(float(ls.cost.sum_reciprocal(a, b).to_sparse()[0, 1]), 12)   # 1 / (1/2 + 1/3)
1.2

Least-cost surfaces, distances and paths

The cost of a step between neighbouring cells is the reciprocal of the transition's value; among equally cheap paths, shortest_path returns the one gdistance returns.

acc_cost

acc_cost(x: Transition, origins)

Accumulated cost surface from the nearest origin: gdistance's accCost().

The cost of a step between neighbouring cells is the reciprocal of the transition's value (a conductance); every cell gets the cost of the cheapest route from any origin.

Parameters:

Name Type Description Default
x Transition

A Transition of conductances (usually after geo_correction()).

required
origins

Coordinates (an (x, y) pair or an (n, 2) array), shapely points or a GeoDataFrame; or a raster (array or DataArray of the transition's shape) whose non-zero cells are the origins.

required

Returns:

Type Description
DataArray or ndarray

The accumulated cost; inf where no origin can be reached. A DataArray when the transition came from one.

Examples:

>>> import landschaft as ls
>>> import numpy as np
>>> r = np.array([[2, 2, 1, 1, 5, 5, 5],
...               [2, 2, 8, 8, 5, 2, 1],
...               [7, 1, 1, 8, 2, 2, 2],
...               [8, 7, 8, 8, 8, 8, 5],
...               [8, 8, 1, 1, 5, 3, 9],
...               [8, 1, 1, 2, 5, 3, 9]], dtype=float)   # GRASS r.cost example
>>> tr = ls.cost.geo_correction(1 / ls.cost.transition(r, "mean", 8, extent=(0, 7, 0, 6)))
>>> cost = ls.cost.acc_cost(tr, (5.5, 1.5))
>>> cost.round(1)[0]                                # the top row
array([21.8, 21.1, 20.7, 19.7, 16.9, 14.9, 13.7])

cost_distance

cost_distance(x: Transition, from_coords, to_coords=None) -> ndarray

Least-cost distances between points: gdistance's costDistance().

Parameters:

Name Type Description Default
x Transition

A Transition of conductances.

required
from_coords

Points (coordinates, shapely points or a GeoDataFrame). Without to_coords the distances among from_coords.

required
to_coords

Points (coordinates, shapely points or a GeoDataFrame). Without to_coords the distances among from_coords.

required

Returns:

Type Description
ndarray

(n_from, n_to) costs (inf: unreachable; NaN for points outside the grid). Among one set of points with a symmetric transition the matrix is symmetric, each pair summed from its later point as gdistance's dist result.

Examples:

>>> import landschaft as ls
>>> import numpy as np
>>> r = np.ones((10, 10))
>>> tr = ls.cost.geo_correction(ls.cost.transition(r, "mean", 8, extent=(0, 10, 0, 10)))
>>> ls.cost.cost_distance(tr, [(0.5, 0.5), (9.5, 9.5), (0.5, 9.5)]).round(3)
array([[ 0.   , 12.728,  9.   ],
       [12.728,  0.   ,  9.   ],
       [ 9.   ,  9.   ,  0.   ]])

shortest_path

shortest_path(x: Transition, origin, goal, output: str = 'transition')

Least-cost path from an origin to one or more goals: gdistance's shortestPath().

Among equally cheap paths the one gdistance (igraph's Dijkstra) returns.

Parameters:

Name Type Description Default
x Transition

A Transition of conductances.

required
origin

One point (the first one is taken if several are given).

required
goal

One or more points.

required
output ('transition', 'transitions', 'cells', 'lines')

"transition": a Transition with 1 / n_goals on the connections of each path (added up where paths share connections); "transitions": one such transition per goal; "cells": the cells of each path (row-major indices, origin first); "lines": a GeoDataFrame (or, without geopandas, a list) of line strings through the cell centres.

"transition"

Examples:

>>> import landschaft as ls
>>> import numpy as np
>>> r = np.array([[1, 1, 1], [9, 9, 1], [1, 1, 1]], dtype=float)
>>> tr = ls.cost.geo_correction(1 / ls.cost.transition(r, "mean", 4, extent=(0, 3, 0, 3)))
>>> ls.cost.shortest_path(tr, (0.5, 0.5), (0.5, 2.5), output="cells")[0]   # around the wall
array([6, 7, 8, 5, 2, 1, 0])

Random walks

A random walk moves from a cell to a neighbour with a probability proportional to the conductance of the connection. Its commute distances and passages are those of an electrical circuit (the transition's conductances as resistors), computed with the same sparse Cholesky factorisation as the circuit tools.

commute_distance

commute_distance(x: Transition, coords) -> ndarray

Expected commute distances of a random walk between points: gdistance's commuteDistance().

A random walk that moves from a cell to a neighbour with probability proportional to the conductance, starting at one point, takes on average this long (in steps weighted by the transition) to reach the other and come back. It equals the effective resistance between the points (the circuit view: circuit) times the sum of all conductances (the graph's volume).

Parameters:

Name Type Description Default
x Transition

A symmetric Transition of conductances; for longitude/latitude grids gdistance recommends geo_correction(tr, "r").

required
coords

Points (coordinates, shapely points or a GeoDataFrame).

required

Returns:

Type Description
ndarray

(n, n) symmetric; inf between points in separate parts of the graph (gdistance fails there; the volume is then that of each part), NaN for points outside the grid or on cells without connections.

Notes

Solved with the circuit module's multifrontal Cholesky factorisation, one per connected part; gdistance uses CHOLMOD, and the two agree to about 1e-12 (relative).

Examples:

>>> import landschaft as ls
>>> import numpy as np
>>> tr = ls.cost.transition(np.ones((1, 3)), "mean", 4)   # a chain of 3 cells, conductance 1
>>> ls.cost.commute_distance(tr, [(0.5, 0.5), (2.5, 0.5)]).round(9)   # resistance 2, volume 4
array([[0., 8.],
       [8., 0.]])

passage

passage(
    x: Transition,
    origin,
    goal,
    theta: float | None = None,
    *,
    total_net: str = "net",
    output: str = "raster",
    gdistance_compat: bool = True,
)

Passages of a random walk from origins to goals: gdistance's passage().

Without theta: the net number of times a random walk from the origin (one of them at random) to the goal passes through each cell, which is the current through the cell when a unit current flows from the origins to the goals (as in Circuitscape).

With theta: randomised shortest paths (Saerens et al. 2009), walks that prefer cheap routes more and more as theta grows: 0 is the random walk, large values approach the least-cost path. The walk's steps follow exp(-theta * cost) * P, P the random walk's probabilities, cost the reciprocal of the transition's values; with several goals each of them absorbs part of the walk (gdistance's 1 - 1/n rows).

Parameters:

Name Type Description Default
x Transition

A Transition of conductances (symmetric without theta).

required
origin

Points, or rasters whose non-zero cells are the origins / goals.

required
goal

Points, or rasters whose non-zero cells are the origins / goals.

required
theta float | None

None, or 0 to 20 (gdistance's range).

None
total_net ('net', 'total')

Net passages (through minus back) or total visits; without theta only "net".

"net"
output ('raster', 'transition')

Passages per cell, or per connection (a transition; "net": the positive part of the net flow). Without theta only "raster".

"raster"
gdistance_compat bool

Without theta: True (default) keeps gdistance's potential of the circuit's grounded cell (the last cell with connections takes the potential of the one before it), which changes the passages around that cell; False gives the exact currents.

True

Returns:

Type Description
(DataArray, ndarray or Transition)

Without theta: 1 at the origins and goals, 0 off the graph. With theta: NaN off the graph; net passages at the origins and goals doubled, as gdistance.

Examples:

>>> import landschaft as ls
>>> import numpy as np
>>> tr = ls.cost.transition(np.ones((3, 3)), "mean", 4)
>>> ls.cost.passage(tr, (0.5, 1.5), (2.5, 1.5), gdistance_compat=False).round(3)
array([[0.25, 0.25, 0.25],
       [1.  , 0.5 , 1.  ],
       [0.25, 0.25, 0.25]])
>>> ls.cost.passage(tr, (0.5, 1.5), (2.5, 1.5), theta=2).round(3)   # the straight route takes more
array([[0.009, 0.009, 0.009],
       [1.   , 0.982, 1.   ],
       [0.009, 0.009, 0.009]])

Randomised shortest paths

Between the random walk and the least-cost path: walks that prefer cheap routes more and more as theta grows (Saerens et al. 2009). passage with a theta gives their passages; rsp_distance their expected costs.

rsp_distance

rsp_distance(
    x: Transition,
    from_coords,
    to_coords,
    theta: float,
    *,
    total_net: str = "net",
    method: int = 1,
) -> ndarray

Randomised-shortest-path distances between points: gdistance's rSPDistance().

The expected cost (the sum of the reciprocals of the transition's values along the way) of the randomised shortest-path walk from each origin to each goal (see passage()): with theta near 0 close to a random-walk distance, with large theta close to the least-cost distance.

Parameters:

Name Type Description Default
x Transition

A Transition of conductances.

required
from_coords

Points (coordinates, shapely points or a GeoDataFrame).

required
to_coords

Points (coordinates, shapely points or a GeoDataFrame).

required
theta float

0 to 20 (gdistance's range).

required
total_net ('net', 'total')

Cost of the net passages (default) or of all of them.

"net"
method (1, 2)

1: steps weighted by exp(-theta * cost) * P; 2: by P ** theta (a walk that only follows the random walk's probabilities).

1

Returns:

Type Description
ndarray

(n_from, n_to); NaN for points off the grid.

Notes

gdistance factorises I - W once per pair of points; here once per goal (the goals in parallel), with a sparse Cholesky factorisation for symmetric transitions (I - W scaled row by row is symmetric positive definite) and a multifrontal LU without pivoting otherwise (I - W is an M-matrix). The results agree to about 1e-12.

Examples:

>>> import landschaft as ls
>>> import numpy as np
>>> tr = ls.cost.transition(np.ones((5, 5)), "mean", 4)
>>> pts = [(0.5, 2.5), (4.5, 2.5)]
>>> ls.cost.rsp_distance(tr, pts, pts, theta=10).round(3)    # 4 steps of cost 1 at best
array([[0., 4.],
       [4., 0.]])

Route overlap, barriers and areas

How much the routes from a common origin to two locations share (van Etten and Hijmans 2010), optionally weighted by barriers or areas.

path_inc

path_inc(
    x: Transition,
    origin,
    from_coords,
    to_coords=None,
    *,
    theta: float | None = None,
    weight=None,
    functions: Sequence[str | Callable] = ("overlap", "nonoverlap"),
    gdistance_compat: bool = True,
) -> dict

Overlap and non-overlap of the routes from a common origin to each location: gdistance's pathInc().

For each location, the flow of a random walk (or, with theta, of the randomised shortest paths) from origin to it on every connection; then, for each pair of locations, the sum over the connections of function(flow_1, flow_2) * weight. With overlap it measures how much the two routes share, with nonoverlap how much they differ: the "path of dispersal from a common origin" distances of van Etten and Hijmans (2010).

Parameters:

Name Type Description Default
x Transition

A Transition of conductances (symmetric without theta).

required
origin

The common origin (a point).

required
from_coords

Locations (points). Without to_coords, the pairs among from_coords.

required
to_coords

Locations (points). Without to_coords, the pairs among from_coords.

required
theta float | None

None: random walks; else randomised shortest paths (0 to 20).

None
weight

None: the cost of each connection (the reciprocal of the transition's value); a Transition (a conductance is turned into its reciprocal); or a list of them (e.g. barriers(), areas()), one result per layer.

None
functions Sequence[str | Callable]

"overlap", "nonoverlap" or vectorised callables f(a, b) of two arrays of flows (one value per connection).

('overlap', 'nonoverlap')
gdistance_compat bool

Random walks: keep gdistance's potential of the grounded cell (see passage()).

True

Returns:

Type Description
dict

Function name (or function<k> for callables) -> (n, n) matrix ((n_from, n_to) with to_coords; (layers, n, n) for a list of weights), NaN for locations off the graph. Among one set of locations the matrix is symmetric with 0 on the diagonal, as gdistance's dist.

Notes

Two gdistance behaviours are not reproduced: with to its result is all missing (.finishFlowFromTo copies an empty matrix), and its default weights are read from the wrong connections when some cells have no connection (the full matrix indexed with the positions of the reduced one); landschaft gives what the code intends in both cases.

Examples:

>>> import landschaft as ls
>>> import numpy as np
>>> tr = ls.cost.transition(np.ones((5, 5)), "mean", 8)
>>> out = ls.cost.path_inc(tr, (2.5, 2.5), [(0.5, 0.5), (4.5, 0.5), (0.5, 4.5)])
>>> sorted(out), out["overlap"].shape
(['nonoverlap', 'overlap'], (3, 3))
>>> bool(np.allclose(out["overlap"], out["overlap"].T))
True

overlap

overlap(a: ndarray, b: ndarray) -> ndarray

gdistance's overlap: the flow two routes share on each connection, min(a, b).

nonoverlap

nonoverlap(a: ndarray, b: ndarray) -> ndarray

gdistance's nonoverlap: max(max(a, b) * (1 - min(a, b)) - min(a, b), 0).

barriers

barriers(
    x,
    directions: int = 8,
    *,
    breaks: Sequence[float] | None = None,
    symmetric: bool = True,
    extent=None,
    crs=None,
    band=None,
    nodata=None,
) -> list[Transition]

Barrier transitions: gdistance's transition(x, "barriers", directions).

Each layer marks (with 1, as resistances) the connections that cross a boundary, for use as weights of path_inc().

Parameters:

Name Type Description Default
x

A raster.

required
directions (4, 8, 16)
4
breaks Sequence[float] | None

Continuous values: one layer per break b, the connections between a cell below b and one above it. Without breaks the values are categories: one layer per pair of categories (in gdistance's order: (2, 1), (3, 1), ..., (3, 2), ...), the connections between cells of the two; with symmetric=False two layers per pair, one per direction.

None
symmetric bool

See breaks (continuous barriers are always symmetric, as in gdistance).

True

Returns:

Type Description
list of Transition

Examples:

>>> import landschaft as ls
>>> import numpy as np
>>> r = np.array([[1.0, 1.0, 5.0], [1.0, 5.0, 5.0]])
>>> layer = ls.cost.barriers(r, 4, breaks=[3])[0]
>>> layer.n_connections, layer.matrix_values          # 3 boundary pairs, both ways
(6, 'resistance')

areas

areas(
    x, directions: int = 8, *, extent=None, crs=None, band=None, nodata=None
) -> list[Transition]

Area transitions: gdistance's transition(x, "areas", directions).

One layer per category k (1, 2, ... n; as gdistance, category k is the value k): 1 between two cells of the category, 0.5 between one of it and another cell, for use as weights of path_inc().

Returns:

Type Description
list of Transition

Examples:

>>> import landschaft as ls
>>> import numpy as np
>>> r = np.array([[1.0, 1.0, 2.0]])
>>> [t.to_sparse().toarray()[0, 1:].tolist() for t in ls.cost.areas(r, 4)]
[[1.0, 0.0], [0.0, 0.0]]

Example data

example_data

example_data(name: str = 'maungawhau') -> Path

Path of an example data set for the grid distances.

Parameters:

Name Type Description Default
name ('maungawhau', 'europe', 'gen_dist', 'pop_coord')

"maungawhau": elevation of the Maungawhau volcano (Auckland), 87 x 61 cells of 10 m (New Zealand Map Grid), the classic hiking example; "europe": land (1) and sea (missing) of Europe, 135 x 195 cells of 1/3 degree (longitude/latitude); "gen_dist": genetic distances between 23 European populations of the Y-chromosome haplogroup R1b1b2 (Balaresque et al. 2010, PLoS Biology 8: e1000285), a CSV table with a population column; "pop_coord": the longitude (x) and latitude (y) of those populations.

"maungawhau"

Returns:

Type Description
Path

Examples:

>>> import landschaft as ls
>>> dem = ls.load_raster(ls.cost.example_data("maungawhau"))
>>> dem.shape, int(dem.max())
((87, 61), 195)