본문 바로가기

Function

15분만에 전국 음식점 개폐업 지도 만들어보기

 

로컬데이터(localdata.kr)의 개폐업 데이터를 바탕으로 위와 같은 히트맵을 만들어보려고 한다.

 

언론에서 종종 작년과 올해 사이에 폐업이 증가한 곳들을 보도하는데, 실제 데이터를 보면 개업과 폐업은 순환하는 신진대사처럼 일어난다. 잘 되는 곳 역시 개업도 많겠지만 폐업도 많다. 드는 곳이 있으면 나는 곳도 있고 나는 곳이 있으면 드는 곳도 있기 마련이다.

 

그래서 일반적인 히트맵 그리는 방식에서 개업과 폐업에 가중치를 양과 음으로 부여하여 많이 늘어난 지역과 많이 줄어든 지역을 동시에 보려고 한다.

 

그럼 만들어보자.

정말 15분만에 될까? Qgis와 Rstudio가 깔려있다면 가능할 것 같기도 하다. 물론 R과 Qgis의 기본적인 기능은 사용할 수 있어야 한다.

 

 

 

 

 

데이터 준비

 

 

 

localdata.kr 에서 전체분 csv를 내려받는다.

지자체에 인허가 받아야 하는 업종에 한해 1주일단위로 개폐업종이 업데이트가 된다. 가장 마음에 드는 점은 괜히 일일이 검색하지 않고 이 사이트에 있는 데이터를 원클릭 한 방에 받을 수 있다는 부분이다. 

 

 

 

압축을 풀어 크기 순으로 정렬하면 위와 같은 순서로 보인다. 

여기서는 일반음식점과 휴게음식점만으로 히트맵을 그려보자.

 

 

 

 

 

 

데이터를 가공하여 QGIS용 shape 파일 만들기

 

R을 이용하여 작업한다. 라이브러리는 아래의 네 개 정도가 필요하다.

폴더 설정만 해주면, 나머지는 그대로 진행해도 실행이 무리없이 될 것 같다.

library(dplyr)
library(data.table)

library(rgdal)
library(sf)



workFolder <- "d:/데이터 압축을 풀어놓은 폴더/"
writeFolder <- "d:/결과 shp 파일을 저장할 폴더/"

######### 일반 음식점 읽기
system.time(raw <- fread(paste0(workFolder,"fulldata_07_24_04_P_일반음식점.csv"),
                         quote="\"", #encoding="unknown",
                         select = c(2,6,12,26,27,28), 
                         colClasses = list(character = c(2,6,12,26),
                                           numeric = c(27,28)),
                         col.names = c('type0','opendate','closedate','type1','xx','yy'),
                         sep = ",", header = TRUE, stringsAsFactors = FALSE, nThread = 5
)
)

data <- raw

######### 휴게음식점 읽기
system.time(raw <- fread(paste0(workFolder,"fulldata_07_24_05_P_휴게음식점.csv"),
                         quote="\"", #encoding="unknown",
                         select = c(2,6,12,26,27,28), 
                         colClasses = list(character = c(2,6,12,26),
                                           numeric = c(27,28)),
                         col.names = c('type0','opendate','closedate','type1','xx','yy'),
                         sep = ",", header = TRUE, stringsAsFactors = FALSE, nThread = 5
)
)


##### 데이터 병합 후 임시파일 지우기
data <- data %>% bind_rows(raw)
rm(raw)


##### 2020년 이후 개업한 업종 필터링 후 가중치 1 부여
dataOpen <- data %>%
  filter(closedate =="") %>%
  filter(opendate>="20200000") %>%
  mutate(prop = 1)


##### 2020년 이후 폐업한 업종 필터링 후 가중치 -1 부여
dataClosed <- data %>%
  filter(closedate >="20200000") %>%
  mutate(prop = -1)

#### 두 데이터 다시 병합 후 좌표없는 행 제외
data0 <- dataOpen %>% bind_rows(dataClosed) %>%
  filter(xx>0 & yy>0)

단계별로 코드에 주석을 달아놓았다.

시각화에 필요한 행만 읽어서 2020년 이후 개업한 업종에는 prop 컬럼에 1을, 2020년 이후 폐업한 업종에는 prop 컬럼에 -1을 넣었다.

 

 

 

이제 좌표를 변환해서 shape 파일로 저장한다.

좌표변환은 꼭 필요한 작업은 아닌데, 요새 습관상 거의 EPSG:5179 방식으로 작업하기 때문에,  그냥 그렇게 했다.

 

