필요로 하는 패키지

먼저 지도를 그리기 위해 maptools 패키지와 rgdal 패키지를 준비합니다.

install.package(c("maptools", "rgdal"), dependencies=TRUE)

그리고 자료를 다루기 위한 tidyverse 패키지를 준비합니다.

install.package("tidyverse", dependencies=TRUE)

이와 같이 패키지를 시스템에 설치하고 나면, (보다 쉬운)사용을 위해 library() 함수를 이용하여 현재 작업영역과 패키지의 이름공간을 연결합니다.

먼저 자료들을 쉽게 다루고 도표 등을 그리기 위한 패키지들의 모음인 tidyverse 패키지와 연결해 봅시다.

library(tidyverse)
## -- Attaching packages -------------------------------------------------- tidyverse 1.2.1 --
## √ ggplot2 3.0.0     √ purrr   0.2.5
## √ tibble  1.4.2     √ dplyr   0.7.6
## √ tidyr   0.8.1     √ stringr 1.3.1
## √ readr   1.1.1     √ forcats 0.3.0
## -- Conflicts ----------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()

tidyverse 패키지와 이름공간 연결 후 (library() 함수 사용 후) 에 나오는 메세지는 tidyverse 패키지를 구성하는 다른 패키지(ggplot2, purrr, tibble, dplyr, tidyr, stringr, readr, forcats)와 이름공간을 연결하고 있음을 보여주고 Conflicts 이후에 나오는 것은 이름공간을 연결하면서 기존 이름이 충돌(conflict)되는 것을 알려줍니다. 다음은 여기에 나오는 충돌 메세지 중 일부로,

x dplyr::filter() masks stats::filter()

tidyverse 패키지를 구성하는 dplyr 패키지의 filter() 함수가 기존에 연결되어 있던 stats 패키지의 filter() 함수와 충돌되고 있으며, 사용자가 filter() 함수를 사용하면, dplyr 패키지의 함수가 작동합니다. 만일 기존에 충돌되서 이름이 덮어씌워진(mask) stats 패키지의 filter() 함수를 사용하려면 stats::filter() 와 같이 사용하면 됩니다. 어떤 함수 이름이 충돌하는지 잘 확인해 봅시다.

이제 지도를 그리기 위한 패키지들을 연결해 봅시다.

library(maptools)
library(rgdal)

지도로 그릴 자료

도로 공간정보는 국가공간정보포털오픈마켓에서 강원도 자료를 다운로드 받아 R 프로젝트 내의 data 폴더에 kw_roads 폴더로 압축을 풀었습니다.

자료 구성

다운로드 받은 공간자료는 ESRI Shapefile 이며, 다운로드 받은 파일의 압축을 풀면 다음과 같은 유형의 파일이 있습니다.

  • 추가로 포함되는 데이터를 담고 있는 .dbf
  • 공간정보 파일인 .shp
  • 공간정보의 인덱스 값을 갖고 있는 .shx

함께 제공되는 데이터 정보

파일을 다운로드 받을 때 자료 정의서를 반드시 같이 다운로드 받으셔야 합니다. 추후 어떤 정보들이 있는지 잘 알고 있어야 원하는 정보들을 추출할 수 있습니다. 이번에 사용한(시간이 지남에 따라 변경될 수 있습니다.) 파일 정의는 다음과 같습니다.

열이름 설명
XGEOMETRY 공간이미지정보
SIG_CD (PK) 시군구코드
RDS_MAN_NO (PK) 도로구간일련번호
RN 도로명
RN_CD 도로명코드
ENG_RN 영문도로명
NTFC_DE 고시일자
WDR_RD_CD 광역도로구분코드
ROA_CLS_SE 도로위계기능구분
RDS_DPN_SE 도로구간종속구분
RBP_CN 기점
REP_CN 종점
ROAD_BT 도로폭
ROAD_LT 도로길이
BSI_INT 기초간격
ALWNC_RESN 부여사유
ALWNC_DE 부여일자
MVM_RES_CD 이동사유코드
MVMN_RESN 이동사유
MVMN_DE 이동일자
OPERT_DE 작업일시

Shapefile 읽기

