Is there a way to draw a polygon with specified point order ? (I now use the sf package in R)

Viewed 125

I run the following code under the following environment:

R: 4.1.0

packages: sf : 1.0.0 dplyr : 1.0.7

After looking at https://gis.stackexchange.com/questions/280671/r-create-multipolygon-from-overlapping-polygons-using-sf-package , I was trying to play with sf package and I ran into some problems.

The problem I met is with the following code :

library(sf)
library(dplyr)
poly <- data.frame(
  lon = c(0, 1, 1, 0, 0.5),
  lat = c(0, 0, 1, 1, 0.5),
  var = c(1, 1, 1, 1, 1)
) %>%
  st_as_sf(coords = c("lon", "lat"), dim = "XY") %>% st_set_crs(4326) %>% 
  group_by(var) %>%
  summarise() %>% st_cast("POLYGON")
plot(poly)

The output plot of the code is the following

, and I thought it will follow the order of the original dataframe to create the polygon. i.e. (0,0) -> (1,0) -> (1,1) -> (0,1) -> (0.5,0.5) -> (0,0), which should look like this picture.

I was wondering if there is a way to specify the order of the point connections? I have use set_convex_hull() in this example but the output will just be a square, which makes sense because of the definition of convex hull. I have looked through the sf documentation website https://r-spatial.github.io/sf/articles/sf1.html but still cannot find the solution for this. I feel like I must have missed some key words or directions when researhing the use of this package. If anyone has any advice, it will be much appreciated.

1 Answers

I've always found building polygons from data.frames tricky, so I wrote the sfheaders library to make this easier

library(sf)
library(sfheaders)

poly <- data.frame(
  lon = c(0, 1, 1, 0, 0.5),
  lat = c(0, 0, 1, 1, 0.5),
  var = c(1, 1, 1, 1, 1)
)

sf <- sfheaders::sf_polygon(
  obj = poly
  , x = "lon"
  , y = "lat"
  , keep = T  ## To keep the 'var' variable
) 

sf

# Simple feature collection with 1 feature and 1 field
# Geometry type: POLYGON
# Dimension:     XY
# Bounding box:  xmin: 0 ymin: 0 xmax: 1 ymax: 1
# CRS:           NA
#   var                       geometry
# 1   1 POLYGON ((0 0, 1 0, 1 1, 0 ...

This uses and maintains the order of the coordinates in the input data.frame.

plot( sf )

enter image description here


You will need to set the CRS on this object if you want to do any calculations / geometric operations

sf::st_crs(sf) <- 4326
Related