######### 좌표 변환 함수 입력
convertCRS <- function(df, xColNM, yColNM){

  
  from.crs <- CRS(SRS_string = "+proj=tmerc +lat_0=38 +lon_0=127.0028902777778 +k=1 +x_0=200000 +y_0=500000 +ellps=bessel +units=m +no_defs +towgs84=-115.80,474.99,674.11,1.16,-2.31,-1.63,6.43")
  to.crs <- CRS(SRS_string = "EPSG:5179")
  
  df <- df %>% filter( !is.na(xColNM) & !is.na(yColNM))
  
  df <- df %>% dplyr::select(x=xColNM, y=yColNM) %>%
    SpatialPoints(., proj4string=from.crs) %>%
    spTransform( ., to.crs) %>%
    as.data.frame(.) %>%
    cbind(df, .)
  
  return(df)
}


######## 좌표변환 후 최종 컬럼 남기기
data0 <- convertCRS(data0, "xx","yy") %>%
  dplyr::select(type0, type1, opendate, closedate, x, y,prop)


#######  point 형식의 shp 파일로 변환 저장

shopShp <- st_as_sf(data0, coords = c("x", "y"), crs = 5179)
st_write(shopShp, paste0(writeFolder,"음식점개폐업.shp"), driver="ESRI Shapefile",
         layer_options = "ENCODING=UTF-8")  # create to a shapefile

좌표변환하는 함수는 예전에 이것저것 찾아가면서 만들었는데, 함수 하나하나를 지금은 잘 기억하지 못한다.

from.crs와 to.crs 부분에는 EPSG:5179 처럼 표준화된 좌표계 이름을 입력할 수도 있고, proj4 인자 텍스트를 넣을 수도 있다.

 

위의 과정을 모두 마치면 설정한 폴더에 음식점개폐업.shp 파일들이 만들어졌을 것이다.

 

 

QGIS에서 불러오기

 

qgis에서 음식점개폐업.shp 파일을 불러들여보자.

 

속성의 심볼 설정을 아래와 같이 해보자.

 

 

심볼은 [분류값 사용]을 선택하고 크기를 [지도단위] 50m 로 설정해보자. 지도 확대 축소에 관계 없이 동일한 크기로 보여준다. 사실 히트맵과는 크게 상관없는 부분이라, 이미 이런 설정에 익숙하다면 자신이 원하는대로 해주면 된다.

 

색상은 분류값을 사용하여 위와 같이 했다. 개업이 1이었으므로 파란색 계열, 폐업이 -1이었으므로 붉은색 계열로 해주자. 주식차트에 익숙한 사람이라면 색상을 반대로 해야 마음이 편할 수도 있겠다.

 

 

불투명하면 뒤의 지도가 안보이므로 분류 선택 후 오른쪽마우스 버튼 메뉴로 불투명도를 바꿔주자. 70정도면 될 것 같다.

 

 

 

확인을 누르면 아래와 같은 지도가 보일 것 같다.

 

 

아.

배경지도는 TMS for Korea 플러그인을 설치한 후 Kakao street 로 깔아주었다. 이 부분은 검색하면 많이 나오므로 해당 부분을 더 친철하게 설명한 글들을 참고하면 좋을 것 같다.

 

 

좌측 하단의 레이어 창에서 분류별로 켜고 꺼주면 아래와 같은 지도들이 보인다.

여기저기 폐업도 많은 것 같지만

 

 

여기저기 개업도 많다.

 

흠. 그런데 신촌역과 이대는 그냥 이렇게 대략 봐도 확실히 개업보다 폐업이 많다.

어쨌든 모든 곳들을 이렇게 구분할 수는 없으니 히트맵을 만들어보기로 한다.

 

 

 

 

 

 

히트맵 만들기

 

히트맵 플러그인은 qgis에 기본으로 설치되어 있다.

화면 우측의 공간처리 툴박스에서 heatmap으로 검색해보면 플러그인 딱 하나가 보인다.

공간처리 툴박스가 없으면, 풀다운 메뉴의 보기 -> 패널 에서 체크해서 찾을 수 있다.

 

 

 

설정은 위와 같이 했다.

 

히트맵 알고리즘은 화선지에 묽은 먹물을 한방울 떨어뜨렸다고 생각하면 된다. 해당 점 주변으로는 진하게 가중치를 주고, 주변부로 갈수록 옅게 가중치를 부여해서 공간 전체에 이 점들의 먹물들을 하나하나 겹쳐서 만든다고 생각하면 된다.

(아, 그러고 보니, qgis의 히트맵 알고리즘이 주변부로 갈수록 옅어지는지, 반경까지 동일한 가중치를 일괄적으로 부여하는지는 잘 모르겠다)

 

[반경]은 하나의 점에서 어느정도 반경까지 옅어지는 가중치를 뿌릴 것인가를 설정하는 부분이다.