rgdal 패키지의 함수를 이용하여 Shapefile을 읽습니다. 기존에는 readShape**() 과 같이 Shapefile의 유형인 다각형, 선, 점 등을 읽는 함수가 별도로 제공되었는데 현재 이 함수들은 readOGR()로 대체되었습니다.

readOGR() 함수는 다양한 인수를 갖으며 간단하게 읽어올 파일의 위치만 지정하면 바로 읽어올 수 있습니다. 여기서는 기존 R 사용자들에게 조금 생소한 인수를 사용하였으나 readOGR(‘Shapefile명’) 으로도 바로 읽을 수 있습니다. 하지만 보편적으로 사용하는 두 인수를 통해 자료를 불러오겠습니다.

이제 파일을 읽어 봅시다.

roads <- readOGR(dsn="./data/kw_roads",
                 layer="Z_KAIS_TL_SPRD_MANAGE_42000")
## OGR data source with driver: ESRI Shapefile 
## Source: "G:\Toolkit\Mirror\R.Practice\data.go.kr_API\data\kw_roads", layer: "Z_KAIS_TL_SPRD_MANAGE_42000"
## with 49846 features
## It has 20 fields
## Integer64 fields read as strings:  RDS_MAN_NO

살펴보기

shapefile을 읽기 위해 사용한 readOGR() 함수가 불러온 구조를 살펴봅시다.

class( roads )
## [1] "SpatialLinesDataFrame"
## attr(,"package")
## [1] "sp"
str(roads, max.level=2)
## Formal class 'SpatialLinesDataFrame' [package "sp"] with 4 slots
##   ..@ data       :'data.frame':  49846 obs. of  20 variables:
##   ..@ lines      :List of 49846
##   ..@ bbox       : num [1:2, 1:2] 212555 395752 409972 570232
##   .. ..- attr(*, "dimnames")=List of 2
##   ..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
  • class() 함수를 통해 읽어온 대상은 SpatialLinesDataFrame 클래스로 공간정보 중 선정보를 담고 있는 것임을 확인할 수 있습니다.
  • str() 함수로 구조를 살펴보면, data, lines, bbox, proj4string의 4개의 슬롯을 포함하는 객체 임을 확인할 수 있습니다.

각각의 슬롯에 접근하는 방법은 먼저 객체명과 각 슬롯을 **@**으로 구분하여 지칭하느 것입니다. 다음은 roads 객체 내에서 텍스트 정보를 담고 있는 data 슬롯의 앞 부분 일부를 보는 것과, 각 선의 공간정보(lines 슬롯의 내용) 중 첫번째를 살펴보는 것입니다.

head(roads@data)
##   ALWNC_DE
## 0 20090220
## 1 20160418
## 2 20091201
## 3 20090728
## 4 20091201
## 5 20091001
##                                                             ALWNC_RESN
## 0                                                         법정리명사용
## 1 우천 일반산업단지 조성사업 완료 지역으로 지역적 특성을 도로명에 반영
## 2                                송학강변로의 서수 번호 부여 방법 활용
## 3                                            자연지형명칭 반영(진고개)
## 4               홍천을 동서로 가로 지르는 중심도로의 기능적의미를 반영
## 5                               행정구역명(옥계)을이용하여옥계로로명명
##   BSI_INT                    ENG_RN  MVMN_DE
## 0      20          Sangwolgeomun-ro 20170202
## 1      20      Ucheonsaneopdanji-ro 20160419
## 2      20 Songhakgangbyeon-ro 1-gil 20141031
## 3      20               Jingogae-ro 20141031
## 4      20              Hongcheon-ro 20141031
## 5      20                  Okgye-ro 20141031
##                                  MVMN_RESN MVM_RES_CD  NTFC_DE
## 0                                     <NA>         12 20090220
## 1                                     <NA>         12 20160418
## 2 광역도로 정비 및 부여사유, 부여방식 정비         90 20091201
## 3 광역도로 정비 및 부여사유, 부여방식 정비         90 20090807
## 4 광역도로 정비 및 부여사유, 부여방식 정비         90 20091201
## 5 광역도로 정비 및 부여사유, 부여방식 정비         90 20091001
##         OPERT_DE                  RBP_CN RDS_DPN_SE RDS_MAN_NO
## 0 20170202130409 진부면 상월오개리 346-9          1      23278
## 1 20160419160618   우천면 상하가리 541-0          1      12007
## 2 20141031015746     홍천읍 연봉리 258-1          1       4121
## 3 20141031020107           삼산리999-1천          1       3206
## 4 20141031015750   북방면 상화계리 294-9          1       1546
## 5 20141031020133         남양리산379-4임          1       3288
##                    REP_CN             RN   RN_CD ROAD_BT   ROAD_LT
## 0 진부면 상월오개리 347-9     상월거문로 3228014   2.798    22.672
## 1 우천면 상하가리 산136-2 우천산업단지로 3351158   3.000   455.527
## 2    홍천읍 연봉리 402-25  송학강변로1길 4475397   2.000    25.000
## 3           삼산리983-3전       진고개로 3220059   0.000 40600.000
## 4  화촌면 구성포리 산74-8         홍천로 3225052   2.000    94.000
## 5           현내리223-8답         옥계로 3220024  26.000   270.798
##   ROA_CLS_SE SIG_CD WDR_RD_CD
## 0          3  42760         3
## 1          3  42730         3
## 2          4  42720         3
## 3          3  42150         2
## 4          3  42720         3
## 5          3  42150         3
head(roads@data[[1]])
## [1] 20090220 20160418 20091201 20090728 20091201 20091001
## 273 Levels: 20041104 20061110 20061113 20061114 20061115 ... 20171207

