SF: Function that can find all available polygones to a point within a certain radius

Hi everyone,

I would like to achieve the below function via SF (or some other packages in R) and I am not sure how to programme it. Basically, assuming there is a point A c(3000, 50000) and a bunch of polygons group B around this point, what I want to do is to first create a polygon that using point A as a circle centre and has a radius of 200 meters (namely Polygone C). Then, I would like to find all available polygons in group B that pass through polygon C.

Maybe an image will make my clarification more clear.

Basically, as you can see in the image, the yellow polygon with a "selected" is the only one selected and the other two polygons that are either out or within polygon C are not selected.

I am wondering if you are aware of any function that can achieve my problem? Thanks very much for your help in advance :slight_smile:

1 Like

What you describe is doable within context of sf package. The only tricky part seems to be selection of polygons intersecting the outer boundary (and not those fully contained). A possible approach for this is to convert your buffer from polygon to a linestring.

For implementation consider this piece of code (adapted from an earlier blogpost on merging geometries):

library(sf)
library(dplyr)
library(ggplot2)

# NC counties as polygons - a shapefile shipped with the sf package
counties <- st_read(system.file("shape/nc.shp", package = "sf"), quiet = T) %>% 
  st_transform(2264) # a feety CRS, to make it interesting :)

# three NC cities as points
points <- data.frame(name = c("Raleigh", "Greensboro", "Wilmington"),
                     x = c(-78.633333, -79.819444, -77.912222),
                     y = c(35.766667, 36.08, 34.223333)) %>% 
  st_as_sf(coords = c("x", "y"), crs = 4326) %>% 
  st_transform(2264) # transform to a feety CRS


# buffer of 50 miles around Raleigh city centre
buffer <- st_buffer(subset(points, name == "Raleigh"), 5280 * 50)


# intersection with buffer as a polygon
counties$close2raleigh <- ifelse(sf::st_intersects(counties, buffer, sparse = F), 
                                 "Yes", 
                                 "No")

ggplot() +
  geom_sf(data = counties, aes(fill = close2raleigh)) +
  geom_sf(data = subset(points, name == "Raleigh"), pch = 4, color = "red") +
  geom_sf(data = buffer, fill = NA, color = "red") +
  scale_fill_viridis_d() +
  theme(legend.position = "bottom") +
  labs(fill = "Close to Raleigh?")

# ring around raleigh (just the ring!)
ring <- buffer %>% 
  st_cast("LINESTRING")

# intersection with buffer as a linestring / edge of polygon
counties$intersects_ring <- ifelse(sf::st_intersects(counties, ring, sparse = F), 
                                 "Yes", 
                                 "No")

ggplot() +
  geom_sf(data = counties, aes(fill = intersects_ring)) +
  geom_sf(data = subset(points, name == "Raleigh"), pch = 4, color = "red") +
  geom_sf(data = buffer, fill = NA, color = "red") +
  scale_fill_viridis_d() +
  theme(legend.position = "bottom") +
  labs(fill = "Close to Raleigh?")

4 Likes

Hi Jindra,

Thanks very much for your detailed answers! It is a really good tutorial and very friendly to users that are new to sf (like me). I tried the code and it works really well :slight_smile: Thanks very much for your kind help!

1 Like

Glad to be of service! :slight_smile:

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.