GIS Data?

GIS : Geographic Information System
현실의 다양한 지리정보를 체계적으로 ’전산화’하여 다루기 위함

크게 Raster, Vector 두 가지 형태로 나뉜다

Raster 형태의 경우 pixel 과 같은 grid 형태로 지리정보를 저장하며 주로 위성이미지 등의 예시가 있다
Vector 형태의 경우 좌표를 기반으로 지도 위의 개별 object 들을 구성한다

본 세션에서는 Vector 형태 데이터를 다루는 법 위주로 설명한다

sf package

R에서 GIS 데이터를 다루기 위한 간편한 패키지로 sf 를 추천한다

sf : simple feature
현실의 다양한 object 들, 특히 spatial object 를 컴퓨터에서 표현하기 위한 방법이다
이러한 simple feature 들에는 다음과 같은 7가지 대표적 geometry type 이 존재한다 (물론 다른 type 들도 많다)

POINT : 점
LINESTRING : 선
POLYGON : 면
MULTIPOINT : point 집합
MULTILINESTRING : linestring 집합
MULTIPOLYGON : polygon 집합
GEOMETRYCOLLECTION : geometrycollection 을 제외한 다른 geometry type들의 집합

위 대표적인 7가지 geometry type 들을 직접 만들고 시각화해보자

library(sf)
## Warning: package 'sf' was built under R version 3.6.2
## Linking to GEOS 3.7.2, GDAL 2.4.2, PROJ 5.2.0
# point 
a_ <- c(1,1)
point <- st_point(a_)
plot(point)

# line
b_ <- matrix(c(0,0, 3,3, 3,0, 0,0), 4, 2, byrow=TRUE)
big_triangle <- st_linestring(b_)
plot(big_triangle, col='red')

# polygon
c_ <- matrix(c(1,1, 2,2, 2,0, 1,1), 4, 2, byrow=TRUE)
outer <- b_
hole <- c_
triangle_polygon_with_hole <- st_polygon(list(outer, hole))
plot(triangle_polygon_with_hole)

library(leaflet)

# polygon visualize : outer & hole
leaflet() %>%
  addPolygons(
    data=triangle_polygon_with_hole, 
    color='black', fillColor='gold', weight=1)
# points
plot(st_multipoint(b_))

# lines
d_ <- list(
  matrix(c(0,0, 2,2), 2, 2, byrow=TRUE),
  matrix(c(0,2, 2,0), 2, 2, byrow=TRUE))

x <- st_multilinestring(d_)
plot(x)

# polygons

polygons <- st_multipolygon(
  list(
    list(outer, hole),
    list(outer + 3, hole + 3)
  )
)

leaflet() %>%
  addPolygons(
    data=polygons, 
    color='black', fillColor='gold', weight=1)

위에서 만든 geometry object 들에 속성값들을 붙여주고 다루려면 어떻게해야할까?

예를 들어 지도 상의 행정동 구역들이 있다고해보자…
이러한 행정동 구역들에 하위행정구역수를 속성으로 붙여주고 시각화로 띄워서 표시해준다고하면?

이럴 때 data.frame 형태로 geometry object 와 딸려있는 다양한 속성들을 각각 컬럼으로 삼아준다면 아주 간편할 것이다
바로 그것을 sf 패키지에서 sf 라는 class 로 다루고 있다

?st_sf
로 설명을 부르게되면 이렇게 표현하고 있다

“Create sf, which extends data.frame-like objects with a simple feature list column”

그 형태를 살짝 살펴보도록 하자

# if(!require('devtools')) install.packages('devtools')
# devtools::install_github("Curycu/valuemap")
library(valuemap)

