Skip to content

Commit

Permalink
sa
Browse files Browse the repository at this point in the history
  • Loading branch information
rhijmans committed Nov 21, 2024
1 parent 7353703 commit 162c51b
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 27 deletions.
2 changes: 1 addition & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
useDynLib(terra, .registration=TRUE)
import(methods, Rcpp)
exportClasses(SpatExtent, SpatRaster, SpatRasterDataset, SpatRasterCollection, SpatVector, SpatVectorProxy, SpatVectorCollection)
exportMethods("[", "[[", "!", "%in%", activeCat, "activeCat<-", "add<-", addCats, adjacent, all.equal, aggregate, allNA, align, animate, anyNA, app, area, Arith, approximate, as.bool, as.int, as.contour, as.lines, as.points, as.polygons, as.raster, as.array, as.data.frame, as.factor, as.list, as.logical, as.matrix, as.numeric, atan2, atan_2, autocor, barplot, blocks, boundaries, boxplot, buffer, cartogram, categories, cats, catalyze, clamp, clamp_ts, classify, clearance, cellSize, cells, cellFromXY, cellFromRowCol, cellFromRowColCombine, centroids, click, bestMatch, colFromX, colFromCell, colorize, coltab, "coltab<-", combineGeoms, compare, concats, Compare, compareGeom, contour, convHull, countNA, costDist, crds, cover, crop, crosstab, crs, "crs<-", datatype, deepcopy, delaunay, densify, density, depth, "depth<-", describe, diff, disagg, direction, distance, dots, draw, droplevels, elongate, emptyGeoms, erase, extend, ext, "ext<-", extract, extractRange, expanse, fillHoles, fillTime, flip, focal, focal3D, focalCor, focalPairs, focalReg, focalCpp, focalValues, forceCCW, freq, gaps, geom, geomtype, getTileExtents, global, gridDist, gridDistance, has.colors, has.RGB, has.time, hasMinMax, hasValues, hist, head, identical, ifel, impose, init, image, inext, interpIDW, interpNear, inMemory, inset, interpolate, intersect, is.bool, is.int, is.lonlat, is.rotated, isTRUE, isFALSE, is.empty, is.factor, is.lines, is.points, is.polygons, is.related, is.valid, k_means, lapp, layerCor, levels, "levels<-", linearUnits, lines, Logic, varnames, "varnames<-", logic, longnames, "longnames<-", makeValid, mask, match, math, Math, Math2, mean, median, meta, merge, mergeLines, mergeTime, minCircle, minmax, minRect, modal, mosaic, na.omit, not.na, NAflag, "NAflag<-", nearby, nearest, ncell, ncol, "ncol<-", nlyr, "nlyr<-", noNA, normalize.longitude, nrow, "nrow<-", nsrc, origin, "origin<-", pairs, panel, patches, perim, persp, plot, plotRGB, plet, prcomp, princomp, RGB, "RGB<-", polys, points, predict, project, quantile, query, rangeFill, rapp, rast, rasterize, rasterizeGeom, rasterizeWin, readStart, readStop, readValues, rectify, regress, relate, removeDupNodes, res, "res<-", resample, rescale, rev, rcl, roll, rotate, rowFromY, rowColCombine, rowColFromCell, rowFromCell, sapp, scale, scoff, "scoff<-", sds, sort, sprc, sel, selectRange, setMinMax, setValues, segregate, selectHighest, set.cats, set.crs, set.ext, set.names, set.RGB, set.values, size, sharedPaths, shift, sieve, simplifyGeom, snap, sources, spatSample, split, spin, stdev, stretch, subset, subst, summary, Summary, svc, symdif, t, metags, "metags<-", tail, tapp, terrain, tighten, makeNodes, makeTiles, time, timeInfo, "time<-", text, trans, trim, units, union, "units<-", unique, unwrap, update, vect, values, "values<-", viewshed, voronoi, vrt, weighted.mean, where.min, where.max, which.lyr, which.min, which.max, which.lyr, width, window, "window<-", writeCDF, writeRaster, wrap, wrapCache, writeStart, writeStop, writeVector, writeValues, xmin, xmax, "xmin<-", "xmax<-", xres, xFromCol, xyFromCell, xFromCell, ymin, ymax, "ymin<-", "ymax<-", yres, yFromCell, yFromRow, zonal, zoom, cbind2, readRDS, saveRDS, unserialize, serialize, xapp)
exportMethods("[", "[[", "!", "%in%", activeCat, "activeCat<-", "add<-", addCats, adjacent, all.equal, aggregate, allNA, align, animate, anyNA, app, Arith, approximate, as.bool, as.int, as.contour, as.lines, as.points, as.polygons, as.raster, as.array, as.data.frame, as.factor, as.list, as.logical, as.matrix, as.numeric, atan2, atan_2, autocor, barplot, blocks, boundaries, boxplot, buffer, cartogram, categories, cats, catalyze, clamp, clamp_ts, classify, clearance, cellSize, cells, cellFromXY, cellFromRowCol, cellFromRowColCombine, centroids, click, bestMatch, colFromX, colFromCell, colorize, coltab, "coltab<-", combineGeoms, compare, concats, Compare, compareGeom, contour, convHull, countNA, costDist, crds, cover, crop, crosstab, crs, "crs<-", datatype, deepcopy, delaunay, densify, density, depth, "depth<-", describe, diff, disagg, direction, distance, dots, draw, droplevels, elongate, emptyGeoms, erase, extend, ext, "ext<-", extract, extractRange, expanse, fillHoles, fillTime, flip, focal, focal3D, focalPairs, focalReg, focalCpp, focalValues, forceCCW, freq, gaps, geom, geomtype, getTileExtents, global, gridDist, has.colors, has.RGB, has.time, hasMinMax, hasValues, hist, head, identical, ifel, impose, init, image, inext, interpIDW, interpNear, inMemory, inset, interpolate, intersect, is.bool, is.int, is.lonlat, is.rotated, isTRUE, isFALSE, is.empty, is.factor, is.lines, is.points, is.polygons, is.related, is.valid, k_means, lapp, layerCor, levels, "levels<-", linearUnits, lines, Logic, varnames, "varnames<-", logic, longnames, "longnames<-", makeValid, mask, match, math, Math, Math2, mean, median, meta, merge, mergeLines, mergeTime, minCircle, minmax, minRect, modal, mosaic, na.omit, not.na, NAflag, "NAflag<-", nearby, nearest, ncell, ncol, "ncol<-", nlyr, "nlyr<-", noNA, normalize.longitude, nrow, "nrow<-", nsrc, origin, "origin<-", pairs, panel, patches, perim, persp, plot, plotRGB, plet, prcomp, princomp, RGB, "RGB<-", polys, points, predict, project, quantile, query, rangeFill, rapp, rast, rasterize, rasterizeGeom, rasterizeWin, readStart, readStop, readValues, rectify, regress, relate, removeDupNodes, res, "res<-", resample, rescale, rev, rcl, roll, rotate, rowFromY, rowColCombine, rowColFromCell, rowFromCell, sapp, scale, scoff, "scoff<-", sds, sort, sprc, sel, selectRange, setMinMax, setValues, segregate, selectHighest, set.cats, set.crs, set.ext, set.names, set.RGB, set.values, size, sharedPaths, shift, sieve, simplifyGeom, snap, sources, spatSample, split, spin, stdev, stretch, subset, subst, summary, Summary, surfArea, svc, symdif, t, metags, "metags<-", tail, tapp, terrain, tighten, makeNodes, makeTiles, time, timeInfo, "time<-", text, trans, trim, units, union, "units<-", unique, unwrap, update, vect, values, "values<-", viewshed, voronoi, vrt, weighted.mean, where.min, where.max, which.lyr, which.min, which.max, which.lyr, width, window, "window<-", writeCDF, writeRaster, wrap, wrapCache, writeStart, writeStop, writeVector, writeValues, xmin, xmax, "xmin<-", "xmax<-", xres, xFromCol, xyFromCell, xFromCell, ymin, ymax, "ymin<-", "ymax<-", yres, yFromCell, yFromRow, zonal, zoom, cbind2, readRDS, saveRDS, unserialize, serialize, xapp)

