sf
패키지는 공간 영역간에 겹치는 부분, 혹은 그 특정 경계내에만 위치하는 특정 공간을 표시하는 등의 공간간 연산 작업을 아주 쉽게 수행할 수 있도록 기능을 제공하고 있다. 예를 들어 특정 프랜차이즈 가맹점을 전국 지도에 x 로 모두 표시했는데, 서울 영등포구안에 있는 가맹점만 지도에 표시하고 싶을 때, sf
패지키의 공간간의 관계연산을 통해 쉽게 필터링 할 수 있다.
단순한 예시지만, 특정 경계를 기준으로 바깥 공간들과 내부 공간을 나누어 그릴 수 있다.
이전에 벤다이어그램을 이용해서 교집합, 합집합, 차집합을 구현해보았었는데, 아래 글도 참조하는게 좋다.
공간 정의
임의로 공간을 정의해보려한다. 첫번째로 삼각형 2개가 있는 공간이다. 삼각형 한개당 list 하나에 담는데, (x,y) 좌표를 기준으로 점과 점사이를 선으로 잇는다고 생각하면 된다.
sf_sam1 = list(list(rbind(c(3,7), c(9,9), c(8,3), c(3,7))),
list(rbind(c(13,4), c(17,9), c(19,3), c(13,4)))) |>
st_multipolygon() |>
st_sfc() |>
st_sf(geometry = _)
# 출력결과
Simple feature collection with 1 feature and 0 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 3 ymin: 3 xmax: 19 ymax: 9
CRS: NA
geometry
1 MULTIPOLYGON (((3 7, 9 9, 8...
데이터가 준비되었으니, 그리기만 하면 된다. 2개의 삼각형 공간이 생겼다.
ggplot() +
geom_sf(data = sf_sam1)
서로 다른 공간간에 연산해야하니, 공간 하나를 더 만들어야 한다. 이번에는 타일처럼 길이1인 정사각형 여러개의 공간을 만들어볼것이다. 여러개의 정사각형 공간을 만들어야 하다보니, polygon
을 만드는 function
을 정의해 활용했다.
polygon_square = function(x, y, gap) {
p1 = c(x, y)
p2 = c(x, y + gap)
p3 = c(x + gap, y + gap)
p4 = c(x + gap, y)
p5 = c(x, y)
st_polygon(list(rbind(p1, p2, p3, p4, p5)))
}
grid1 = expand.grid(x = seq(1, 10, by = 1),
y = seq(1, 10, by = 1))
sf_grid1 = tibble(grid1) |>
mutate(geometry = map2(x,y, polygon_square, gap = 1)) |>
pull(geometry) |>
st_sfc() |>
st_sf(geometry = _)
# 출력결과
Simple feature collection with 200 features and 0 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 1 ymin: 1 xmax: 21 ymax: 11
CRS: NA
First 10 features:
geometry
1 POLYGON ((1 1, 1 2, 2 2, 2 ...
2 POLYGON ((2 1, 2 2, 3 2, 3 ...
3 POLYGON ((3 1, 3 2, 4 2, 4 ...
4 POLYGON ((4 1, 4 2, 5 2, 5 ...
5 POLYGON ((5 1, 5 2, 6 2, 6 ...
6 POLYGON ((6 1, 6 2, 7 2, 7 ...
7 POLYGON ((7 1, 7 2, 8 2, 8 ...
8 POLYGON ((8 1, 8 2, 9 2, 9 ...
9 POLYGON ((9 1, 9 2, 10 2, 1...
10 POLYGON ((10 1, 10 2, 11 2,...
그래프를 그려보면, 여러개의 정사각형 영역이 그려진걸 확인할 수 있다.
ggplot() +
geom_sf(data = sf_grid1)
st_within
이제부터 삼각형 공간영역과 정사각형 공간영역을 이용해서 sf
패키지의 기능을 하나씩 알아볼 것이다. st_within
함수는 말그대로 특정 공간내에 있는 타 공간 영역을 추출할 수 있다.
log_within = st_within(sf_grid1, sf_sam1) |>
lengths() > 0
> log_within
[56] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[67] TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE
[78] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE
[89] FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE
[100] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE FALSE ...
나오는 결과를 가지고, 공간을 sf_grid1[log_within,]
와 같이 필터링만 해서 그리면 된다. 삼각형안에 포함되어 있는 정사각형들 공간만 그려진다.
ggplot() +
geom_sf(data = sf_grid1[log_within,], fill = "red") +
geom_sf(data = sf_sam1, fill = NA)
st_touches
st_touches
는 딱 맞닿아있는 공간을 추출할 수 있다. 아래 그림을 보면 이해가 갈 것이다.
log_touches = st_touches(sf_grid1, sf_sam1) |>
lengths() > 0
ggplot() +
geom_sf(data = sf_grid1[log_touches,], fill = "red") +
geom_sf(data = sf_sam1, fill = NA)
st_overlaps
st_overlaps
는 포함관계는 아니고, 경계에 걸쳐있는 공간만 추출해준다.
log_overlaps = st_overlaps(sf_grid1, sf_sam1) |>
lengths() > 0
ggplot() +
geom_sf(data = sf_grid1[log_overlaps,], fill = "red") +
geom_sf(data = sf_sam1, fill = NA)
st_intersects
st_intersects
는 공간이 맞닿아있거나, 겹쳐있거나, 포함한 모든 공간을 추출할 수 있다. 한마디로 st_within
, st_touches
, st_overlaps
이 3개 영역을 합친 공간이다.
log_intersects = st_intersects(sf_grid1, sf_sam1) |>
lengths() > 0
ggplot() +
geom_sf(data = sf_grid1[log_intersects,], fill = "red") +
geom_sf(data = sf_sam1, fill = NA)
st_disjoint
st_disjoint
는 여집합 개념처럼 나머지 영역을 필터링할 때 사용한다.
log_disjoint = st_disjoint(sf_grid1, sf_sam1) |>
lengths() > 0
ggplot() +
geom_sf(data = sf_grid1[log_disjoint,], fill = "red") +
geom_sf(data = sf_sam1, fill = NA)
sf
함수 사용결과를 보면서, 공간간 관계에 따라 어떻게 영역을 추출하고 표시할 수 있는지 알아봤다. 아래 그림으로 정리해봤다.