inst/doc/theory.R

## ----include = FALSE----------------------------------------------------------
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  dev = "svglite",
  fig.ext = "svg",
  fig.width = 7,
  fig.height = 5
)
# Save par settings and restore on exit (CRAN policy)
oldpar <- par(no.readonly = TRUE)
knitr::knit_hooks$set(document = function(x) { par(oldpar); x })

## ----classification, echo=FALSE, fig.cap="Point classification by AoE. Core points (green) are inside the original support. Halo points (orange) are in the expanded region. Points outside the AoE are pruned."----
library(sf)
library(areaOfEffect)

# Create support
support <- st_as_sf(
  data.frame(id = 1),
  geometry = st_sfc(st_polygon(list(
    cbind(c(2, 8, 8, 2, 2), c(2, 2, 8, 8, 2))
  ))),
  crs = 32631
)

# Use aoe() to get proper AoE geometry
dummy_pt <- st_as_sf(
  data.frame(id = 1),
  geometry = st_sfc(st_point(c(5, 5))),
  crs = 32631
)
aoe_result <- aoe(dummy_pt, support)
aoe_geom <- aoe_geometry(aoe_result, "aoe")

# Create random points
set.seed(42)
n_pts <- 50
pts_coords <- cbind(
  runif(n_pts, -2, 12),
  runif(n_pts, -2, 12)
)
pts <- st_as_sf(
  data.frame(id = 1:n_pts),
  geometry = st_sfc(lapply(1:n_pts, function(i) st_point(pts_coords[i, ]))),
  crs = 32631
)

# Classify
in_support <- st_intersects(pts, support, sparse = FALSE)[, 1]
in_aoe <- st_intersects(pts, aoe_geom, sparse = FALSE)[, 1]

pts$class <- ifelse(in_support, "core",
                    ifelse(in_aoe, "halo", "pruned"))

# Plot
par(mar = c(2, 2, 2, 2), bty = "n")
plot(st_geometry(aoe_geom), border = "steelblue", lty = 2,
     xlim = c(-3, 13), ylim = c(-3, 13), asp = 1)
plot(st_geometry(support), border = "black", lwd = 2, add = TRUE)
points(pts_coords[pts$class == "pruned", ], col = "gray60", pch = 4, cex = 0.8)
points(pts_coords[pts$class == "halo", ], col = "darkorange", pch = 16)
points(pts_coords[pts$class == "core", ], col = "forestgreen", pch = 16)
legend("topright",
       legend = c("Core", "Halo", "Pruned", "Original", "AoE"),
       col = c("forestgreen", "darkorange", "gray60", "black", "steelblue"),
       pch = c(16, 16, 4, NA, NA),
       lty = c(NA, NA, NA, 1, 2),
       lwd = c(NA, NA, NA, 2, 1))

## ----mask-concept, echo=FALSE, fig.cap="Hard boundaries constrain the AoE. The dashed line shows the theoretical AoE; the gray area shows the AoE after applying a land mask."----
# Create a coastal support
support_coastal <- st_as_sf(
  data.frame(id = 1),
  geometry = st_sfc(st_polygon(list(
    cbind(c(4, 8, 8, 4, 4), c(2, 2, 6, 6, 2))
  ))),
  crs = 32631
)

# Land mask (irregular coastline)
land <- st_as_sf(
  data.frame(id = 1),
  geometry = st_sfc(st_polygon(list(cbind(
    c(0, 10, 10, 7, 5, 3, 0, 0),
    c(0, 0, 5, 6, 5.5, 7, 6, 0)
  )))),
  crs = 32631
)

# Create dummy point and run aoe WITHOUT mask to get theoretical AoE
dummy_coastal <- st_as_sf(
  data.frame(id = 1),
  geometry = st_sfc(st_point(c(6, 4))),
  crs = 32631
)
result_unmasked <- aoe(dummy_coastal, support_coastal)
aoe_theoretical <- aoe_geometry(result_unmasked, "aoe")

# Run aoe WITH mask to get constrained AoE
result_coastal <- aoe(dummy_coastal, support_coastal, mask = land)
aoe_masked <- aoe_geometry(result_coastal, "aoe")

par(mar = c(2, 2, 2, 2), bty = "n")
plot(st_geometry(land), col = NA, border = "steelblue", lwd = 2,
     xlim = c(-1, 11), ylim = c(-1, 9), asp = 1)
# Show theoretical AoE as dashed outline
plot(st_geometry(aoe_theoretical), border = "gray50", lty = 2, lwd = 1.5, add = TRUE)
# Show masked AoE as gray fill
plot(st_geometry(aoe_masked), col = rgb(0.5, 0.5, 0.5, 0.3), border = NA, add = TRUE)
plot(st_geometry(support_coastal), border = "black", lwd = 2, add = TRUE)

# Add "SEA" label in the water area
text(9, 7.5, "SEA", col = "steelblue", font = 2, cex = 1.2)

legend("topleft",
       legend = c("Support", "Theoretical AoE", "AoE (masked)", "Coastline"),
       col = c("black", "gray50", "gray50", "steelblue"),
       lty = c(1, 2, NA, 1),
       lwd = c(2, 1.5, NA, 2),
       pch = c(NA, NA, 15, NA),
       pt.cex = c(NA, NA, 2, NA))

Try the areaOfEffect package in your browser

Any scripts or data that you put into this service are public.

areaOfEffect documentation built on Feb. 7, 2026, 1:08 a.m.