## EC 20210702 ecor
exportMethods(watershed, pitfinder, NIDP, flowAccumulation)
Expand Down
4 changes: 1 addition & 3 deletions R/Agenerics.R
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ if (!isGeneric("focal3D")) { setGeneric("focal3D", function(x, ...) standardGene
if (!isGeneric("focalReg")) { setGeneric("focalReg", function(x, ...) standardGeneric("focalReg")) }
if (!isGeneric("focalCpp")) { setGeneric("focalCpp", function(x, ...) standardGeneric("focalCpp")) }
if (!isGeneric("focalPairs")) { setGeneric("focalPairs", function(x, ...) standardGeneric("focalPairs")) }
if (!isGeneric("focalCor")) { setGeneric("focalCor", function(x, ...) standardGeneric("focalCor")) }

if (!isGeneric("clearance")) {setGeneric("clearance", function(x, ...) standardGeneric("clearance"))}
if (!isGeneric("width")) {setGeneric("width", function(x, ...) standardGeneric("width"))}
Expand All @@ -115,6 +114,7 @@ if (!isGeneric("weighted.mean")) {setGeneric("weighted.mean", function(x, w, ...

if (!isGeneric("split")) {setGeneric("split", function(x, f, drop = FALSE, ...) standardGeneric("split"))}
if (!isGeneric("cellSize")) {setGeneric("cellSize", function(x, ...) standardGeneric("cellSize"))}
if (!isGeneric("surfArea")) {setGeneric("surfaceArea", function(x, ...) standardGeneric("surfaceArea"))}

if (!isGeneric("na.omit")) {setGeneric("na.omit", function(object, ...) standardGeneric("na.omit"))}
if (!isGeneric("catalyze")) {setGeneric("catalyze", function(x, ...) standardGeneric("catalyze"))}
Expand Down Expand Up @@ -279,8 +279,6 @@ if (!isGeneric("crs<-")) { setGeneric("crs<-", function(x, ..., value) standardG
if (!isGeneric("density")) { setGeneric("density", function(x, ...) standardGeneric("density"))}
if (!isGeneric("aggregate")) {setGeneric("aggregate", function(x, ...) standardGeneric("aggregate"))}
if (!isGeneric("disagg")) {setGeneric("disagg", function(x, ...) standardGeneric("disagg"))}
#if (!isGeneric("costDistance")) {setGeneric("costDistance", function(x, ...)standardGeneric("costDistance"))}
if (!isGeneric("gridDistance")) {setGeneric("gridDistance", function(x, ...)standardGeneric("gridDistance"))}
if (!isGeneric("costDist")) {setGeneric("costDist", function(x, ...)standardGeneric("costDist"))}
if (!isGeneric("gridDist")) {setGeneric("gridDist", function(x, ...)standardGeneric("gridDist"))}
if (!isGeneric("distance")) {setGeneric("distance", function(x, y, ...)standardGeneric("distance"))}
Expand Down
43 changes: 22 additions & 21 deletions R/Zdeprecated.R
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@

if (!isGeneric("area")) {setGeneric("area", function(x, ...) standardGeneric("area"))}
setMethod ("area" , "SpatRaster",
function (x, ...) {
error("area", "this method was removed. Use expanse or cellSize")
}
)
#if (!isGeneric("area")) {setGeneric("area", function(x, ...) standardGeneric("area"))}
#setMethod ("area" , "SpatRaster",
# function (x, ...) {
# error("area", "this method was removed. Use expanse or cellSize")
# }
#)


#if (!isGeneric("setCats")) { setGeneric("setCats", function(x, ...) standardGeneric("setCats")) }
Expand All @@ -24,18 +24,19 @@ setMethod ("area" , "SpatRaster",
# }
#)

setMethod("gridDistance", signature(x="SpatRaster"),
function(x, ...) {
error("gridDistance", "'gridDistance' was renamed to 'gridDist'")
#. 'gridDistance' will be removed in a future version")
#gridDist(x, target=target, scale=scale, maxiter=maxiter, filename=filename, ...)
}
)


setMethod("focalCor", signature(x="SpatRaster"),
function(x, ...) {
error("focalCor", "'focalCor' was renamed to 'focalPairs'")
# focalPairs(x, ...)
}
)
#setMethod("gridDistance", signature(x="SpatRaster"),
# function(x, ...) {
# error("gridDistance", "'gridDistance' was renamed to 'gridDist'")
# #. 'gridDistance' will be removed in a future version")
# #gridDist(x, target=target, scale=scale, maxiter=maxiter, filename=filename, ...)
# }
#)


#if (!isGeneric("focalCor")) { setGeneric("focalCor", function(x, ...) standardGeneric("focalCor")) }
#setMethod("focalCor", signature(x="SpatRaster"),
# function(x, ...) {
# error("focalCor", "'focalCor' was renamed to 'focalPairs'")
# # focalPairs(x, ...)
# }
#)
9 changes: 9 additions & 0 deletions R/generics.R
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,15 @@ setMethod("cellSize", signature(x="SpatRaster"),
)


setMethod("surfaceArea", signature(x="SpatRaster"),
function(x, filename="", ...) {
opt <- spatOptions(filename, ...)
x@ptr <- x@ptr$surface_area(opt)
messages(x, "surfaceArea")
}
)


setMethod("atan2", signature(y="SpatRaster", x="SpatRaster"),
function(y, x) {
opt <- spatOptions(filename="", overwrite=TRUE)
Expand Down
40 changes: 40 additions & 0 deletions man/surfArea.Rd
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
\name{surfArea}

\alias{surfArea}
\alias{surfArea,SpatRaster-method}

\title{
Compute surface area from elevation data
}

\description{
It is often said that if Wales was flattened out it would have an area bigger than England. This function computes the surface area for a raster with elevation values, taking into account the sloping nature of the surface.
}

\usage{
surfArea(x, filename="", ...)
}

\arguments{
\item{x}{SpatRaster with elevation values. Currently the raster CRS must be planar and have the same distance units (e.g. m) as the elevation values}

}

\value{SpatRaster}

\references{
Jenness, Jeff S., 2004. Calculating Landscape Surface Area from Digital Elevation Models. Wildlife Society Bulletin 32(3): 829-839
}

\author{
Barry Rowlingson <b.rowlingson@lancaster.ac.uk>
}

\examples{
f <- system.file("ex/elev.tif", package="terra")
r <- rast(f)
surfArea(r)
}

\keyword{spatial}

1 change: 1 addition & 0 deletions src/RcppModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,7 @@ RCPP_MODULE(spat){
.method("rst_area", &SpatRaster::rst_area)
.method("sum_area", &SpatRaster::sum_area)
.method("sum_area_group", &SpatRaster::sum_area_group)
.method("surface_area", &SpatRaster::surfaceArea)

.method("as_points", &SpatRaster::as_points)
.method("as_points_value", &SpatRaster::as_points_value)
Expand Down
3 changes: 1 addition & 2 deletions src/spatRaster.h
Original file line number Diff line number Diff line change
Expand Up @@ -592,10 +592,9 @@ class SpatRaster {
SpatRaster aggregate(std::vector<size_t> fact, std::string fun, bool narm, SpatOptions &opt);
SpatExtent align(SpatExtent e, std::string snap);
SpatRaster rst_area(bool mask, std::string unit, bool transform, int rcmax, SpatOptions &opt);

std::vector<std::vector<double>> sum_area(std::string unit, bool transform, bool by_value, SpatOptions &opt);

std::vector<std::vector<double>> sum_area_group(SpatRaster group, std::string unit, bool transform, bool by_value, SpatOptions &opt);
SpatRaster surfaceArea(SpatOptions &opt);

SpatRaster roll(size_t n, std::string fun, std::string type, bool circular, bool narm, SpatOptions &opt);

Expand Down
125 changes: 125 additions & 0 deletions src/surfArea.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@

#include "spatRaster.h"

/* Compute surface area, using method from:
Jeff S. Jenness, 2004. Calculating Landscape Surface Area from Digital Elevation Models. Wildlife Society Bulletin 32(3):829-839. http://www.jstor.org/stable/3784807
With edge adjustments. Adapted from code in R package "sp" by Barry Rowlingson 2010 <[email protected]>
*/

inline double height(const std::vector<double> &heights, const size_t &ncols, const size_t &row, const size_t &col) {
return heights[col + ncols*row];
}

inline double triarea(const double &a, const double &b, const double &c) {
// triangle area given side lengths
double s = (a+b+c) / 2.0;
return sqrt(s * (s-a) * (s-b) * (s-c));
}


void sarea(std::vector<double> &heights, const size_t &nrow, const size_t &ncol, const double &w, const double &h,
std::vector<double> &sa, const bool &startadd, const bool &endadd) {

// given an nx by ny matrix of heights with single-cell edge border, compute the surface area.

// point values
double z1, z2, z3;
// side lengths
double l1, l2, l3;
// diagonal length
double s2 = sqrt((w*w)+(h*h));

// offsets to neighbours
int dxv[] = {-1, 0, 1, 1, 1, 0, -1, -1, -1};
int dyv[] = {-1, -1, -1, 0, 1, 1, 1, 0, -1};

// triangle side lengths
// first the radial sides
double side[] = {s2, h, s2, w, s2, h, s2, w, s2};
// outer edges
double l3v[] = {w, w, h, h, w, w, h, h};

size_t outsize = heights.size() - ncol * (startadd + endadd);
sa = std::vector<double>(outsize, NAN);
size_t cellI = startadd ? 0 : ncol;

for (size_t i=1; i<(nrow-1); i++){
cellI++;
for (size_t j=1; j<(ncol-1); j++){
z1 = height(heights, ncol, i, j);
if (!std::isnan(z1)) {
double cellArea = 0;
for (size_t tri=0; tri<8; tri++){
z2 = height(heights, ncol, i+dxv[tri], j+dyv[tri]);
// replace missing adjacent values with the current cell value
if (std::isnan(z2)) z2=z1;
z3 = height(heights, ncol, i+dxv[tri+1], j+dyv[tri+1]);
if (std::isnan(z3)) z3=z1;
l1 = 0.5 * sqrt(side[tri] * side[tri] + (z1-z2)*(z1-z2));
l2 = 0.5 * sqrt(side[tri+1] * side[tri+1] + (z1-z3)*(z1-z3));
l3 = 0.5 * sqrt(l3v[tri] * l3v[tri] + (z2-z3)*(z2-z3));
cellArea += triarea(l1, l2, l3);
}
// sa[cellI] = cellArea;
sa[i*ncol+j] = cellArea;
}
cellI++;
}
cellI++;
}
}



SpatRaster SpatRaster::surfaceArea(SpatOptions &opt) {

SpatRaster out = geometry(1, false);
if (is_lonlat()) {
out.setError("not yet implemented for lonlat data");
return out;
}

if (!hasValues()) {
out.setError("cannot compute surfaceArea for a raster with no values");
return out;
}

size_t nl = nlyr();
if (nl != 1) {
out.setError("can only compute surfaceArea for a single raster layer");
return out;
}

if (!readStart()) {
out.setError(getError());
return(out);
}

if (!out.writeStart(opt, filenames())) {
readStop();
return out;
}

BlockSize cbs = out.bs;
for (size_t i = 0; i < (cbs.n-1); i++) {
cbs.nrows[i] += 1;
}
for (size_t i = 1; i < cbs.n; i++) {
cbs.row[i] -= 1;
cbs.nrows[i] += 1;
}

std::vector<double> wh = resolution();
for (size_t i = 0; i < cbs.n; i++) {
std::vector<double> v;
readBlock(v, cbs, i);
std::vector<double> sa;
sarea(v, cbs.nrows[i], ncol(), wh[0], wh[1], sa, i>0, i<(cbs.n-1));
if (!out.writeBlock(sa, i)) return out;
}
readStop();
out.writeStop();
return(out);
}

0 comments on commit 162c51b

Please sign in to comment.