GIS

카카오 로컬 API: 250개 시군구청 위치 좌표 획득하기

유병혁 2022. 4. 26. 00:14

안녕하세요? 이번 글은 카카오 로컬(Local) API를 사용해 250개 시군구청의 위치 좌표를 획득해 보겠습니다. 참고로 시군구청을 비롯한 민원행정기관 위치 좌표는 '민원행정기관 전자지도'를 통해 Shapefile로 제공받을 수 있는데요, 보다 최신화된 정보 획득을 위해 카카오 로컬 API를 사용해 봅니다.

 

민원행정기관 전자지도 | 전자지도 다운로드 | 도로명주소 개발자센터

민원행정기관 전자지도 --> 제공되는 레이어는 Point입니다. * 좌표계 안내 : 좌표계(ITRF2000), 기준타원체(GRS80), 투영법(UTM), 장반경(6,378,137m)

www.juso.go.kr

카카오 로컬 API 발급 과정은 생략하겠습니다. 이번 실습은 카카오 로컬 API 중 '키워드로 장소 검색하기' 기능을 사용합니다. Jupyter Notebook을 실행해서 실습을 진행해 보겠습니다.

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

필요한 라이브러리를 추가합니다.

# 라이브러리 추가
import requests
from urllib.parse import urlparse
import pandas as pd
import geopandas

카카오 로컬 API에서 "서울특별시 종로구청"을 키워드로 장소 검색을 시험해 보겠습니다. "REST API" 키는 발급받은 값으로 대체하시면 됩니다.

# 카카오 로컬(Local) API: 키워드로 장소 검색하기
keyword = "서울특별시 종로구청"
url = "https://dapi.kakao.com/v2/local/search/keyword.json?&query=" + keyword
result = requests.get(urlparse(url).geturl(),
                      headers={"Authorization":"REST API 키"})
json_obj = result.json()
print(json_obj)

검색 결과를 정렬해 봅니다.

# 검색 결과 정렬
list = []
for document in json_obj['documents']:
    val = [document['place_name'],
           document['address_name'],
           document['category_name'],
           document['y'],
           document['x']]
    list.append(val)
df = pd.DataFrame(list, columns = ['place_name', 'address_name', 'category_name', 'lat', 'lon'])
df.head()

키워드 검색으로 위치 좌표를 획득할 수 있는 함수를 정의합니다.

# 키워드 검색 함수 정의
def keyword_to_latlon(keyword):
    url = "https://dapi.kakao.com/v2/local/search/keyword.json?&query=" + keyword
    result = requests.get(urlparse(url).geturl(),
                          headers={"Authorization":"REST API 키"})
    json_obj = result.json()
    list = []
    for document in json_obj['documents']:
        val = [keyword, document['place_name'],
               document['address_name'],
               document['category_name'],
               document['y'],
               document['x']]
        list.append(val)
    df = pd.DataFrame(list, columns = ['keyword', 'place_name', 'address_name', 'category_name', 'lat', 'lon'])
    return df

함수 적용 결과는 다음과 같습니다.

# 키워드 검색 함수 적용
keyword_to_latlon("서울특별시 종로구청").head()

250개 시군구청 목록 파일을 준비합니다.

SIGUNGU.xlsx
0.02MB

시군구청 목록 데이터프레임을 정의합니다.

# 시군구청 목록 xlsx 파일 읽기
df = pd.read_excel('D:/GEODATA/SIGUNGU.xlsx', sheet_name='SIGUNGU')
df.head()

키워드 검색 함수를 반복 적용해서 250개 시군구청에 대한 검색 결과를 확인합니다.

df1 = pd.DataFrame(columns = ['keyword', 'place_name', 'address_name', 'category_name', 'lat', 'lon'])
# 키워드 검색 함수 반복 적용
for keyword in df['명칭']:
    df1 = pd.concat([df1, keyword_to_latlon(keyword)])
df1.head()

카테고리 이름이 '시청', '군청', '구청'을 포함하는 목록만 선택해 봅니다. 

admin_list = ['시청', '군청', '구청']
admin = '|'.join(admin_list)
df1 = df1[df1['category_name'].str.contains(admin)]
df1.head()

목적에 따라 '예정', '별관', '2청사'와 같은 단어의 포함 여부로 필터링을 적용해 볼 수 있겠습니다. 카카오 로컬 API 검색 결과가 우수해서 인덱스 이름이 0인 행만 선택해도 큰 문제가 없어보입니다. 

filter_list = ['예정', '별관', '2청사']
filter = '|'.join(filter_list)
df1 = df1[~df1['place_name'].str.contains(filter)]
df1.head()

인덱스 이름이 0인 행만 선택해서 개수를 체크해 보니 250개가 나옵니다.

df1 = df1.loc[[0]]
len(df1)

해당 파일을 xlsx 파일로 저장합니다.

# xlsx 파일로 저장
df1.to_excel('D:/GEODATA/SIGUNGU_LATLON.xlsx', index=False)

SIGUNGU_LATLON.xlsx
0.02MB

Shapefile로 저장하고 QGIS에서 열어보겠습니다.

# Shapefile로 저장
geometry=geopandas.points_from_xy(df1.lon.astype(float), df1.lat.astype(float))
gdf = geopandas.GeoDataFrame(df1, geometry=geometry)
gdf.crs= "+init=epsg:4326"
gdf.to_file('D:/GEODATA/SIGUNGU_LATLON.shp', driver='ESRI Shapefile', encoding='utf-8', index=False)

SIGUNGU_LATLON.zip
0.02MB

결과는 아래와 같습니다. 여기까지 카카오 로컬API를 사용해 250개 시군구청의 위치 좌표 획득 과정을 정리해 봤습니다.

카카오_로컬_API_250개_시군구청_위치좌표_획득.ipynb
0.04MB