1 공간자료(Spatial Data) 1

공간자료(Spatial Data)와 자료구조를 이해하고, 한국 주소명을 지리정보(위도, 경도)로 변환시키고, dplyr 팩키지 mutate_geocode 위도경도 함수를 파이프연산자와 결합하여 코드를 간결화한다. 좌표와 좌표기준계(coordinate reference system)를 활용하여 장소가 기술되는 자료를 공간자료(Spatial Data)라고 한다. 가장 흔히 알려진 좌표기준계는 위도와 경도를 활용하여 지구상 위치를 표식한 것이다. 보통 \(x-\)축 방향을 의미하는 경도(longitude)를 먼저 넣고 나서 \(y-\)축 방향을 나타내는 위도(latitude) 순으로 데이터를 분석한다.

공간자료 작업 흐름도

공간자료를 R에서 작업하는 작업흐름은 크게 두가지가 있다. 이와 같은 작업흐름이 별도로 생겨나는 이유는 R 데이터프레임이 공간자료를 저장하기 적합하지 못하다는 내재적인 이유가 가장 크다.

  • CSR(좌표기준계) 정보를 저장하는 방법이 데이터프레임에는 없다.
  • 공간자료를 저장하기 위해서 반복적으로 데이터프레임에 저장하는 구조라 저장공간 낭비가 심하다.
  • 공간자료를 표현하는 방법도 데이터프레임으로는 적절하지 못하다.

이런 이유로 인해서 sp, raster 팩키지를 데이터프레임과 붙여 사용한다. 즉, 지리정보는 .shp 파일에 담기고, 지도를 사용해서 정보로 표현하는 데이터는 데이터프레임에 담기게 된다. 따라서 데이터프레임 정보를 .shp 파일에 녹여내기 위해서는 merge() 같은 병합연산자를 통해 합하는 과정이 수반된다.

.shp 파일 중심으로 작업을 할 것인가? 데이터프레임 중심으로 작업을 할 것이냐에 따라 크게 두가지 작업흐름으로 나눠진다.

1.1 데이터프레임 중심

지도관련 정보는 .shp 파일을 통해 얻고 이를 fortify() 함수를 사용해서 데이터프레임으로 변환한다. 이제 지도에 표시할 정보도 데이터프레임이고, .shp 파일도 데이터프레임이라 left_join 같은 병합 연산자를 사용해서 통합 데이터프레임으로 생성시키고 나서 ggplot 그래픽 팩키지를 사용해서 마무리한다.

1.2 .shp 파일 중심

.shp 파일은 shdf 파일형태로 내부적으로 데이터프레임을 담고 있다. @data 명령어를 통해 접근할 수 있는데, 데이터프레임과 .shp 파일 @data 데이터프레임을 merge() 명령어로 병합시켜 데이터프레임이 포함된 .shp 파일을 생성시킨다. 그리고 나서 tmap 주제도를 활용하여 쉽게 시각화한다.

2 구글과 다음카카오 API

데이터를 지리정보와 결합하여 제공할 경우 현상에 대한 이해, 예측, 통찰력을 얻을 수 있다. 데이터를 지리정보와 결합할 때, 가장 필요한 것이 주소정보에 위도와 경도 정보를 붙여 지도에 표시하게 된다. 주소정보가 제공되었을 때, 이에 해당되는 위도와 경도를 불러올 때 사용하는 것이 함수의 일종인 API다. 위경도 정보를 제공하는 업체로 구글, 네이버, 다음 등 여러 업체가 있다.

R에서 구글, 네이버, 다음등에서 제공하는 지리정보 API를 활용할 경우, 크게 두가지 방법이 존재한다. 하나는 직접 구글, 네이버, 다음 지리정보 API 문서를 읽고 R코드로 작성하는 방식이 있고, 또 다른 하나는 ggmap 팩키지에서 이미 지리정보 API를 내재화해서 함수로 구현해 놓은 것을 호출해서 사용하는 방법이다.

한국주소를 전달하면 위도, 경도 정보를 반환하는 API로 구글 지도 API를 기본으로 사용한다. library(ggmap) 팩키지를 불러오면 geocode 함수가 주소명을 받아 위도, 경도 정보를 반환한다. 하지만, Hadley Wickham이 관여한 팩키지는 인코딩으로 utf-8을 사용한다. 따라서, 한국어는 enc2utf8 함수를 사용해서 인코딩을 바꿔 넣은 후에 geocode 함수에 인자로 넣어야 원하는 위도경도 정보를 반환받을 수 있다.

