분석가 Step 1. 데이터 분석/Python

Geocoder API 2.0 레퍼런스를 이용하여 좌표계 추출

뚱뿌 2023. 7. 26. 14:55

지난번, 주소 정보가 포함된 데이터를 활용하여 지오코딩과 역지오코딩을 하였다. 

 

지오코딩(Geocoding), 역지오코딩(Geocoding-reverse) 편

지오코딩(Geocoding) 원하는 주소를 x, y 좌표(위도, 경도)로 변환하자! from geopy.geocoders import Nominatim # Nominatim 객체 생성 geo_local = Nominatim(user_agent= 'South Korea', timeout=None) # 위도/경도 반환 함수 def geocod

danha23.tistory.com

 

그러나 해당 정보로 좌표계를 추출한 후에 지도상에 데이터를 확인하였을 때,

좌표정보가 정확하지 않았다.

 

주소 데이터를 좌표로 변환하는 많은 글들을 참고하였을 때, 

파이썬 geopy는 주소 정보가 매우 정확해야 한다는 것이다. 

 

그래서 이번에는 Geocoder API 2.0 레퍼런스를 참고하여 좌표계를 추출하려고 한다.

Geocoder API 2.0 레퍼런스
vworld 오픈 api로도 불리며, 국토 교통부에서 제공하고 있다.
요청 url을 전송하면, 지오코딩 서비스를 이용할 수 있으며, 일일 지오코딩 요청 건수는 최대 40,000건
단, API 요청은 실시간으로 사용해야 하며, 별도의 저장 장치나 데이터베이스에 저장할 수 없다.
 

공간정보 오픈플랫폼 오픈API

Geocoder API 2.0 레퍼런스 Geocoder API 2.0 레퍼런스입니다. API 버전 : Geocoder API 2.0 레퍼런스 Geocoder API 1.0 레퍼런스 이동 소개 주소를 좌표로 변환하는 서비스를 제공합니다. 요청URL을 전송하면 지오코

www.vworld.kr

 

해당 서비스는 로그인 후에 이용할 수 있다.

로그인 후에 인증키를 발급한다. (본인만의 인증키 필요)

인증키 발급을 완료했다면, 이제 준비는 끝났다.

 

실습에 사용할 데이터는 "공공데이터포털"에서 제공하는 대전광역시_모범음식점 현황 데이터이다.

2023년 3월 기준, 대전광역시 모범음식점은 어느 지역에 많이 분포되어 있는지 확인해 보자.

 

데이터는 업소명과 소재지로만 되어 있다.

소재지는 해당 업소의 주소 정보로서, 소재지 정보를 활용하여 각각의 좌표를 추출해 보자.

import pandas as pd
import requests
import json

df = pd.read_csv('data/대전광역시_모범음식점 현황_20230307.csv', encoding='euc_kr')
df

대전광역시 모범음식점 현황(2023_03) 데이터

Geocoder API 2.0 레퍼런스는 참 친절하다.

각 사용 언어에 따른 사용예제를 보여준다.

vworld 오픈 api 서비스에서의 언어별 사용예제

우리는 한 주소에 대한 위도, 경도가 필요한 것이 아닌 데이터 전체에 해당하는 주소의 위도, 경도가 필요하다.

따라서, address는 소재지 각 행이 반복되어 들어가야 하기에 반복문을 이용하여 각 주소 정보를 불러왔다. 

나머지 부분은 vworld 오픈 api 서비스에서 알려준 사용예제 코드와 동일하다.

 

여기서 중요한 것은 key 부분은 이전에 발급받았던 본인 인증키를 입력해야 한다.

import pandas as pd
import requests

df = pd.read_csv('data/대전광역시_모범음식점 현황_20230307.csv', encoding='euc_kr')

# 주소를 이용하여 API 호출
result_df = pd.DataFrame(columns=['Address', 'Latitude', 'Longitude'])

apiurl = "http://api.vworld.kr/req/address?"

for i in df['소재지']:
    address = i
    print(address)
    # 주소에서 위도, 경도 좌표 검색
    params = {
        "service": "address",
        "request": "getCoord",
        "crs": "epsg:4326",
        "address": address,
        "format": "json",
        "type": "ROAD",
        "refine": "false",
        "key": "[인증키]"
    }
    response = requests.get(apiurl, params=params)
    jsonData = None
    if response.status_code == 200:
        jsonData = response.json()
        if jsonData.get("response").get("status") == "OK":
            point_data = jsonData.get("response").get("result").get("point")
            if point_data:  # 유효한 위도, 경도 정보가 있는 경우에만 추가
                lat = point_data.get("x")
                lng = point_data.get("y")
                result_df = pd.concat([result_df, pd.DataFrame({'Address': [address], 'Longitude': [lat], 'Latitude': [lng]})], 
                                      ignore_index=True)
            else:
                print(f"유효하지 않은 주소: {address}")
        else:
            print(f"API 호출 오류 - 주소: {address}, 상태: {jsonData.get('response').get('status')}")

# 결과를 엑셀 파일로 저장
result_df.to_excel('output.xlsx', index=False)

모든 주소에 대한 위도, 경도를 불러온 후  result_df 변수에 각 정보들을 저장하였다.

그러나 기존 485개 데이터가 483개의 데이터로만 나타났다.

확인 결과, API 호출 오류가 발생한 데이터가 2개가 존재하였다.

 

API 호출 오류는 주소정보가 유효하지 않는다면, 위도와 경도 정보 반환이 되지 않는다.

아래 결과를 보면, NOT_FOUND! 주소 정보가 유효하지 않아 API 호출에 오류가 발생하였다.

 

전체 데이터 중 2개의 주소 정보가 유효하지 않아 NOT_FOUND, 즉 API 호출 오류가 발생하였다.

따라서, 최종적으로는 API 호출 오류가 발생한 데이터는 제외하고, 총 483개의 데이터만이 위도, 경도로 변환되어 result_df 변수에 저장되었다.

result_df 변수

 

result_df 변수를 확인하면, 'Address', 'Latitude', 'Longitude' 총 3개의 열과 483개의 행으로 이루어진 것을 알 수 있다.

그러나 해당 정보만으로 어떤 업소인지 알기는 어렵기에 각 주소에 맞는 업소명을 추가한 후 result_dff 변수로 다시 저장하였다.

result_df['업소명'] = df['업소명']

result_dff = result_df[['업소명', 'Address', 'Latitude', 'Longitude']]
result_dff

result_dff 변수

 

 

Geocoder API 2.0 레퍼런스를 이용하여 주소 정보를 정확한 좌표 정보로 변환

지난번에, 주소 정보가 포함된 데이터를 활용하여 지오코딩, 역지오코딩을 하였다. 주소 정보를 좌표계로 ...

blog.naver.com