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.
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
5363plot_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
0 commit comments