안녕하세요? 이번 글은 카카오 로컬(Local) API를 사용해 250개 시군구청의 위치 좌표를 획득해 보겠습니다. 참고로 시군구청을 비롯한 민원행정기관 위치 좌표는 '민원행정기관 전자지도'를 통해 Shapefile로 제공받을 수 있는데요, 보다 최신화된 정보 획득을 위해 카카오 로컬 API를 사용해 봅니다.
카카오 로컬 API 발급 과정은 생략하겠습니다. 이번 실습은 카카오 로컬 API 중 '키워드로 장소 검색하기' 기능을 사용합니다. Jupyter Notebook을 실행해서 실습을 진행해 보겠습니다.
필요한 라이브러리를 추가합니다.
# 라이브러리 추가
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개 시군구청 목록 파일을 준비합니다.
시군구청 목록 데이터프레임을 정의합니다.
# 시군구청 목록 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)
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)
결과는 아래와 같습니다. 여기까지 카카오 로컬API를 사용해 250개 시군구청의 위치 좌표 획득 과정을 정리해 봤습니다.