SteveH
SteveH

Reputation: 21

Intersecting polygons from two sf objects sharing a common attribute (unique and one-to-one)

I have two sf objects that each contains 3 polygons (circles). Each polygon in each object has a unique, one-to-one identifier ('name'). I want to intersect these two objects so that it returns an object of the same length where each geometry is the intersection of the two polygons with the same name. For instance, the resulting geometry A will be the intersection of geometry A from the first sf object with geometry A of the second object. This is easily done in QGIS, but I'm trying to automate that workflow.

Here is some code that creates three circles in a simple xy space. How can I intersect pts_a with pts_b as described?

I've tried st_intersects and aggregate

(I'm only a few days into R, so I don't really know how to format these questions properly - thanks for your help)

library(sf)
#create some XY coordinates
pts_a <- (matrix(c(1,1,3,2,5,3),nrow=3,ncol=2))
pts_b <- (matrix(2:7,nrow=3,ncol=2))

#convert to a data frame
pts_a <- data.frame(pts_a)
pts_b <- data.frame(pts_b)

#set values to numbers, create a points object and add point names for pts_a
pts_a$X1 <- as.numeric(pts_a$X1) 
pts_a$X2 <- as.numeric(pts_a$X2) 
pts_a <- st_as_sf(pts_a,coords=c('X1','X2'))
pts_a <- cbind(pts_a,c('A','B','c'))

#set values to numbers, create a points object and add point names for pts_b
pts_b$X1 <- as.numeric(pts_b$X1) 
pts_b$X2 <- as.numeric(pts_b$X2) 
pts_b <- st_as_sf(pts_b,coords=c('X1','X2'))
pts_b <- cbind(pts_b,c('A','B','c'))

#rename columns
colnames(pts_a) <- c('name','geometry')
colnames(pts_b) <- c('name','geometry')

#create polygons (circles of radius 2)
pts_a <- st_buffer(pts_a,2)
pts_b <- st_buffer(pts_b,2)```

This is where I'm stuck after having tried a number of approaches.

Upvotes: 2

Views: 2834

Answers (1)

dieghernan
dieghernan

Reputation: 3402

You want to use st_intersection(), that returns the spatial intersection. st_intersects() return a logical indicating wheter there are a intersection or not of the objects, this is a pretty common error due to the the similarity of names.

If I understood properly your desired output, after st_intersection() you may need just to filter out those intersections of the objects that have the same name (note that after intersecting the final result has the values of object pts_a and pts_b).

I think in your example "c" objects on pts_a and pts_b does not intersect.

library(sf)
#create some XY coordinates
pts_a <- (matrix(c(1,1,3,2,5,3),nrow=3,ncol=2))
pts_b <- (matrix(2:7,nrow=3,ncol=2))

#convert to a data frame
pts_a <- data.frame(pts_a)
pts_b <- data.frame(pts_b)

#set values to numbers, create a points object and add point names for pts_a
pts_a$X1 <- as.numeric(pts_a$X1) 
pts_a$X2 <- as.numeric(pts_a$X2) 
pts_a <- st_as_sf(pts_a,coords=c('X1','X2'))
pts_a <- cbind(pts_a,c('A','B','c'))

#set values to numbers, create a points object and add point names for pts_b
pts_b$X1 <- as.numeric(pts_b$X1) 
pts_b$X2 <- as.numeric(pts_b$X2) 
pts_b <- st_as_sf(pts_b,coords=c('X1','X2'))
pts_b <- cbind(pts_b,c('A','B','c'))

#rename columns
colnames(pts_a) <- c('name','geometry')
colnames(pts_b) <- c('name','geometry')

#create polygons (circles of radius 2)
pts_a <- st_buffer(pts_a,2)
pts_b <- st_buffer(pts_b,2)

# Use st_intersection
inter <- st_intersection(pts_a, pts_b)

# Keep only those intersections of objects with the same name
# i.e A = A, B = B
inter_end <- inter[inter$name == inter$name.1, ]


plot(inter_end)

enter image description here

# Visual check with ggplot2


library(ggplot2)

ggplot() +
  geom_sf(data = pts_a, aes(fill=name), alpha=0.5)+
  geom_sf(data = pts_b, aes(fill=name), alpha=0.5) +
  geom_sf(data = inter_end, fill=NA, color="red", size=2)

enter image description here

Upvotes: 2

Related Questions