Forest of Dean — Plot-Level Tree Metrics

Author

Miguel Ibañez Alvarez

Published

1 September 2026

Forest Research

1 Overview

This document summarises tree-level measurements (height, DBH, volume) by survey plot.

For each plot we calculate:

  • Number of trees (point count inside the polygon)
  • Median tree height
  • median DBH
  • Total (summed) volume
Show code
library(tidyverse)
library(sf)
library(leaflet)
library(gt)

2 Load the data

Show code
plots <- st_read("Shapefiles/plots_FoD.shp", quiet = TRUE)
trees <- st_read("Shapefiles/trees_FoD.shp", quiet = TRUE)

plots
Id geometry
1 POLYGON ((363425.2 211843.7…
2 POLYGON ((362963.5 210367.9…
3 POLYGON ((363719.7 211586.5…
4 POLYGON ((362332 211155.4, …
Show code
trees_in_plots <- trees |>
  st_join(plots, join = st_within) |>
  # Trees are only relevant here if they fall inside a plot
  filter(!is.na(Id))

3 Metrics by plot

Show code
plot_metrics <- trees_in_plots |>
  st_drop_geometry() |>
  group_by(Id) |>
  summarise(
    n_trees = n(),
    median_height_m = median(TreHght, na.rm = TRUE),
    median_dbh_cm = median(DBH, na.rm = TRUE),
    total_volume_m3 = sum(Volume, na.rm = TRUE),
    .groups = "drop"
  ) |>
  arrange(Id)

plot_metrics
Id n_trees median_height_m median_dbh_cm total_volume_m3
1 143 16.4 19.7 36.799
2 93 28.2 35.0 111.917
3 103 25.4 31.7 93.496
4 99 32.1 38.1 225.372
Show code
plot_metrics |>
  gt() |>
  fmt_number(columns = c(median_height_m, median_dbh_cm, total_volume_m3), decimals = 1) |>
  cols_label(
    Id = "Plot Id",
    n_trees = "No. of trees",
    median_height_m = "Median height (m)",
    median_dbh_cm = "Median DBH (cm)",
    total_volume_m3 = "Total volume (m³)"
  ) |>
  tab_header(title = "Tree metrics by plot")

4 Map of the plots

Show code
plots_wgs <- st_transform(plots, 4326)

# Attach the summary metrics to each polygon so they can be shown on click
plots_labelled <- plots_wgs |>
  left_join(plot_metrics, by = "Id") |>
  mutate(
    popup = sprintf(
      "<b>Plot %s</b><br>No. of trees: %d<br>Median height: %.1f m<br>Median DBH: %.1f cm<br>Total volume: %.2f m³",
      Id, n_trees, median_height_m, median_dbh_cm, total_volume_m3
    )
  )

leaflet(plots_labelled) |>
  addProviderTiles(providers$Esri.WorldImagery) |>
  addPolygons(
    color = "orange",
    weight = 3,
    fillOpacity = 0.15,
    popup = ~popup,
    label = ~paste("Plot", Id),
    highlightOptions = highlightOptions(weight = 5, fillOpacity = 0.35)
  ) |>
  addLabelOnlyMarkers(
    data = st_centroid(plots_labelled),
    label = ~as.character(Id),
    labelOptions = labelOptions(
      noHide = TRUE,
      direction = "center",
      textOnly = TRUE,
      style = list("font-weight" = "bold", "font-size" = "16px", "color" = "white")
    )
  )