--- title: "Introducing: the POLYGON FULL" author: "Edzer Pebesma" date: "11 October 2024" comments: false layout: post categories: r --- TOC [DOWNLOADHERE] ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE, fig.align = 'center') ``` ## Summary This post introduces the `POLYGON FULL` geometry, new in `sf` 1.0-18 which appeared on CRAN Today. ## Why? Polygons delineate a two-dimensional bound _area_. The OGC [simple feature access standard](https://portal.ogc.org/files/?artifact_id=25355) defines besides the regular `POLYGON` and `MULTIPOLYGON` (a set of polygons) also the `POLYGON EMPTY` and `MULTIPOLYGON EMPTY`, which can both be thought of as "no points". There is however nothing polygonal about "no points", you can read more about this in [Even Rouault's blog entry](https://erouault.blogspot.com/2024/09/those-concepts-in-geospatial-field-that.html). Although the simple feature standard does not explicitly state this, it was clearly developed [for flat, planar geometries](https://r-spatial.org/book/04-Spherical.html). The Earth however is round, and doing geometrical operations e.g. on the two-dimensional surface of a sphere changes many things. One of them is that the total, entire surface is also a bound area. To denote that area, since `sf` 1.0-18 we can now use `POLYGON FULL`. ## How? As [of 2020](https://r-spatial.org/r/2020/06/17/s2.html), R package `sf` uses the R packgae `s2` and the `s2geometry` library for computations on geometries with geodetic (unprojected) coordinates, unless it is told not to do so (and assume a flat Earth) by ```{r} library(sf) sf_use_s2(FALSE) ``` The `s2geomety` library uses the concept of a `POLYGON FULL`, and represents it internally by `POLYGON((0 -90, 0 -90))`. Package `sf` also does this: ```{r} sf_use_s2(TRUE) (p = st_as_sfc("POLYGON FULL", crs = 'OGC:CRS84')) ``` If `s2` is switched off, this geometry is not recognized as a `POLYGON FULL` but instead is printed as the `POLYGON((0 -90, 0 -90))`: ```{r} sf_use_s2(FALSE) p ``` which obviously is not a valid polygon ```{r} st_is_valid(p) ``` and will lead to errors when used, e.g. in ```{r error=TRUE} st_make_valid(p) ``` When using `s2`, it works nicely: ```{r} sf_use_s2(TRUE) st_is_full(p) st_is_empty(p) st_is_valid(p) pt = st_as_sfc("POINT(7 52)", crs = 'OGC:CRS84') st_intersects(p, pt) st_intersection(p, pt) st_distance(p, pt) st_area(p) |> units::set_units(km^2) # spherical approximation st_bbox(p) ``` ## Examples A more full example is described in [this vignette](https://r-spatial.github.io/sf/articles/sf7.html#polygons-on-s2-divide-the-sphere-in-two-parts), yielding this figure: ```{r polygonfull} options(s2_oriented = TRUE) # don't change orientation from here on co = st_as_sf(s2::s2_data_countries()) g = st_as_sfc("POLYGON FULL", crs = 'EPSG:4326') oc = st_difference(g, st_union(co)) # oceans b = st_buffer(st_as_sfc("POINT(-30 52)", crs = 'EPSG:4326'), 9800000) # visible half i = st_intersection(b, oc) # visible ocean plot(st_transform(i, "+proj=ortho +lat_0=52 +lon_0=-30"), col = 'blue') ``` Some more discussion leading to the current implementation is found in this [sf issue](https://github.com/r-spatial/sf/issues/2441).