seoul
## Simple feature collection with 25 features and 2 fields
## geometry type:  POLYGON
## dimension:      XY
## bbox:           xmin: 126.7643 ymin: 37.42901 xmax: 127.1836 ymax: 37.70108
## CRS:            +proj=longlat +datum=WGS84 +no_defs
## # A tibble: 25 x 3
##    name  value                                                     geometry
##    <chr> <int>                                                <POLYGON [°]>
##  1 1111     17 ((126.969 37.56819, 126.968 37.56718, 126.9679 37.5671, 126…
##  2 1114     15 ((127.0163 37.55301, 127.0132 37.54994, 127.0117 37.54851, …
##  3 1117     16 ((126.9825 37.51351, 126.9801 37.51212, 126.9756 37.5123, 1…
##  4 1120     17 ((127.0628 37.54019, 127.0566 37.5291, 127.0491 37.53255, 1…
##  5 1121     15 ((127.0923 37.52679, 127.0904 37.526, 127.0885 37.52549, 12…
##  6 1123     14 ((127.0786 37.57186, 127.0782 37.57094, 127.0778 37.57008, …
##  7 1126     16 ((127.0958 37.5711, 127.0957 37.5711, 127.0955 37.57105, 12…
##  8 1129     20 ((127.0245 37.5792, 127.0232 37.57804, 127.0225 37.5781, 12…
##  9 1130     13 ((127.022 37.61229, 127.0207 37.6125, 127.0206 37.61252, 12…
## 10 1132     14 ((127.0464 37.63916, 127.0455 37.63783, 127.0453 37.63749, …
## # … with 15 more rows
valuemap(seoul)
17
15
16
17
15
14
16
20
13
14
19
16
14
16
18
20
15
10
18
15
21
18
22
27
18
10.00 – 15.00
15.00 – 16.00
16.00 – 16.96
16.96 – 18.00
18.00 – 27.00
Leaflet | © OpenStreetMap contributors

이제 본격적으로 CRS에 대한 이야기를 할 차례가 왔다

앞서 우리는 XY 평면좌표를 기준으로 coordinate 를 잡아주고 geometry object 들을 만들었다
이 작업을 위경도 좌표계에서 하고 배경에 map 을 깔아주게되면 바로 현업에서 쓸 수 있는 지도 시각화 작업이 이루어진다
물론 우리가 직접 simple feature 를 만들기 보다는 미리 만들어진 한반도 폴리곤, 행정동 폴리곤 등을 불러오는 경우가 더 많다

CRS 에는 다양한 좌표계가 있지만 압도적으로 사용되는 1가지를 꼽아보자면 역시 WGS84를 꼽을 수 있다
우리가 흔히 쓰는 위경도 좌표계라고 보면 된다

이러한 CRS 정보는 EPSG(European Petroleum Survey Group) ID 라든가 proj4string 등을 입력하여 지정해줄수 있다 (st_sf)
CRS_참고자료

seoul$geometry
## Geometry set for 25 features 
## geometry type:  POLYGON
## dimension:      XY
## bbox:           xmin: 126.7643 ymin: 37.42901 xmax: 127.1836 ymax: 37.70108
## CRS:            +proj=longlat +datum=WGS84 +no_defs
## First 5 geometries:
## POLYGON ((126.969 37.56819, 126.968 37.56718, 1...
## POLYGON ((127.0163 37.55301, 127.0132 37.54994,...
## POLYGON ((126.9825 37.51351, 126.9801 37.51212,...
## POLYGON ((127.0628 37.54019, 127.0566 37.5291, ...
## POLYGON ((127.0923 37.52679, 127.0904 37.526, 1...

위 데이터 같은 경우 위경도 기반 WGS84 에 따른 좌표계를 따르고 있음을 알 수 있다
물론 이러한 crs 정보는 다른 좌표계로 변환이 가능하다 (st_transform)

좋은 예시로… WGS84 위경도 좌표를 평면좌표계로 바꾼 뒤 두 지점의 유클리드 거리를 계산하는 등의 작업이 가능하다
지구는 구형이기에 넓은 지역에 대해서는 부정확한 작업이지만 충분히 작은 지역에 대해서는 평면에 근사하므로 무리가 없다

물론 그냥 st_distance 를 쓰는 간단한 방법도 있다

위와 같은 geometric list-column 의 class 는 sfc
이 sfc 를 하나의 컬럼으로 갖는, 다양한 속성값을 붙일 수 있는 data.frame like geospatial class 는 sf 로 불린다
여기에 sfg 라는 class 도 있는데, 이는 st_point로 만든 것과 같은 single feature 를 의미한다

