Title: | Correction Factors for Tree Plot Areas Intersected by Stand Boundaries |
Version: | 2.1.0 |
Description: | The German national forest inventory uses angle count sampling, a sampling method first published as 'Bitterlich, W.: Die Winkelzählmessung. Allgemeine Forst- und Holzwirtschaftliche Zeitung, 58. Jahrg., Folge 11/12 vom Juni 1947' and extended by Grosenbaugh (https://academic.oup.com/jof/article-abstract/50/1/32/4684174) as probability proportional to size sampling. When plots are located near stand boundaries, their sizes and hence their probabilities need to be corrected. |
License: | BSD_2_clause + file LICENSE |
URL: | https://gitlab.com/fvafrcu/treeplotarea.git |
Depends: | R (≥ 4.0.0) |
Imports: | fritools, graphics, sf, stats |
Suggests: | checkmate, pkgload, plotrix, rmarkdown, rprojroot, RUnit, testthat, tinytest |
VignetteBuilder: | utils |
Encoding: | UTF-8 |
Language: | en-US |
LazyData: | true |
RoxygenNote: | 7.3.1 |
NeedsCompilation: | no |
Packaged: | 2024-04-04 09:20:38 UTC; qwer |
Author: | Andreas Dominik Cullmann [aut, cre], Bernhard Bösch [ctb], Christoph Fischer [ctb], Gerald Kändler [ctb] |
Maintainer: | Andreas Dominik Cullmann <fvafrcu@mailbox.org> |
Repository: | CRAN |
Date/Publication: | 2024-04-04 10:00:02 UTC |
Correction Factors for Tree Plot Areas Intersected by Stand Boundaries
Description
The German national forest inventory uses angle count sampling, a sampling method first published by Bitterlich (1947) and extended by Grosenbaugh (1952) as probability proportional to size sampling. When plots are located near stand boundaries, their sizes and hence their probabilities need to be corrected.
Details
You will find the details in
vignette("An_Introduction_to_treePlotArea", package =
"treePlotArea")
.
Author(s)
Maintainer: Andreas Dominik Cullmann fvafrcu@mailbox.org
Other contributors:
Bernhard Bösch [contributor]
Christoph Fischer [contributor]
Gerald Kändler [contributor]
References
Bitterlich, W. (1947): Die Winkelzählmessung. Allgemeine Forst- und Holzwirtschaftliche Zeitung, 58.
Grosenbaugh, L. R. (1952): Plotless Timber Estimates – New, Fast, Easy. Journal of Forestry. https://academic.oup.com/jof/article-abstract/50/1/32/4684174.
See Also
Useful links:
Boundaries of the German National Inventory 2022
Description
An extract from the the federal database. Refer to Aufnahmeanweisung für die vierte Bundeswaldinventur (2021 - 2022).
Usage
data("boundaries", package = "treePlotArea")
Format
A data frame with 148 observations on the following 13 variables. Variables not needed with the package are marked with an asterisk.
tnr
The tract id.
enr
The corner id. A tract may have up to 4 corners on wooden floor.
vbl
* An indicator giving the country. 804 denotes Baden-Wuerttemberg.
rnr
* The boundary id.
rk
An indicator giving the validity of the boundary. Values of 9 or higher indicate that this boundary is not valid (any more).
rart
An indicator giving the type of the boundary (stand or forest boundary, for example).
rterrain
* An Indicator giving the type of terrain behind the border.
spa_gon
The azimuth in gon of the starting point of the boundary.
spa_m
The distance to the starting point of the boundary in centimeter
spk_gon
As above, for the boundary's flexing point.
spk_m
As above, for the boundary's flexing point.
spe_gon
As above, for the boundary's stopping point.
spe_m
As above, for the boundary's stopping point.
References
Aufnahmeanweisung für die vierte Bundeswaldinventur (2021 - 2022) Johann Heinrich von Thünen-Institut. Bundesforschungseinheit für Ländliche Räume, Wald und Fischerei, Thünen-Institut für Waldökologie.
Examples
boundaries <- get(data("boundaries", package = "treePlotArea"))
Convert Preprocessed Data Back to Original Units
Description
The data tree coming with this package was processed by Gerald Kaendler for the country of Baden-Wuerttemberg, and is the reference for testing as he adjusted diameter measurements to breast height where they had been measured in diverging heights (due to deformations of trees at breast height). Which we really need to do. But he did some other things we need to revert if we want to follow the standards from the federal database. He
converted the diameter at breast height from millimeter to centimeter and renamed it,
converted horizontal distance from centimeter to meter and renamed it.
So we add two variables holding the diameter in millimeter and the horizontal
distance in centimeter, named by the output of
getOption("treePlotArea")[["angle_counts"]][["dbh"]]
and
getOption("treePlotArea")[["angle_counts"]][["distance"]]
respectively.
Usage
bw2bwi2022de(x)
Arguments
x |
A tree data set, typically
|
Value
A tree data set prepared to work with the package.
See Also
Other data functions:
select_valid_angle_count_trees()
Examples
trees <- get(data("trees", package = "treePlotArea"))
summary(trees)
angle_counts <- bw2bwi2022de(trees)
summary(angle_counts)
Convert Coordinates of the German National Forest Inventory to Cartesian Coordinates
Description
Coordinates of the German national forest inventory are measured in gon eastward from north at distance in centimeter. We need cartesian coordinates for relational computations.
Usage
bwi2cartesian(azimuth, distance)
Arguments
azimuth |
The azimuths, from north, eastern side, in gon. |
distance |
The distances from the origin, typically measured in centimeter. |
Value
Matrix of cartesian coordinates in the unit of distance
.
Examples
a1 <- c(0, 100)
d1 <- c(100, 200)
print(coords <- bwi2cartesian(a1, d1))
all.equal(coords, matrix(c(0, 100, 200, 0), nrow = 2, byrow = TRUE),
check.attributes = FALSE)
Check Validity of Boundaries
Description
There is a boundary (tract 6878, corner 1, boundary 1) in the federal database for the 2012 survey that runs exactly through the plot. If that boundary would be valid, at that corner the term "stand" is not defined.
Usage
check_boundaries(x, stop_on_error = TRUE, clean_data = FALSE)
Arguments
x |
A |
stop_on_error |
Throw an error if invalid boundaries are found? |
clean_data |
Get rid of invalid boundaries? |
Details
So we check for such boundaries. These are straight boundaries with identical azimuth values for start and end, and flexed boundaries where azimuth values for either start or end and the azimuth value for the nook are identical and the nook is farther away form the plot than the corresponding start or end.
Value
A (possibly cleansed) data.frame
containing boundaries.
See Also
Other boundary functions:
get_boundary_polygons()
Examples
data("boundaries", package = "treePlotArea")
validate_data(x = boundaries)
check_boundaries(boundaries)
Convert Boundaries to Polygons
Description
Used by get_correction_factors
to convert a boundary table
to polygons. You may want to see the polygons, that is why we exported this
function.
Usage
get_boundary_polygons(boundaries, stop_on_error = TRUE, clean_data = FALSE)
Arguments
boundaries |
A |
stop_on_error |
Throw an error if invalid boundaries are encountered? (There was tract 6878, corner 1, boundary 1 in the federal database for the 2012 survey, runs through the plot. There is no stand defined that way!). |
clean_data |
Omit invalid boundaries in any further calculations? |
Value
A list with all boundary polygons for each corner for each tract.
See Also
Other boundary functions:
check_boundaries()
Examples
boundaries <- get(data("boundaries", package = "treePlotArea"))
boundary_polygons <- get_boundary_polygons(boundaries)
Get the Boundary Radius for a Given Diameter at Breast Height
Description
The boundary radius is the maximum distance a tree with a given diameter at breast height may be away from the center of the plot to still be part of the sample.
Usage
get_boundary_radius(
dbh,
unit = c("mm", "cm", "dm", "m"),
counting_factor = 4,
area = 10000,
is_ti_round = TRUE
)
Arguments
dbh |
Diameter at breast height in millimeter. |
unit |
The unit for the return value. |
counting_factor |
The basal area factor used in counting the trees. For tally trees in the German national forest inventory its value is 4 [m^2]. |
area |
The reference surface in [m^2]. |
is_ti_round |
When checking for the boundary circle of a tree to include the center of the plot: round that circle's radius to the unit (i.e. [cm]) as done by Thuenen Institute? |
Details
counting_factor
and area
really don't have to be
square meters as long as they are in the same unit.
Value
Minimum diameter at breast height in units
.
Examples
# A diameter at breast height of 50.5 cm
get_boundary_radius(505, unit = "m")
get_boundary_radius(505, unit = "m", is_ti_round = FALSE)
get_boundary_radius(1000, unit = "cm")
get_boundary_radius(973, unit = "cm")
get_boundary_radius(973, unit = "cm", is_ti_round = FALSE)
Correction Factors for Tree Plot Areas Intersected by Stand Boundaries
Description
Get correction factors for an angle count table (i.e. a
data.frame
) and a corresponding boundary
table (i.e. a data.frame
).
Usage
get_correction_factors(
angle_counts,
boundaries,
verbose = TRUE,
stop_on_error = FALSE,
skip_check = FALSE,
counting_factor = 4,
is_ti_round = TRUE
)
Arguments
angle_counts |
A |
boundaries |
A |
verbose |
Be verbose? |
stop_on_error |
Passed to |
skip_check |
We usually check if the angle counts are suitable (for example whether a diameter at breast height, a horizontal distance and an azimuth measurement are given). Skip this check? This might be of interest if you want to check whether another plot with no dbh recorded (for example a corner) is intersected by a boundary. |
counting_factor |
The basal area factor used in counting the trees. For tally trees in the German national forest inventory its value is 4 [m^2]. |
is_ti_round |
When checking for the boundary circle of a tree to include the center of the plot: round that circle's radius to the unit (i.e. [cm]) as done by Thuenen Institute? |
Details
The columns in the names have to be named according to the values of
getOption("treePlotArea")
.
If they do not: you can either rename the columns
or set the option accordingly, probably using set_options
.
Value
A data.frame
containing the correction factors and a
status giving information on possibly errors.
See Also
set_options
Examples
data("trees", "boundaries", package = "treePlotArea")
# For CRAN's sake: draw a subset
tracts <- c(sample(boundaries[["tnr"]], 20), 10056)
# Calculate correction factors
trees <- subset(trees, tnr %in% tracts)
boundaries <- subset(boundaries, tnr %in% tracts)
angle_counts <- bw2bwi2022de(trees)
validate_data(x = boundaries)
validate_data(x = angle_counts)
boundary_polygons <- get_boundary_polygons(boundaries)
correction_factors <- get_correction_factors(angle_counts, boundary_polygons)
summary(correction_factors$status)
# Select valid angle count trees only
valid_angle_counts <- select_valid_angle_count_trees(angle_counts)
correction_factors <- get_correction_factors(valid_angle_counts,
boundary_polygons)
summary(correction_factors$status)
# Select a single tree
tnr <- 10056
enr <- 4
bnr <- 3
tree <- valid_angle_counts[valid_angle_counts[["tnr"]] == tnr &
valid_angle_counts[["enr"]] == enr &
valid_angle_counts[["bnr"]] == bnr, TRUE]
bounds <- boundaries[boundaries[["tnr"]] == tnr & boundaries[["enr"]] == enr,
TRUE]
get_correction_factors(tree, bounds)
# Deadwood plots:
dead_wood_plots <- unique(trees[TRUE, c("tnr", "enr")])
dead_wood_plots[["bnr"]] <- 0
dead_wood_plots[["hori"]] <- 0
dead_wood_plots[["azi"]] <- 0
dead_wood_plots[["bhd"]] <- 200
get_correction_factors(dead_wood_plots, boundary_polygons,
skip_check = TRUE)
# Set the deadwood plot's radius to 500 mm
dead_wood_plots[["bhd"]] <- 5000
# The counting factor has unit square meters per area.
# Area is hardcoded to 10000 [square meters], so to get a plot radius that's
# equal to the dbh, we need 2 * sqrt(counting_factor) / sqrt(10000) to be
# equal to 1.
get_correction_factors(dead_wood_plots, boundary_polygons,
skip_check = TRUE,
counting_factor = 2500)
Get Default Options for treePlotArea
Description
Used to see (not set) the default options set by treePlotArea.
Use set_options
to change these default values.
Usage
get_defaults()
Value
A named list. It has the following entries giving the column names of the angle count or boundary data that hold information on:
- angle_counts
-
- tract_id
The tract id.
- corner_id
The corner id.
- tree_id
The tree id.
- distance
The distance from the center of the tract's corner.
- azimuth
The azimuth from North.
- dbh
The diameter at breast height.
- boundaries
-
- tract_id
The tract id.
- corner_id
The corner id.
- boundary_type
Type of boundary.
- boundary_status
Validity of the boundary.
- distance_start
The starting point's distance.
- distance_flexing
The flexing point's distance.
- distance_end
The ending point's distance.
- azimuth_start
The starting point's azimuth.
- azimuth_flexing
The flexing point's azimuth.
- azimuth_end
The ending point's azimuth.
See Also
Other option functions:
set_options()
Examples
get_defaults()
Get Intersection Point of Two Lines
Description
Get the intersection point of two straight lines given in slope–intercept form.
Usage
get_intersection(x, y)
Arguments
x |
A named vector with intercept ["a"] and slope ["b"]. |
y |
A named vector with intercept ["a"] and slope ["b"]. |
Value
A named vector giving the intersection, NULL
if the
lines do not intersect, NaN
if they are identical.
See Also
Other geometry functions:
points2equation()
,
vector_length()
Examples
get_intersection(x = c(a = 0, b = 1), y = c(a = 2, b = -1))
get_intersection(x = c(a = 0, b = 1), y = c(a = 2, b = 1))
x <- c(a = 0, b = 1)
get_intersection(x = x, y = x)
Get a Theoretical Maximum Distance for a Tree
Description
Maximum distance is of interest as boundaries that are more than double that
distance away are of no interest.
This only a convenience wrapper to get_boundary_radius
.
Usage
get_r_max(counting_factor = 4, area = 10000)
Arguments
counting_factor |
The basal area factor used in counting the trees. For tally trees in the German national forest inventory its value is 4 [m^2]. |
area |
The reference surface in [m^2]. |
Value
A theoretical maximum distance in centimeter. Based on the assumption that trees have a maximum diameter at breast height of 200 cm.
Examples
get_r_max()
Get the Slope–intercept Form of an Orthogonal
Description
If slope-point form of an equation is given, we might be interested in the slope-intercept form of the orthogonal to the equation running through the point.
Usage
orthogonal(b, xy)
Arguments
b |
The slope. |
xy |
The point. |
Value
A named vector with intercept ["a"] and slope ["b"], as in
graphics::abline
.
If the slope was 0, there is no slope-intercept form as this is a vertical
line. Then the intercept is NA
and the slope gives the value of
x.
Examples
orthogonal(1, c(x = 0, y = 0))
orthogonal(0, c(x = 4, y = 0))
orthogonal(-1, c(x = -2, y = -2))
orthogonal(Inf, c(x = 0, y = 4))
Plot Tree Plot Area
Description
Visualize a corner, its boundaries and tree plot areas.
Usage
plot_tree_plot_area(
angle_counts,
boundaries,
tnr,
enr,
bnr = NULL,
frame_factor = 1,
use_sub = NULL
)
Arguments
angle_counts |
A |
boundaries |
A |
tnr |
Number of the tract. |
enr |
Number of the tract's corner. |
bnr |
If given, the number of a corner's tree. |
frame_factor |
Plotting from as a factor of the tree plot area. Stick with the default. |
use_sub |
Deprecated. |
Value
The corrections factors for the trees' plot areas.
Examples
tnr <- 166
enr <- 2
bnr <- 7
angle_counts <- bw2bwi2022de(get(data("trees", package = "treePlotArea")))
plot_tree_plot_area(angle_counts = angle_counts,
boundaries = get(data("boundaries",
package = "treePlotArea")),
tnr = tnr, enr = enr, bnr = bnr, frame_factor = 4)
plot_tree_plot_area(angle_counts = angle_counts,
boundaries = get(data("boundaries",
package = "treePlotArea")),
tnr = tnr, enr = enr, frame_factor = 1)
Get a Slope–intercept Form from a Two-point Form of an Equation
Description
Two-point from is often seen in German national forest inventory data, we want to get an equation of form y = a + bx.
Usage
points2equation(p1, p2 = c(0, 0))
Arguments
p1 |
The first point (x, y). |
p2 |
The second point (x, y). |
Value
A named vector with intercept ["a"] and slope ["b"].
If both points have the same value for x, no function exists. Then
the intercept is NA
and the slope gives the value of x.
See Also
Other geometry functions:
get_intersection()
,
vector_length()
Examples
points2equation(c(0, 4), c(1, 5))
Calculate Intersections of Circle by a Straight Line
Description
The circle is centered a (0, 0) and has radius r, the line is given in slope-intercept from.
Usage
secant_intersections(a, b, r, verbose = FALSE)
Arguments
a |
The secant's intercept. |
b |
The secant's slope. |
r |
The circle's radius |
verbose |
Be verbose? |
Value
A matrix of x und y values. For a tangent, both rows are identical,
for a straight line missing the circle, a matrix of NA
.
Examples
secant_intersections(a = 0, b = 1, r = 2)
# A tangent
secant_intersections(a = 2, b = 0, r = 2, verbose = TRUE)
# Missing the circle
secant_intersections(a = 3, b = 0, r = 2)
# Creating a circle boundary approximation
plot(0, 0, col = "red", pch = "+",
xlim = c(-2, 2),
ylim = c(-2, 2))
for (i in seq(-1, 1, by = 0.01)) {
points(secant_intersections(Inf, i, 1), pch = "+")
}
Select Valid Angle Counts Only
Description
The tree data coming with this package was processed by Gerald Kaendler for
the
country of Baden-Wuerttemberg, and is the reference for testing as he
adjusted diameter measurements to breast height where they had been measured
in diverging heights (due to deformations of trees at breast height).
Which we really need to do.
But he also
added trees that are not part of the angle count sampling, which this
function removes. We need that mainly to run tests against the reference
values computed by grenzkreis
because we would not be able to
easily find the keys to merge the data. So this function is probably of
no use to you.
And we remove trees with a diameter at breast height greater than zero and a
distance of 0, for these tree should not be there.
Usage
select_valid_angle_count_trees(x, sample_type = "stp", tree_status = "pk")
Arguments
x |
A tree data set, typically
|
sample_type |
An indicator giving the type of sample the tree was in. 0 marks the angle count sample with counting factor 4. |
tree_status |
An indicator giving the status of a tree in the German national forest inventory. 0 marks ingrowth, 1 marks ongrowth. |
Value
A tree data containing valid angle count trees only.
See Also
Other data functions:
bw2bwi2022de()
Examples
trees <- get(data("trees", package = "treePlotArea"))
subset(trees, entf == 0 & bhd2 > 0 & stp == 0)
angle_counts <- select_valid_angle_count_trees(trees)
subset(angle_counts, entf == 0 & bhd2 > 0 & stp == 0)
Set Default Options for treePlotArea
Description
Just convenience function for options
.
treePlotArea has a set of default options to define the columns of the
data.frames
that are passed to
get_correction_factors
.
See get_defaults
for a description of these options.
Usage
set_options(...)
Arguments
... |
See |
Value
See Also
Other option functions:
get_defaults()
Examples
# Set the default
set_options()
getOption("treePlotArea")
# Overwrite some
option_list <- list(angle_counts = list(dbh = "diameter"),
boundaries = list(boundary_status = "boundart_stat"))
set_options(angle_counts = option_list[["angle_counts"]],
boundaries = option_list[["boundaries"]])
getOption("treePlotArea")$angle_counts$dbh
# restore default
option_list <- get_defaults()
set_options(angle_counts = option_list[["angle_counts"]],
boundaries = option_list[["boundaries"]])
getOption("treePlotArea")$angle_counts$dbh
Throw a Condition
Description
Throws a condition of class c("error", "treePlotArea", "condition").
Usage
throw(message_string, system_call = sys.call(-1), ...)
Arguments
message_string |
The message to be thrown. |
system_call |
The call to be thrown. |
... |
Arguments to be passed to
|
Details
We use this condition as an error dedicated to treePlotArea.
Value
The function does never return anything, it stops with a condition of class c("error", "treePlotArea", "condition").
Angle Count Sampling of the German National Inventory 2022
Description
This is an extract form a data set prepared by Gerald Kaendler. He
added trees that are not part of the angle count sampling,
converted the diameter at breast height from millimeter to centimeter and renamed it,
converted horizontal distance from centimeter to meter and renamed it,
computed correction factors using
grenzkreis
.
Usage
data("trees", package = "treePlotArea")
Format
A data frame with 1121 observations on the following 9 variables. Variables not needed with the package are marked with an asterisk.
tnr
The tract id.
enr
The corner id. A tract may have up to 4 corners on wooden floor.
bnr
The tree id.
bhd2
The diameter at breast height, given in centimeter
.
kf2
* The correction factor given by
grenzkreis
.
entf
The trees' distance from the center of the tract's corner, given in meter.
azi
The azimuth from North, measured in gon (or gradian).
pk
* An indicator giving the type of a tree in the German national forest inventory. 0 marks ingrowth, 1 marks ongrowth.
stp
* An indicator giving the type of sample the tree was in. 0 marks the angle count sample with counting factor 4.
Examples
trees <- get(data("trees", package = "treePlotArea"))
summary(trees)
angle_counts <- bw2bwi2022de(trees)
summary(angle_counts)
Validate Data and Optionally Delete Missing Data
Description
The 2012 data of the federal database contains tract 18063, corner 2.
There are boundaries recorded for that corner, nevertheless tree 14 has no
azimuth measurement. This function therefore checks for the data sets not
having missing
data in the columns needed by get_correction_factors
and
optionally removes affected observations.
It does not cross check whether missing data is really needed (azimuth is
not when there is no boundary recorded for that tracts corner).
Usage
validate_data(x, type = c(NA, "angle_counts", "boundaries"), clean = FALSE)
Arguments
x |
A tree or angle count data set. |
type |
The type of data, stick with the default to let us guess. |
clean |
Omit missing data? If the input contains missing data in the
columns needed by |
Value
A tree data set. The input, if that was valid data, the cleaned input otherwise. Throws an error if columns are missing.
Examples
boundaries <- get(data("boundaries", package = "treePlotArea"))
nrow(boundaries)
nrow(validate_data(x = boundaries))
boundaries[1, "enr"] <- NA
try(validate_data(boundaries))
nrow(validate_data(boundaries, clean = TRUE))
Give the Length of a Vector
Description
A vector given by two points in a plane.
Usage
vector_length(p1, p2 = c(0, 0))
Arguments
p1 |
The first point (x, y). |
p2 |
The second point (x, y). |
Value
The length of the vector.
See Also
Other geometry functions:
get_intersection()
,
points2equation()
Examples
p1 <- c(0, 4)
vector_length(p1)
p2 <- c(3, 4)
vector_length(p1, p2)