만일 roads@data 의 각 열에 접근하려면 다음과 같이 roads$열이름 으로도 가능합니다.

table(roads$ROA_CLS_SE)
## 
##     1     2     3     4 
##    15   374 14889 34568

다음으로 함수를 통해 각 슬롯의 내용을 확인하는 것입니다.

bbox(roads)
##        min      max
## x 212554.7 409972.3
## y 395752.0 570231.9
proj4string(roads)
## [1] NA
  • bbox() 함수는 bbox 슬롯의 내용을 출력하는 함수로 공간정보상 표현되어 있는 영역(x축과 y축의 최소/최대 좌표)을 알 수 있습니다.
  • proj4string() 함수는 해당 공간자료의 투영좌표계를 나타내는 문자열을 나타냅니다. 이 함수의 수행 결과는 결측인 NA 로 지정되지 않았으나, 아래에서 공간자료 생성시 이용한 투영좌표계로 바꿔보겠습니다.

도로 지도 작성하기

plot() 함수 이용하기

R의 기본 함수인 plot()을 이용하여 바로 그릴 수 있습니다.

plot( roads )

아주 단순하면서도 쉽게 도로를 표현할 수 있습니다. 이제 도로위계에 따라 색을 달리하면서 그림을 그려봅시다. 도로의 위계는 기능에 따라 크게 고속도로, 간선도로, 집산도로, 국지도로로 구분되고 이를 바탕으로 각 시도별 위계체계를 갖고 있는 것으로 알고 있습니다. 위의 표에서 도로위계값별로 도로의 색을 달리하면서 지도를 그려봅시다.

도로위계별로 자료 마련하기

위에서 우리는 각 위계를 나타내는 roads$ROA_CLS_SE 열의 표를 통해 도로 위계가 1, 2, 3, 4로 저장하고 있음을 확인했습니다. 여기에 맞춰 각 값별로 자료를 구분하고 그 위에 지도를 그려보겠습니다.

rd.cat1 <- subset(roads, ROA_CLS_SE == 1)
rd.cat2 <- subset(roads, ROA_CLS_SE == 2)
rd.cat3 <- subset(roads, ROA_CLS_SE == 3)
rd.cat4 <- subset(roads, ROA_CLS_SE == 4)

먼저 4번 값을 갖는 도로부터 그림을 그리고 그 위에 lines()를 이용하여 각 도로들을 표현합니다.

plot( rd.cat4, lwd=0.5, col="darkgray" )
lines( rd.cat1, lwd=0.8, col="red" )
lines( rd.cat2, lwd=0.7, col="blue" )
lines( rd.cat3, lwd=0.6, col="green" )

작성단계

아직 미완인 문서입니다.

2019. 1. 24 : plot()으로 도로위계에 따른 도표 작성까지