## ----include = FALSE----------------------------------------------------------
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  tidy = FALSE
)

## ----setup--------------------------------------------------------------------
library(osbng)
library(sf)

## ----loader-------------------------------------------------------------------
# Read the Office for National Statistics (ONS) England Regions GeoPackage
# Create an sf data frame
# See examples/data/metadata.json for more information about the data source
gdf <- st_read(
  system.file("extdata", 
              "London_Regions_December_2024_Boundaries_EN_BFC.gpkg", 
              package = "osbng"), 
  quiet = TRUE)

# Filter the data frame columns
gdf_london <- gdf[, c("RGN24CD", "RGN24NM")]

# Return the data frame
gdf_london

## ----crs----------------------------------------------------------------------
# osbng indexing functions require geometry coordinates to be specified 
# in British National Grid (BNG) (OSGB36) cordinate reference system
# EPSG:27700
# https://epsg.io/27700
st_crs(gdf_london)

## ----geom_to_bng--------------------------------------------------------------
# Return the BNG grid squares intersected by the London Region
# Uses `geom_to_bng()`
# Uses a 5km grid square resolution
# Returns a list of `BNGRefernce` objects for each geometry
gdf_london$bng_ref_5km <- geom_to_bng(gdf_london, resolution = "5km")

## ----expanding----------------------------------------------------------------
# Expand the bng_ref_5km column to separate rows for each BNG Reference object
df <- data.frame(id = rep(seq_len(nrow(gdf_london)), 
                          lengths(gdf_london$bng_ref_5km)), 
                 bng_ref_5km = as_bng_reference(unlist(gdf_london$bng_ref_5km)))

# Create a data frame of London and combine with BNG observations
df_london <- st_drop_geometry(gdf_london)

# Drop the original bng_ref_5km column
df_london <- df_london[, !names(df_london) %in% c("bng_ref_5km")]

df_london <- cbind(df_london[df$id, ], df)

## ----expanding_alt, eval=FALSE------------------------------------------------
#  # Alternative approach requiring `tidyr` - NOT RUN
#  
#  df_london <- gdf_london %>%
#    unnest(bng_ref_5km) %>%
#    st_drop_geometry()

## ----get_geometry-------------------------------------------------------------
# Using the data frame with the set of BNG grid squares
# Get the geometry for each grid square
df_london$geometry <- bng_to_grid_geom(df_london$bng_reference, format = "sf")

# Convert this data frame to an `sf` object with the grid square geometry
gdf_london_exp <- st_sf(df_london)

# Return the first few rows
head(gdf_london_exp)

## ----map_bng, fig.height=6.5, fig.width=6.5, warning=FALSE--------------------
# Plot the original London Region
plot(st_geometry(gdf_london), 
     col = "#ffc61e", 
     border = "#fff",
     main = "BNG Grid Squares at 5km Resolution Intersected by London Region",
     cex.main = .8, 
     extent = st_bbox(gdf_london_exp))

# Add the indexed and exploded London regions
plot(st_geometry(gdf_london_exp), 
     col = NA, 
     border = "#333333", 
     add = TRUE)

# Add feature labels at grid square centroids
coords <- st_coordinates(st_centroid(gdf_london_exp))
text(coords[, 1],
     coords[, 2],
     gdf_london_exp$bng_reference, cex = 0.4)


## ----expanding_decompose------------------------------------------------------
# Create a new data frame of the London Region
# Filter the data frame columns
gdf_london <- gdf[, c("RGN24CD", "RGN24NM")]

# Decompose the London Region into a simplified representation
# bounded by its presence in each BNG grid square at a 5km resolution
# Uses the gdf_to_bng_geom_intersection_explode; sf required
gdf_london_exp <- geom_to_bng_intersection_explode(gdf_london, 
                                                   resolution = "5km")

head(gdf_london_exp)

## ----viz_is_core, fig.height=6.5, fig.width=6.5, warning=FALSE----------------
# Plot the indexed and expanded London Region spatial data frame
plot(gdf_london_exp["is_core"],
     border = "#fff",
     col = c("#009ade", "#ff1f5b")[gdf_london_exp$is_core + 1],
     main = "Decomposition of the London Region into BNG Grid Squares at 5km Resolution",
     cex.main = .75)

legend(0.8, 0.3,
       title = "is_core",
       legend = c("True", "False"),
       fill = c("#ff1f5b", "#009ade"))

## ----decompose_london_alt-----------------------------------------------------
# Create a new data frame of the London Region
# Filter the data frame columns
gdf_london <- gdf[, c("RGN24CD", "RGN24NM")]

# Decompose the London Region intoa simplified representation bounded by its
# presence in each BNG grid square at a 5km resolution.
# Uses the geom_to_bng_intersection function
# Returns a list of nested lists
gdf_london$bng_ref_5km <- geom_to_bng_intersection(gdf_london, 
                                                   resolution = "5km")

# Drop original geometry column
gdf_london <- st_drop_geometry(gdf_london)

## ----expanding_decompose_alt, eval=FALSE--------------------------------------
#  # Alternative syntax - NOT RUN
#  # Expand the bng_ref_5km column to separate rows for each object.
#  gdf_london <- cbind("RGN24CD" = gdf_london[, c("RGN24CD")],
#                      data.frame(gdf_london$bng_ref_5km))
#  
#  # Convert this data frame to an `sf` object with the grid square geometry
#  gdf_london_exp <- st_sf(gdf_london)
#  
#  # Return the first few rows of the GeoDataFrame
#  head(gdf_london_exp)

## ----expanding_decompose_alt2, eval=FALSE-------------------------------------
#  # Alternative approach requiring `tidyr` - NOT RUN
#  gdf_london_exp <- gdf_london %>%
#    unnest_wider(bng_ref_5km) %>%
#    unnest(cols = c(BNGReference, is_core, geom)) %>%
#    st_sf()

