ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 지번주소, 도로명주소의 좌표변환(Open API 사용)
    Programming/Geo coding 2021. 2. 4. 18:34
    반응형

     (지번주소 및 도로명주소를 공개된 API를 이용하여 좌표로 변환하여 적재하는 방법을 기록합니다.

     

     

    QGIS에 뿌리기 위해서 좌표변환을 했습니다.

    www.vworld.kr/dev/v4api.do

     

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

    오픈 API 누구나 사용할 수 있는 지도 오픈플랫폼의 오픈 API 서비스는 국가 공간정보의 개방, 공유, 참여를 통해 공간정보의 자율적이고 창조적인 다양한 애플리케이션을 개발할 수 있도록 기술

    www.vworld.kr

    공간정보 오픈API 키를 발급 받고서 진행이 가능합니다.

     

    참고로 하루에 최대 request 받을 수 있는 건수는 25,000건 입니다.

    이후는 아이디를 변경하거나, 따로 문의를 하시는 것을 추천합니다.

     

    반환되는 값은 Json 형태로 반환됩니다.

    우리는 여기서 x,y만 추출할겁니다.

     

    import json
    import pandas as pd
    import requests
    from tqdm import tqdm
    import numpy as np

    사용되는 라이브러리입니다.

    반환되는 데이터는 Json 형식이고, Pandas 및 requests 등

    원래는 3개만 필요합니다.

     

    tqdm은 10000개 이상 진행할때, 진행상황을 보려고 넣었는데, 양이 적다면 빼도 무관합니다.

    numpy는 테스트데이터에 잠깐 사용됩니다.

     

    url = 'http://api.vworld.kr/req/address?'
    params = 'service=address&request=getcoord&version=2.0&crs=epsg:4326&refine=true&simple=false&format=json&type='
    road_type = 'PARCEL'
    address = '&address='
    keys = '&key='
    primary_key = 'key입력!!'
    geocode = pd.DataFrame(columns = ['name','address', 'x', 'y'])

    오픈 API를 자주 사용하신분들은 상관없으시겠지만, 모르시는분들에게 짤막하게 설명을 드리자면

    'url'은 OpenAPI를 가져옴에 있어서 서버같은 역할이고,

    'params'는 입력값으로 넣어주는 파라미터입니다. 이 부분을 수정하면 출력값을 조정할 수 있습니다.

    'road_type'은 검색방식설정 파라미터로 'PARCEL'은 지번주소, 'road'는 도로명주소입니다.

    'address'는 우리가 입력할 주소입니다.

    'primary_key'는 우리의 인증키입니다.

    하이퍼 파라미터로 primary key만 수정하셔서 사용바랍니다.

    정제된 주소일 경우에는 'params'에 refine을 false로 변경하시면 속도가 빨라집니다.

     

    def request_geo(road):
        page = requests.get(url+params+address+road+keys+primary_key)
        json_data = page.json()
        return json_data

    request 받는 부분은 함수로 선언해야합니다.

    한번에 한번씩 밖에 안되는 부분과 메모리 문제를 해결하기 위해서 함수로 사용해야 됩니다.

    응답되는 좌표 설정은 'EPSG:4326'로 진행해야 됩니다.

     

    def extraction_geo(test_data):
        geocode = pd.DataFrame(columns = ['name','address', 'x', 'y'])
        none = None
        for idx, road in tqdm(zip(test_data.index ,test_data['address'])):
            name = str(test_data['name'][idx])
            if len(str(road)) <= 5:
                geocode = geocode.append(
                        pd.DataFrame({'name':name,
                        'address':road,
                        'x':none,
                        'y':none},
                        index=[idx]))
                continue
    
            json_data = request_geo(road)
    
            if json_data['response']['status'] == 'NOT_FOUND' or json_data['response']['status'] == 'ERROR':
                geocode = geocode.append(
                        pd.DataFrame({'name':name,
                        'address':road,
                        'x':none,
                        'y':none},
                        index=[idx]))
                continue
    
            x = json_data['response']['result']['point']['x']
            y = json_data['response']['result']['point']['y']
    
            geocode = geocode.append(
                pd.DataFrame({'name':name,
                        'address':road,
                        'x':float(x),
                        'y':float(y)},
                        index=[idx]))
        return geocode

    데이터프레임에 들어있는 자료를 토대로 x,y 좌표를 반환하는 소스코드입니다.

    5글자 이하로 들어가면 에러가 떠서 에러 조정 후에 json으로 request를 받습니다.

    또한 NOT_FOUND 및 ERROR라고 반환이 되어도 x,y는 None값으로 대체됩니다.

     

    결과적으로는 새로운 데이터프레임을 반환하는것으로 알고리즘은 종료됩니다.

     

    지번주소 or 도로명주소인지를 정확하게 파악한 뒤, 진행하면 무리없이 종료될거라고 생각합니다.

     

    긴글 읽어주셔서 감사합니다.



    ---------코드전체

    import json
    import pandas as pd
    import requests
    from tqdm import tqdm
    import numpy as np
    
    index = np.arange(5)
    
    test_data = pd.DataFrame([{'name':'제주시청','address':'제주시 이도이동 1176-1'},
                      {'name':'함덕해수욕장','address':'제주시 조천읍 함덕리 1004-10'},
                      {'name':'협재해수욕장','address':'제주시 한림읍 협재리 2497-1'},
                      {'name':'쇠소깍','address':'서귀포시 남원읍 하례리 995-1'},
                      {'name':'성산일출봉','address':'서귀포시 성산읍 성산리 1'}],index=index)
    
    url = 'http://api.vworld.kr/req/address?'
    params = 'service=address&request=getcoord&version=2.0&crs=epsg:4326&refine=true&simple=false&format=json&type='
    road_type = 'PARCEL'
    address = '&address='
    keys = '&key='
    primary_key = 'key입력!!'
    
    def request_geo(road):
        page = requests.get(url+params+road_type+address+road+keys+primary_key)
        json_data = page.json()
        return json_data
    
    def extraction_geo(test_data):
        geocode = pd.DataFrame(columns = ['name','address', 'x', 'y'])
        none = None
        for idx, road in tqdm(zip(test_data.index ,test_data['address'])):
            name = str(test_data['name'][idx])
            if len(str(road)) <= 5:
                geocode = geocode.append(
                        pd.DataFrame({'name':name,
                        'address':road,
                        'x':none,
                        'y':none},
                        index=[idx]))
                continue
    
            json_data = request_geo(road)
    
            if json_data['response']['status'] == 'NOT_FOUND' or json_data['response']['status'] == 'ERROR':
                geocode = geocode.append(
                        pd.DataFrame({'name':name,
                        'address':road,
                        'x':none,
                        'y':none},
                        index=[idx]))
                continue
    
            x = json_data['response']['result']['point']['x']
            y = json_data['response']['result']['point']['y']
    
            geocode = geocode.append(
                pd.DataFrame({'name':name,
                        'address':road,
                        'x':float(x),
                        'y':float(y)},
                        index=[idx]))
        return geocode
    
    result = extraction_geo(test_data)

     

    반응형

    'Programming > Geo coding' 카테고리의 다른 글

    Ubuntu 16.04/18.04 Qgis 설치방법 (2version/3version)  (2) 2021.02.06
Designed by Tistory.