Problem with creating buffer zones

I want to create bufferzones around certain points. the bufferzones should be within 250, 250 to 500 and 500 to 1000m around the points. my problem is, that the bigger bufferzones dont subtract the unwanted distances. what do i do wrong?

#Bufferzones

First, i converted the two datasets (the first one contains the points, the second one the layer, a city map):

Geodaten_Anlagen_sf_utm <- st_transform(Geodaten_Anlagen_sf, crs = 32633)
dat_sf_utm <- st_transform(dat_sf, crs = 32633)

then i created the bufferzones:

bufferzone_250 <- st_buffer(Geodaten_Anlagen_sf_utm, dist = 250)
bufferzone_250_to_500 <- st_buffer(Geodaten_Anlagen_sf_utm, dist = 500) %>%
st_difference(st_buffer(Geodaten_Anlagen_sf_utm, dist = 250))
bufferzone_500_to_1000 <- st_buffer(Geodaten_Anlagen_sf_utm, dist = 1000) %>%
st_difference(st_buffer(Geodaten_Anlagen_sf_utm, dist = 500))

buffer_250 <- st_make_valid(bufferzone_250)
buffer_250_to_500 <- st_make_valid(bufferzone_250_to_500)
buffer_500_to_1000 <- st_make_valid(bufferzone_500_to_1000)

inside_250 <- st_intersects(Geodaten_Anlagen_sf_utm, bufferzone_250)
inside_250_to_500 <- st_intersects(Geodaten_Anlagen_sf_utm, bufferzone_250_to_500)
inside_500_to_1000 <- st_intersects(Geodaten_Anlagen_sf_utm, bufferzone_500_to_1000)

when i test the buffer zones with the following plot, i can see that the unwanted distances didnt substract:
ggplot() +
geom_sf(data = dat_sf_utm) +
geom_sf(data = bufferzone_250_to_500, fill = 'lightblue', alpha = 0.2) +
geom_sf(data = Geodaten_Anlagen_sf_utm, color = "red", size = 1) +
labs(title = "test") +
theme_minimal()

obviously there is sth wrong but i dont understand.

another hint that there is a mistake somewhere: the count of observations in bufferzone 250 to 500 isequal to the zone 500 to 1000.

Can somebody help?

Thanks a lot,
Christina

Hi @Molting

the function st_difference doesn't do what we would expect - take elementwise differences of the buffered polygons. It does some type of difference between all combinations of polygons.

So i wrote a helper function that does what I would expect - only take the differences for every pair of polygons.

library(sf)

# get some random data since i don't have yours
Geodaten_Anlagen_sf_utm

# then i created the bufferzones:
bufferzone_250 <- st_buffer(Geodaten_Anlagen_sf_utm, dist = 250) %>% st_geometry() %>% st_make_valid()
bufferzone_500 <- st_buffer(Geodaten_Anlagen_sf_utm, dist = 500) %>% st_geometry() %>% st_make_valid()
bufferzone_1000 <- st_buffer(Geodaten_Anlagen_sf_utm, dist = 1000) %>% st_geometry() %>% st_make_valid()

# custom function to do element-wise  st_difference
custom_st_difference <- function(x,y){
  # needs to be same size
  stopifnot(length(x) == length(y))
  # do st_difference one by one instad of default all with all 
  temp <- lapply(1:length(x), function(idx){
    st_difference(x[[idx]], y[[idx]])
  })
  # return expected object type
  st_as_sfc(temp, crs = 32633)
}

bufferzone_250_to_500 <- custom_st_difference(bufferzone_500, bufferzone_250)
bufferzone_500_to_1000 <- custom_st_difference(bufferzone_1000, bufferzone_500)

# final plot
ggplot() +
geom_sf(data = bufferzone_250_to_500,fill = 'blue', alpha = 0.5) +
geom_sf(data = bufferzone_500_to_1000,fill = 'green', alpha = 0.5) +
geom_sf(data = Geodaten_Anlagen_sf_utm, color = "red", size = 1) +
labs(title = "test") +
theme_minimal()

Result:

Hope it helps.

1 Like

Hi @vedoa,

it worked :heart_eyes: :

thank you so much!

This topic was automatically closed 21 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.