Google 지도 API

3 구글 지리정보 API 2 3

ggmap 2.7버전부터 google_register() 함수를 사용해서 인증과정을 거친다. Google Maps Platform - " Get API Key“ 웹페이지를 참조하여 API키를 받을 수도 있고, ?register_google을 참조하여 인증작업을 시작한다.

Google API는 무료가 아니다. 구글 지도 API를 사용하려면 먼저 Google Maps Pltaform - Get API Key를 참조하여 Google Maps Platform 사용 설정을 따라야만 된다. 신용카드도 등록하고 구글이 원하는 바를 모두 맞춰주면 API키가 발급된다. 월기준 40,000 호출횟수까지는 무료라고 한다. 그 이상을 넘어가면 호출 횟수당 0.005달러가 신용카드를 통해 청구된다. 따라서 API키가 외부에 노출되지 않도록 보안에 특별히 신경을 쓴다.

API키를 발급받게 받아 다음 명령어를 실행시키면 C:/Users/user/Documents/.Renviron 파일에… GGMAP_GOOGLE_API_KEY=API키 행이 추가된다. 따라서 다음부터는 자동으로 구글 지도 API를 사용할 수 있는 효과를 얻게 된다.

  • register_google(key = "API키", write = TRUE)

만약 usethis::edit_r_environ()을 사용하는 경우 GGMAP_GOOGLE_API_KEY=API키 행을 직접 추가해도 무방하다. 그리고 추천하는 것은 Maps Static API 서비스를 제외한 나머지 서비스를 모두 비활성화(Disable) 시킨다. 설사 API키가 외부에 유출되더라도 피해를 최소화할 수 있다. 그리고 필요한 경우만 API를 활성화해서 사용한다. 예를 들어 Geocoding API를 사용해야만, 주소정보를 전달했을 때 위도와 경도 정보를 반환받아 시각화할 수 있게 된다.

Google API 가격관련 자세한 사항은 다음 웹사이트를 참조한다.

library(tidyverse)
library(ggmap)

# register_google(key = "API키", write = TRUE)

3.1 geocode() 헬로월드

가장 먼저 지명을 geocode()로 던지게 되면 위도와 경도 및 경우에 따라서는 주소도 반환시킬 수 있다. 주소정보를 함께 출력하고자할 경우 output="latlona" 선택옵션을 추가한다.

library(ggmap)
library(tidyverse)

geocode(enc2utf8("속초"), source='google')
#geocode(enc2utf8("속초"), source='google', output="latlona")
geocode(enc2utf8("속초&language=ko"), source='google', output="latlona")

"속초"geocode 함수 인자로 넣은 경우와 "속초&language=ko" 넣어 함께 넘긴 경우 한글주소로 출력되게 한다.

3.2 주소에서 위도경도 추출

구글 지도 API를 사용할 경우, 무료로 이용할 수 있는 반면에 사용자의 오남용을 방지하기 위해서 어느 API 서비스도 마찬가지지만, 구글이나 API 서비스 제공자 임의로 API를 변경할 수 있고, 사용제한을 둔다. 전면 유료화 이전 구글 지도 API의 경우 일일 2,500 번 무료로 사용이 가능하다.

geocodeQueryCheck(userType = "free") 명령어를 사용하여 구글 지도 API 사용량을 확인할 수 있었다. 2018년 중반부터 일별 쿼리 한계는 사라지고 월별 40,000건으로 조정되었다.

경기도 및 강원도 3개 지점에 대한 위도경도 정보를 받아오는 경우, 먼저 데이터프레임을 생성하고 나서, enc2utf8() 함수로 인코딩을 검증하고 나서 geocode API를 호출해서 위도경도 정보를 받아오면서 바로 데이터프레임에 붙인다.

library(ggmap)
library(plyr)

kangwon.loc <- data.frame(addr=c("강원도 속초시 영랑동", 
                                 "경기도 의왕시 포일세거리로 73",
                                 "경기도 성남시 분당구 미금동"), stringsAsFactors = FALSE)

