Reputation: 21
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
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)
# 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)
Upvotes: 2