library(sf)
## Linking to GEOS 3.5.1, GDAL 2.2.2, proj.4 4.9.2
bb <- st_bbox(c(xmin = -125.0, xmax = -121.8, ymax = 40.9, ymin = 38.4))
st_as_text(st_as_sfc(bb))
## [1] "POLYGON ((-125 38.4, -121.8 38.4, -121.8 40.9, -125 40.9, -125 38.4))"
# data is a single rectangle, lower left coordinate is first
# key thing in WKT print-out or matrix print-out is change from
# first X to second X, -125 then -121.8 is anti-clockwise
# below we see first to second X (-125) doesn't change as is clockwise
#WKT: [1] "POLYGON ((-125 38.4, -121.8 38.4, -121.8 40.9, -125 40.9, -125 38.4))"
## anti-clock is valid
apoly <- st_as_sfc(bb)
apoly %>% st_is_valid()
## [1] TRUE
apoly[[1]][[1]] ## anti-clockwise
## [,1] [,2]
## [1,] -125.0 38.4
## [2,] -121.8 38.4
## [3,] -121.8 40.9
## [4,] -125.0 40.9
## [5,] -125.0 38.4
## clockwise is valid
cpoly <- apoly
cpoly[[1]][[1]] <- cpoly[[1]][[1]][5:1, ]
cpoly[[1]][[1]] ## clockwise
## [,1] [,2]
## [1,] -125.0 38.4
## [2,] -125.0 40.9
## [3,] -121.8 40.9
## [4,] -121.8 38.4
## [5,] -125.0 38.4
cpoly %>% st_is_valid()
## [1] TRUE
## cast to other form and nothing changes
apoly %>% st_cast("MULTIPOLYGON")
## Geometry set for 1 feature
## geometry type: MULTIPOLYGON
## dimension: XY
## bbox: xmin: -125 ymin: 38.4 xmax: -121.8 ymax: 40.9
## epsg (SRID): NA
## proj4string: NA
## MULTIPOLYGON (((-125 38.4, -121.8 38.4, -121.8 ...
cpoly %>% st_cast("MULTIPOLYGON")
## Geometry set for 1 feature
## geometry type: MULTIPOLYGON
## dimension: XY
## bbox: xmin: -125 ymin: 38.4 xmax: -121.8 ymax: 40.9
## epsg (SRID): NA
## proj4string: NA
## MULTIPOLYGON (((-125 38.4, -125 40.9, -121.8 40...
## but decompose to whatever primitive form GEOS uses and
## we get clockwise preferred
(apoly %>% st_buffer(dist = 0))[[1]][[1]]
## [,1] [,2]
## [1,] -125.0 38.4
## [2,] -125.0 40.9
## [3,] -121.8 40.9
## [4,] -121.8 38.4
## [5,] -125.0 38.4
(cpoly %>% st_buffer(dist = 0))[[1]][[1]]
## [,1] [,2]
## [1,] -125.0 38.4
## [2,] -125.0 40.9
## [3,] -121.8 40.9
## [4,] -121.8 38.4
## [5,] -125.0 38.4