Grid geometry and polygon weights
Source:vignettes/oceancube-geometry-weights.Rmd
oceancube-geometry-weights.Rmdoceancube exposes geometry primitives for rectilinear
grids. Horizontal areas use geodesic polygon areas; vertical bounds must
be explicit or available in unambiguous cube metadata. These functions
do not read ocean values.
library(oceancube)
x <- ocean_cube(
lon = c(-80.5, -79.5), lat = c(-12.5, -11.5),
depth = structure(c(5, 15), units = "m", positive = "down"),
time = as.Date("2020-01-01"),
data = array(1:8, c(2, 2, 2, 1, 1)), vars = "temperature"
)
thickness <- cube_layer_thickness(x, depth_bounds = c(0, 10, 20), unit = "m")
thickness
#> 5 15
#> 10 10
#> attr(,"unit")
#> [1] "m"
#> attr(,"bounds_source")
#> [1] "argument"
#> attr(,"positive")
#> [1] "down"
#> attr(,"coverage_contiguous")
#> [1] TRUE
#> attr(,"geometry_status")
#> [1] "GEOMETRY_METRIC_BOUNDS_SUPPORTED"
#> attr(,"certification_status")
#> [1] "UNCERTIFIED"Horizontal area, volume, masks, and polygon weights require the
optional sf package. The example stays offline and uses a
tiny polygon.
if (requireNamespace("sf", quietly = TRUE)) {
area <- cube_cell_area(x, unit = "km2")
volume <- cube_cell_volume(
x, depth_bounds = c(0, 10, 20), unit = "km3"
)
polygon <- sf::st_as_sf(
data.frame(id = "region", wkt =
"POLYGON ((-81 -13, -79 -13, -79 -11, -81 -11, -81 -13))"),
wkt = "wkt", crs = 4326
)
masked <- cube_mask(x, polygon)
weights_2d <- cube_polygon_weights(x, polygon, id_col = "id")
weights_3d <- cube_polygon_weights(
x, polygon, id_col = "id", dimension = "3d",
depth_bounds = c(0, 10, 20)
)
area
volume
masked$mask
weights_2d
weights_3d
}
#> feature_id feature_order longitude_index latitude_index cell_index longitude
#> 1 region 1 1 1 1 -80.5
#> 2 region 1 1 1 1 -80.5
#> 3 region 1 2 1 2 -79.5
#> 4 region 1 2 1 2 -79.5
#> 5 region 1 1 2 3 -80.5
#> 6 region 1 1 2 3 -80.5
#> 7 region 1 2 2 4 -79.5
#> 8 region 1 2 2 4 -79.5
#> latitude lon_min lon_max lat_min lat_max cell_area_m2 overlap_area_m2
#> 1 -12.5 -81 -80 -13 -12 12071376182 12071376182
#> 2 -12.5 -81 -80 -13 -12 12071376182 12071376182
#> 3 -12.5 -80 -79 -13 -12 12071376182 12071376182
#> 4 -12.5 -80 -79 -13 -12 12071376182 12071376182
#> 5 -11.5 -81 -80 -12 -11 12116249629 12106328908
#> 6 -11.5 -81 -80 -12 -11 12116249629 12106328908
#> 7 -11.5 -80 -79 -12 -11 12116249629 12106328908
#> 8 -11.5 -80 -79 -12 -11 12116249629 12106328908
#> fraction_cell_covered effective_area_m2 polygon_area_m2
#> 1 1.0000000 12071376182 48378457250
#> 2 1.0000000 12071376182 48378457250
#> 3 1.0000000 12071376182 48378457250
#> 4 1.0000000 12071376182 48378457250
#> 5 0.9991812 12106328908 48378457250
#> 6 0.9991812 12106328908 48378457250
#> 7 0.9991812 12106328908 48378457250
#> 8 0.9991812 12106328908 48378457250
#> intersected_grid_area_m2 fraction_polygon_covered_by_grid depth_index depth
#> 1 48355410181 0.9995236 1 5
#> 2 48355410181 0.9995236 2 15
#> 3 48355410181 0.9995236 1 5
#> 4 48355410181 0.9995236 2 15
#> 5 48355410181 0.9995236 1 5
#> 6 48355410181 0.9995236 2 15
#> 7 48355410181 0.9995236 1 5
#> 8 48355410181 0.9995236 2 15
#> depth_min depth_max layer_thickness_m cell_volume_m3 effective_volume_m3
#> 1 0 10 10 120713761821 120713761821
#> 2 10 20 10 120713761821 120713761821
#> 3 0 10 10 120713761821 120713761821
#> 4 10 20 10 120713761821 120713761821
#> 5 0 10 10 121162496288 121063289082
#> 6 10 20 10 121162496288 121063289082
#> 7 0 10 10 121162496288 121063289082
#> 8 10 20 10 121162496288 121063289082cube_mask() uses cell-centre membership and changes cube
values outside the selected coverage.
cube_polygon_weights() instead calculates feature-specific
cell intersections and returns self-contained merge keys, areas,
fractions, and—when requested—volumes. It does not aggregate variables
or calculate an indicator. Indicator definitions, normalization,
uncertainty, and inference belong to spatind.
The 0.2.0 core supports geographic rectilinear grids and deliberately rejects unsafe or ambiguous geometry, including unsupported antimeridian cases.