정리하자면…
geometry object 는 sfg
그걸 geometric list-column 형태로 만드는게 sfc (crs 정보 가지고 있음)
거기다 추가적인 속성값들을 column 형태로 붙인 data.frame like object 가 sf 라고 보면 된다

class(triangle_polygon_with_hole)
## [1] "XY"      "POLYGON" "sfg"
class(seoul$geometry)
## [1] "sfc_POLYGON" "sfc"
class(seoul)
## [1] "sf"         "tbl_df"     "tbl"        "data.frame"

이제… 위에서도 언급한
“물론 우리가 직접 simple feature 를 만들기 보다는 미리 만들어진 한반도 폴리곤, 행정동 폴리곤 등을 불러오는 경우가 더 많다”
부분을 살펴보겠다

기존에 만들어진 geometry object 들이 기록된 format은 크게
GeoJSON, TopoJSON, WKT (Well Known Text) 그리고 shapefile (.shp, .shx, .dbf) 등이 있다

물론 R에서는 .rda 나 .RDS 등으로 R sf object 자체를 저장해놓는 방식 또한 존재한다

전부 살펴보기엔 내용이 많으니 GeoJSON 케이스만 살펴보도록 하겠다
대한민국 행정동 폴리곤 정보 및 속성값들을 기록해둔 github repo를 예시로 사용하겠다

library(geojsonsf)

admdong <- geojson_sf('~/workspace/admdongkor/ver20201001/HangJeongDong_ver20201001.geojson')
admdong
## Simple feature collection with 3492 features and 8 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: 124.6097 ymin: 33.11187 xmax: 131.8713 ymax: 38.61695
## CRS:            EPSG:4326
## First 10 features:
##    OBJECTID                            adm_nm  adm_cd   sgg     sidonm
## 1         1          서울특별시 종로구 사직동 1101053 11110 서울특별시
## 2         2          서울특별시 종로구 삼청동 1101054 11110 서울특별시
## 3         3          서울특별시 종로구 부암동 1101055 11110 서울특별시
## 4         4          서울특별시 종로구 평창동 1101056 11110 서울특별시
## 5         5          서울특별시 종로구 무악동 1101057 11110 서울특별시
## 6         6          서울특별시 종로구 교남동 1101058 11110 서울특별시
## 7         7          서울특별시 종로구 가회동 1101060 11110 서울특별시
## 8         8 서울특별시 종로구 종로1·2·3·4가동 1101061 11110 서울특별시
## 9         9     서울특별시 종로구 종로5·6가동 1101063 11110 서울특별시
## 10       10          서울특별시 종로구 이화동 1101064 11110 서울특별시
##       adm_cd2 sido  sggnm                       geometry
## 1  1111053000   11 종로구 MULTIPOLYGON (((126.9769 37...
## 2  1111054000   11 종로구 MULTIPOLYGON (((126.9827 37...
## 3  1111055000   11 종로구 MULTIPOLYGON (((126.9759 37...
## 4  1111056000   11 종로구 MULTIPOLYGON (((126.9751 37...
## 5  1111057000   11 종로구 MULTIPOLYGON (((126.9607 37...
## 6  1111058000   11 종로구 MULTIPOLYGON (((126.969 37....
## 7  1111060000   11 종로구 MULTIPOLYGON (((126.9891 37...
## 8  1111061500   11 종로구 MULTIPOLYGON (((126.9965 37...
## 9  1111063000   11 종로구 MULTIPOLYGON (((127.0102 37...
## 10 1111064000   11 종로구 MULTIPOLYGON (((127.0073 37...

지금까지 GIS data 에 대한 전반을 빠르고 간단하게 살펴보았다
실무에서 사용되는 GIS data handling 에 대해 구글링함에 있어 기초적인 부분부터 막혀 “어디서부터 손대야할지 모르겠는” 상태는 더이상 아닐 것이다

아쉽지만 더 깊은 내용에 대해서는 각자 살펴보는 것으로 하고 본 세션은 이정도로 마무리 지으려한다