분석하는 입장에서의 의미는 하나의 상점의 영향권을 얼마만큼으로 볼 것인가다. 여기서는 300m 로 설정했다. 딱히 이유를 말하기는 어려운데, 도시 공간에서 국가표준격자 기준으로 250m 정도로 구분하면 이런저런 내용들이 잘 설명되는 편이다. 경험상 너무 국부적이지도 않고, 너무 커서 두개의 상권이 엉겨붙어버리는 정도도 아닌 정도라고 말할 수 있을 것 같다. 혹은 걸어서 부담없이 갈 만한 거리이기 때문에 한 상점의 영향권을 300m 정도라고 볼 수도 있겠다.

 

[픽셀크기 X, Y]는 전국 지도를 몇 m  격자 단위로 구분하여 히트맵을 그릴 것인가를 결정하는 부분이다. 여기서는 50m 로 두었는데, 약 500메가의 tif 파일이 만들어진다. 10m로 두면 12기가의 tif 파일이 생긴다. 전국 단위의 경향을 보는 정도는 50m 의 약간 거칠은 해상도도 충분하므로 너무 욕심부리지 말고 처음에는 크게크게 두자.

 

[Weight from field] 부분이 중요하다.

미리 설정해둔 prop 컬럼으로 맞춰주자. 개업한 곳은 양의 점수로, 폐업한 곳은 온전히 음의 점수로 더하고 빼는 작업이 이루어진다. 똑같은 지점에 개업과 폐업이 하나씩 있다면 평평한 0의 결과가 나오게 된다.

 

이제 임시파일에 저장하든, 파일 이름을 지정해주든 마지막 설정을 하고, 실행해보자. 그리 오래걸리지 않는다.

 

 

 

실행하면 위와 같으 화면이 나온다.

 

보기에 썩 좋지는 않으므로 설정을 좀 바꿔주자.

 

 

이 부분은 꼭 그대로 따라할 필요는 없다. QGIS에 어느 정도 익숙하면 자신만의 열지도를 그리면 된다.

[렌더링 유형]은 단일 밴드 유사색상으로 두고

색상표는 Magma 로 설정했다. 나중에 다시 색상들을 조정했으므로 결과는 좀 다른데, 기본 색상은 거기서 출발했다.

보간은 '이산'으로 두었다. 계단식으로 끊어본다고 생각하면 된다.

처음에는 [모드]를 등간격으로 6분류 한 후, 중간값들을 적절히 다시 설정했다.

색상의 경계값들은 35, 6, 0, -6, -35로 두었는데, 옆의 '라벨'에서 어떻게 구간이 나누어지는지 확인할 수 있다. 개업과 폐업 부분 경계에 절대값이 동일한 값들을 넣어야 왜곡 없이 읽을 수 있을 것 같다.

 

꼭 6이어야 하는 법은 없다. 7이 되어도 되고 5가 되어도 된다. 값들의 분포에서 특정한 경계지점을 찾고자 하면 그렇게 해서 넣으면 된다. 여기서는 결과물의 그림이 적절하게 알아볼 수 있는 정도로 두었다.

 

 

 

 

전체적으로 불투명도를 약간 투명하게 조정하고, 중간의 두개 값은 불투명도를 0으로 두었다. 중간 영역은 그리지 않고, 6이상 -6이 값들이 나타나는 지역만 보기 위해서다.

 

설정이 끝났으면 확인을 누르고 빠져나오자.

이제 아래와 같은 지도가 보일 것 같다.

 

 

배경지도와 겹쳐져서 약간 알아보기가 힘들다.

 

안타깝게도 카카오 지도의 투명도를 조절하는 부분은 없는 듯하니, 히트맵과 지도 사이에 반투명한 도형을 하나 그려주자.

 

새 shape 파일 레이어로 폴리곤 레이어를 만들어 준 후 전국을 덮는 도형을 하나 추가한 후에 반투명한 흰색을 부여하면 된다.

아래와 같이 만들어주자.

 

원래는 되어야 하는데, 이상하게 자꾸 도형생성에서 에러가 발생하는 바람에 다른 방법으로 만들었다.

 

[벡터] -> [조사도구] -> [그리드 생성]에서 아래와 같이 설정해보자.

 

어차피 그리드가 중요한 것이 아니므로 수평, 수직 간격은 100000미터 정도로 해주면 된다. 좌표계가 위와 같은지 꼭 확인하자. 생성하면 아래와 같은 그림이 보인다. 

 

 

속성에서 심볼 설정만 바꿔주면 된다. 테두리를 그리지 않고, 면 색을 반투명한 흰색으로 해주자.

 

