This function calculates the total distance of a path, whose horizontal coordinates are known, over a three-dimensional surface. To implement the function, the path should be supplied as a matrix or dataframe of coordinates or a SpatialLines object and the surface should be supplied as a raster. The function takes the horizontal coordinates of the path and extracts the values of the surface at these points, and then calculates the total distance of the path as the sum of the paired distances between each pair of points.

dist_over_surface(path, surface)

Arguments

path

A matrix or dataframe of horizontal coordinates (x, y) or a SpatialLines object which defines the path over a surface. The coordinate reference system (projection) of path should be the same as that for the surface.

surface

A raster over which the movement that generated the path occurred. The coordinate reference system (projection) of path should be the same as that for the surface and the values of the surface should also be expressed in the same units (e.g., metres).

Value

The function returns a number equal to the total distance along the path.

Details

The total distance of a path over a three-dimensional surface is equal to the sum of the pairwise distances between each point (\(i\)) and its successor (\(i + 1\)) according to the equation: $$\Sigma_{i = 1}^n \sqrt{(x_{i+1} - x_i)^2 + (y_{i + 1} - y_i)^2 + (z_{i + 1} - z_i)^2)}$$ where \(x\), \(y\) and \(z\) are the x, y and z coordinates of each point in three-dimensional space and \(n\) is the total number of points minus 1. Pairwise distances are calculated via dist_btw_points_3d. Note that for realistic distances, some interpolation (e.g., via least-cost paths) between points may be required to generate localisations at sufficiently high resolution to effectively capture the shape of the landscape.

This function does not currently support non-planar coordinates (path or surface).

See also

If the coordinates of the points are known in three dimensions already, dist_btw_points_3d can be used directly.

Author

Edward Lavender

Examples

#### Simulate a hypothetical landscape
# Define a miniature, blank landscape with known dimensions
proj_utm <- sp::CRS(SRS_string = "EPSG:32629")
r <- raster::raster(
  nrows = 3, ncols = 3,
  crs = proj_utm,
  resolution = c(5, 5),
  ext = raster::extent(0, 15, 0, 15)
)
# Define a matrix of hypothetical values for the landscape
mat <- matrix(c(
  5, 10, 3,
  2, 1, 4,
  5, 6, 6
), ncol = 3, nrow = 3, byrow = TRUE)
r[] <- mat
# Visualise simulated landscape
raster::plot(r)
raster::text(r)

#### Example (1): Total distance between two example adjacent points
path_cells <- c(1, 2)
path_matrix <- sp::coordinates(r)[path_cells, ]
dist_over_surface(path_matrix, r)
#> The CRS of 'surface' is not NA. Note that this function only supports planar surfaces.
#> [1] 7.071068
sqrt(5^2 + (10 - 5)^2)
#> [1] 7.071068

#### Example (2): Total distance between two example diagonal points
path_cells <- c(1, 5)
path_matrix <- sp::coordinates(r)[path_cells, ]
dist_over_surface(path_matrix, r)
#> The CRS of 'surface' is not NA. Note that this function only supports planar surfaces.
#> [1] 8.124038
sqrt(sqrt(5^2 + 5^2)^2 + (5 - 1)^2)
#> [1] 8.124038

#### Example (3): Total distance along a longer path
path_cells <- c(1, 2, 3)
path_matrix <- sp::coordinates(r)[path_cells, ]
dist_over_surface(path_matrix, r)
#> The CRS of 'surface' is not NA. Note that this function only supports planar surfaces.
#> [1] 15.67339
sqrt(5^2 + (10 - 5)^2) + sqrt(5^2 + (10 - 3)^2)
#> [1] 15.67339

#### Example (4): Total distance along an even longer path
path_cells <- c(1, 2, 3, 6, 8)
path_matrix <- sp::coordinates(r)[path_cells, ]
dist_over_surface(path_matrix, r)
#> The CRS of 'surface' is not NA. Note that this function only supports planar surfaces.
#> [1] 28.12088

#### Example (5): A SpatialLines object can be used for the path
path_line <- Orcs::coords2Lines(path_matrix, ID = 1, proj4string = proj_utm)
raster::lines(path_line)

dist_over_surface(path_line, r)
#> The CRS of 'surface' is not NA. Note that this function only supports planar surfaces.
#> [1] 28.12088