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)

이제 본격적으로 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 에 대해 구글링함에 있어 기초적인 부분부터 막혀 “어디서부터 손대야할지 모르겠는” 상태는 더이상 아닐 것이다

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