Skip to content

Commit e1951e3

Browse files
committed
plot_crowns(): support SI units
1 parent a24f21c commit e1951e3

2 files changed

Lines changed: 61 additions & 18 deletions

File tree

R/plot_crowns.R

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
#' @param linear_unit An optional character string specifying the linear
2525
#' distance unit. Defaults to the native FIA unit of `"ft"`, but may be set to
2626
#' `"m"` instead (or `"meter"` / `"metre"`), in which case subplot boundaries
27-
#' will be display in meters, tree heights and crown widths are assumed to be
28-
#' given in meters, and tree diameters are assumed to be given in centimeters.
29-
#' **TODO: not currently implemented**
27+
#' will be displayed in meters, tree distances and crown widths are assumed to
28+
#' be given in meters, and tree diameters are assumed to be given in
29+
#' centimeters.
3030
#' @param main Character string giving the main plot title (on top).
3131
#' @param crown_col The color of tree crowns, e.g., either a color name (as
3232
#' listed by `colors()`) or a hexadecimal string.
@@ -49,11 +49,21 @@
4949
#'
5050
#' plot_crowns(plantation, subplot = 4, microplot = TRUE,
5151
#' main = "plantation microplot 4")
52+
#'
53+
#' # using SI units
54+
#' metric_trees <- within(plantation, {
55+
#' CRWIDTH <- calc_crwidth(plantation) |> ft_to_m()
56+
#' rm(DIST, DIA)
57+
#' DIST <- ft_to_m(plantation$DIST)
58+
#' DIA <- in_to_cm(plantation$DIA)
59+
#' })
60+
#' plot_crowns(metric_trees, linear_unit = "meter",
61+
#' main = "plantation plot (SI units)")
5262
#' @export
5363
plot_crowns <- function(tree_list, subplot = NULL, microplot = FALSE,
5464
linear_unit = "ft", main = "", crown_col = "#328e13",
5565
stem_col = "#b85e00", subp_border_lwd = 3,
56-
subp_border_col = "gray61"){
66+
subp_border_col = "gray61") {
5767

5868
if (missing(tree_list) || is.null(tree_list))
5969
stop("'tree_list' is required", call. = FALSE)
@@ -87,8 +97,17 @@ plot_crowns <- function(tree_list, subplot = NULL, microplot = FALSE,
8797
else
8898
linear_unit <- tolower(linear_unit)
8999

90-
if (!(linear_unit %in% c("ft", "foot", "m", "meter", "metre")))
100+
si_units <- FALSE # US customary units by default
101+
axis_unit_name <- "feet"
102+
if (!(linear_unit %in% c("ft", "foot", "m", "meter", "metre"))) {
91103
stop("'linear_unit' is invalid", call. = FALSE)
104+
} else if (linear_unit %in% c("m", "meter", "metre")) {
105+
si_units <- TRUE
106+
if (linear_unit == "metre")
107+
axis_unit_name <- "metres"
108+
else
109+
axis_unit_name <- "meters"
110+
}
92111

93112
if (is.null(subplot) || is.na(subplot))
94113
subplot <- FALSE
@@ -105,20 +124,34 @@ plot_crowns <- function(tree_list, subplot = NULL, microplot = FALSE,
105124
if (!(is.logical(microplot) && length(microplot) == 1))
106125
stop("'microplot' must be a single logical value", call. = FALSE)
107126

127+
tree_min_dia <- 5 # min diamater for tree vs sapling
128+
subp_radius <- 24
129+
micr_radius <- 6.8
130+
if (si_units) {
131+
tree_min_dia <- in_to_cm(5)
132+
subp_radius <- ft_to_m(24)
133+
micr_radius <- ft_to_m(6.8)
134+
}
135+
108136
if (subplot && microplot) {
109137
trees_in <- tree_list[tree_list$STATUSCD == 1 &
110138
tree_list$SUBP == subplot &
111-
tree_list$DIA < 5, ]
139+
tree_list$DIA < tree_min_dia, ]
112140
} else if (subplot && !microplot) {
113141
trees_in <- tree_list[tree_list$STATUSCD == 1 &
114142
tree_list$SUBP == subplot &
115-
tree_list$DIA >= 5, ]
143+
tree_list$DIA >= tree_min_dia, ]
116144
} else {
117-
trees_in <- tree_list[tree_list$STATUSCD == 1 & tree_list$DIA >= 5, ]
145+
trees_in <- tree_list[tree_list$STATUSCD == 1 &
146+
tree_list$DIA >= tree_min_dia, ]
118147
}
119148

120149
trees_in$height <- pmin(trees_in$HT, trees_in$ACTUALHT, na.rm = TRUE)
121-
trees_in$dia_ft <- 0.0833333 * trees_in$DIA
150+
if (si_units) {
151+
trees_in$dia_ft_or_m <- trees_in$DIA / 100
152+
} else {
153+
trees_in$dia_ft_or_m <- 0.0833333 * trees_in$DIA
154+
}
122155
trees_in <- trees_in[order(trees_in$height), ]
123156

124157
if (subplot) {
@@ -127,7 +160,7 @@ plot_crowns <- function(tree_list, subplot = NULL, microplot = FALSE,
127160
pts$x <- trees_in$DIST * sin(trees_in$AZIMUTH * (pi / 180))
128161
pts$y <- trees_in$DIST * cos(trees_in$AZIMUTH * (pi / 180))
129162
} else {
130-
pts <- .get_tree_list_xy(trees_in)
163+
pts <- .get_tree_list_xy(trees_in, linear_unit = linear_unit)
131164
}
132165

133166
crowns <- lapply(seq_len(nrow(trees_in)), \(i) {
@@ -136,13 +169,13 @@ plot_crowns <- function(tree_list, subplot = NULL, microplot = FALSE,
136169

137170
if (subplot) {
138171
if (microplot) {
139-
fia_poly <- gdalraster::g_buffer("POINT (0 0)", 6.8)
172+
fia_poly <- gdalraster::g_buffer("POINT (0 0)", micr_radius)
140173
} else {
141-
fia_poly <- gdalraster::g_buffer("POINT (0 0)", 24)
174+
fia_poly <- gdalraster::g_buffer("POINT (0 0)", subp_radius)
142175
}
143176
stems <- lapply(seq_len(nrow(trees_in)), \(i) {
144177
gdalraster::g_create("POINT", c(pts$x[i], pts$y[i])) |>
145-
gdalraster::g_buffer(trees_in$dia_ft[i] / 2)})
178+
gdalraster::g_buffer(trees_in$dia_ft_or_m[i] / 2)})
146179
} else {
147180
fia_poly <- .get_fia_plot_geom(linear_unit = linear_unit)
148181
}
@@ -151,8 +184,8 @@ plot_crowns <- function(tree_list, subplot = NULL, microplot = FALSE,
151184
gdalraster::g_envelope())
152185
names(rct) <- c("xmin", "xmax", "ymin", "ymax")
153186

154-
xlab <- sprintf("x (%s)", linear_unit)
155-
ylab <- sprintf("y (%s)", linear_unit)
187+
xlab <- sprintf("x (%s)", axis_unit_name)
188+
ylab <- sprintf("y (%s)", axis_unit_name)
156189
gdalraster::plot_geom(fia_poly, xlab, ylab, main, border = subp_border_col,
157190
lwd = subp_border_lwd, bbox = rct)
158191

man/plot_crowns.Rd

Lines changed: 13 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)