레이어 순서를 아래와 같이 맞춰보자.

이제 지도도 약간 흐리게 보이고, 그래서 히트맵도 좀 더 알아보기 쉽게 되었다.

 

끝.

 

 

 

 

 

 

지도 탐색

 

이 글은 [content]가 아니라 [function] 카테고리의 글이지만, 그냥 끝내면 섭섭하니 몇 군데 돌아보자.

편의상 '상권'이라고 할텐데, 여기서 설명하는 '상권'은 일반음식점과 휴게음식점에 국한된 것임을 잊지 말자.

전체적으로 폐업이 심하게 많은 곳들이 보이지만, 개폐업의 기복은 지역에 따라 다르다. 역시 나는 곳이 있으며 드는 곳도 있다.

 

신촌~이대 상권에는 확실히 폐업이 많다. 이대역에서 이대 정문으로 내려가다 보면 빈 점포가 정말 눈에 많이 띈다. 

홍대 앞 상권도 가라앉았다고 하는데, 확실히 홍대 정문쪽 블럭은 폐업이 더 많다. 단, 경의선 철길 북쪽의 연남동 쪽은 그래도 개업이 많다.

 

명동 상권에도 폐업이 눈에 띄게 많다. 세운상가 좌우의 을지로와 시청 쪽으로는 약간 많아졌다.

여의도에 개업이 급증한 곳은 '더현대서울' 이다. 백화점이 생겼으니 당연히 개업이 꽤 증가했을 것 같다. 주변의 낙수효과인지 여의도역 부근에도 개업이 많은 곳으로 나타났다.

 

 

 

 

고속터미널, 압구정역, 코엑스 쪽이 크게 줄었다. 모두 백화점이 있는 곳들인데, 백화점 안에서도 폐업이 많은가보다. 아니면 그 주변지역이거나. 자세한 내용은 잘 보지 못했다. 개폐업 점을 띄워봐도 백화점 한 점포의 점들은 모두 같은 좌표에 겹치기 때문에 별도의 가공으로 좌표값을 흔들어주지 않는다면 곧바로 확인하기는 어려울 것 같다.

 

코엑스 쪽에 역삼역과 선릉역 사이에, 그리고 언주역 부근에는 개업이 많다. 최근에 '다시 뜨고 있다'고 보도된 로데오거리 쪽도 개업이 좀 더 많은 지역에 들어왔다. 역삼역과 선릉역 사이에는 최근에 유동인구도 많이 늘어났던데, 이 쪽에는 가본지가 한참되어서 사정을 잘 모르겠다.

 

 

미사역 부근에도 최근 신축 아파트와 5호선 연장등의 이유인지 개업한 곳들이 많은 것 같다. 강동구는 대체로 개업이 많은 지역이 눈에 들어온다. 

천호역 현대백화점, 지도 왼쪽 구석에 롯데월드쪽, 스타필드 하남도 모두 폐업이 더 많다. 대형 쇼핑몰과 백화점들이 거의 비슷한 추세인 것 같다.

 

 

사정은 잘 모르지만, 캡쳐하는 김에 손이 닿는대로 몇 개 넣어봤다.

 

월곶의 서울대제2캠퍼스 부근, 송도 인천대입구역 부근, 영종1동 지역은 개업이 많은 쪽들이 많다.

가장 크게 줄어든 부분은 주안역 남북방향이다.

 

 

 

 

 

대전은 조금 늘고 조금 줄어든 것 같다.

 

전주는 한옥마을 부근은 폐업이 많고, 서측 혁신도시에는 확실히 개업이 많다.

 

 

 

 

광주는 잘 모르겠는데, 군데군데 섞여있다.

 

 

 

목포는 큰 변화가 없어 보이는데, 개폐업소들을 같이 띄워보자.

 

 

어쨌든 변화가 없는 것은 아닌데, 히트맵 단계 자체를 서울의 스케일에 맞춰놓아서 잘 안보일 수도 있겠다는 생각도 든다. 

 

 

 

 

부산의 경우, 서면역 롯데 본점과 센텀시티쪽은 폐업이 많지만 전반적으로 개업이 우세한 지역들이 많다. 

 

 

 

울산도 좀 섞여 있다.

 

 

대구는 폐업이 우세한 지역들이 더 많아보인다. 그래도 대봉동이나 중앙로역과 시청 사이에는 개업이 우세하다.

 

 

 

코로나 시기에 수도권 사람들이 강릉과 속초에 많이 간 것 같던데, 그래도 강릉역 주변에는 폐업이 더 많다.

 

 

 

더 궁금한 지역이 있다면, 직접 시도해보면서 히트맵의 단계값들도 조정해보길 권장한다. 

끝.