kangwon.loc$addr <- enc2utf8(kangwon.loc$addr)
kangwon.loc.latlon <- geocode(kangwon.loc$addr, source="google")
kangwon.loc.latlon <- with(kangwon.loc, data.frame(addr,
                                   laply(addr, function(val){geocode(val)})))

kangwon.loc.latlon  

3.3 dplyr 활용한 간결한 코드

dplyr에서 제공하는 mutate_geocode 함수를 사용해서 위도경도 정보를 일괄적으로 받아와서 R 데이터프레임으로 저장한다.

kangwon_loc_df <- kangwon.loc %>% 
  mutate_geocode(addr)

경기도와 강원도 3개 주소정보를 구글 지도 API 지역에 전달하여 위도와 경도정보를 받아와서 이를 데이터프레임에 붙인다. 받아온 정보를 kangwon.loc.dplyr 데이터프레임에 저장하고 이를 활용하여 구글지도에 시각화를 한다. qmap() 함수를 사용해서 신속하게 지도를 만들어 시각화하는 것도 가능하다.

kangwonMap <- qmap(enc2utf8("속초"), zoom = 8, maptype = "toner-lite")

kangwonMap + 
  geom_point(data = kangwon_loc_df, aes(lon,lat), size = 2, colour="blue")

4 다음 지도 API 4

구글 공간정보서비스가 위세를 떨치는 기간에 다음 지도 API 사용법과 사용량 등 개발자 관점에서 나름 쓸만한 형태로 개선되었다.

4.1 헬로우 월드

C:\Program Files\R\R-3.5.2\etc 디렉토리 Rprofile.site 파일에 카카오 개발자센터 앱개발에 사용할 API 키를 DAUM_MAP_API_KEY 변수에 저장시킨다. 재미있는 것은 Authorization에서 "KakaoAK "를 꼭 앞에 붙여야함으로 paste0() 함수로 결합시켜 던진다.

혹은 usethis 팩키지를 사용해서 edit_r_environ() 명령어를 사용해서 .Renviron 파일에 DAUM_MAP_API_KEY값을 설정하여 사용하는 것도 좋다.

삼정KPMG주소를 지도위에 표시하는 것을 목표로 먼저 삼정KPMG 주소를 던져서 위도경도를 받아내는 헬로월드 코드를 작성해본다.

library(httr)
library(tidyverse)
library(jsonlite)

# usethis::edit_r_environ()

# 주소를 지정합니다. 
kpmg_addr <- '서울특별시 강남구 역삼동 737' 

# HTTP 요청을 실행합니다. 
kpmg_res <- GET(url = 'https://dapi.kakao.com/v2/local/search/address.json',
           query = list(query = kpmg_addr),
           add_headers(Authorization = paste0("KakaoAK ", DAUM_MAP_API_KEY)))

# KPMG 지리정보 데이터프레임
kpmg_list <- kpmg_res %>% 
  content(as = 'text') %>% 
  fromJSON()

## 도로명주소
kpmg_list$documents$road_address %>% 
  select(address_name, building_name, x,y)
              address_name    building_name                  x
1 서울 강남구 테헤란로 152 강남파이낸스센터 127.03650986522962
                  y
1 37.50002568178363
## 지명주소
kpmg_list$documents$address %>% 
  select(address_name, zip_code, x,y)
            address_name zip_code                  x                 y
1 서울 강남구 역삼동 737   135984 127.03662737282788 37.49980940394687

4.2 위도경도 → 지도 시각화 5

다음 지도 API는 일반적인 TM 좌표계 기반으로 TM128에 대응되는 좌표계는 API에서 지원하지 않고 있다. 지리정보 시각화를 위해서 먼저 데이터프레임 위도경도 정보를 지도상에 표시할 수 있도록 sf 팩키지 st_as_sf() 함수로 자료형을 변환시킨다. 그리고 나서 mapview() 함수로 시각화를 완성한다.

library(sf)
library(mapview)

# 3. 데이터프레임을 지도객체로 변환 ------
kpmg_df <- kpmg_list$documents$road_address %>% 
  select(address_name, building_name, lon=x, lat=y) %>% 
  mutate(lon = as.numeric(lon),
         lat = as.numeric(lat))
  
kpmg_sf <- st_as_sf(kpmg_df, 
                  coords = c("lon", "lat"),
                  crs = 4326)

mapview(kpmg_sf, hide =TRUE)