Diary of Chanjun 데이터 분석가의 다이어리

GIS 관련 API에 대한 도움글

1. API란?

API(Application Programming Interface, 응용 프로그램 프로그래밍 인터페이스) : 응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다.

출처 : 위키피디아

Oops

출처 : moonspam님의 gitpage

A. Naver MAP API

네이버에서는 Storage, DB, 이미지, 자연어 등 다양한 API 서비스를 제공하고 있습니다.
그 중에서 GIS 관련 서비스를 모아둔 MAPS 의 API에 대해서 살펴보겠습니다.
위의 링크로 가게되면 서비스의 종류와 요금 안내를 받을 수 있습니다. 서비스를 상용화하지 않는다면 대부분 무료로 사용할 수 있다고 생각하시면 됩니다.
자세한 내용은 NAVER API 참조서를 참고하시기 바랍니다.


일단 API를 사용하기 위해서는 네이버 개발자 센터에 회원가입을 한 뒤
어플리케이션 등록을 하여 api key를 받아야합니다.
저는 사전에 받은 api key를 불러오도록 하겠습니다.

import os
import sys


import pandas as pd

# 공간연산을 위한 라이브러리
import geopandas as gpd
from shapely.geometry import LineString

# API를 사용하기 위한 라이브러리
import requests
import json

# 데이터 시각화를 위한 라이브러리
import folium
import matplotlib
%matplotlib inline
key_csv = pd.read_csv("key/api_key.secret", index_col = "name")

위의 링크에 걸려있는 API 참조서에서 geocoding 과 reverse geocoding을 해보겠습니다.
geocoding 은 주소 -> 좌표
reverse geocoding 은 좌표 -> 주소 변환을 해주는 역할을 합니다.


참조서에서 request의 방식, header에 넣어야될 파라미터 값 그리고 요청 파라미터를 어떤 이름으로 어떻게 넣어야되는지 나와있습니다.
예시를 위해서 서울 시청 주소를 geocoding 하여 좌표로 바꿔보도록 하겠습니다.

# 위에서 말했던 header에 넣어야할 id와 key를 넣어주고 url 을 지정해줍니다.
header = {}
header["Accept"]="application/json"
header["X-NCP-APIGW-API-KEY-ID"] = key_csv.loc["naver_id"]["value"]
header["X-NCP-APIGW-API-KEY"] = key_csv.loc["naver_key"]["value"]
naver_geocoding = "https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode"
# 서울시청 주소
exam_address = "서울특별시 중구 세종대로 110"
# get 방식으로하기 위해 url 뒤에 ?를 붙이면 어떠한 데이터를 보내겠다는 이야기입니다. 그러므로 query 뒤에 주소를 하나 적어서 보내봅니다.
naver_geturl = naver_geocoding + "?query="+ str(exam_address)
print("naver_geturl = {}".format(naver_geturl))
naver_geturl = https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query=서울특별시 중구 세종대로 110
res = requests.get(naver_geturl, headers = header)
res_ = json.loads(res.text)
res_
{'status': 'OK',
 'meta': {'totalCount': 1, 'page': 1, 'count': 1},
 'addresses': [{'roadAddress': '서울특별시 중구 세종대로 110 서울특별시청',
   'jibunAddress': '서울특별시 중구 태평로1가 31 서울특별시청',
   'englishAddress': '110, Sejong-daero, Jung-gu, Seoul, Republic of Korea',
   'addressElements': [{'types': ['SIDO'],
     'longName': '서울특별시',
     'shortName': '서울특별시',
     'code': ''},
    {'types': ['SIGUGUN'], 'longName': '중구', 'shortName': '중구', 'code': ''},
    {'types': ['DONGMYUN'],
     'longName': '태평로1가',
     'shortName': '태평로1가',
     'code': ''},
    {'types': ['RI'], 'longName': '', 'shortName': '', 'code': ''},
    {'types': ['ROAD_NAME'],
     'longName': '세종대로',
     'shortName': '세종대로',
     'code': ''},
    {'types': ['BUILDING_NUMBER'],
     'longName': '110',
     'shortName': '110',
     'code': ''},
    {'types': ['BUILDING_NAME'],
     'longName': '서울특별시청',
     'shortName': '서울특별시청',
     'code': ''},
    {'types': ['LAND_NUMBER'],
     'longName': '31',
     'shortName': '31',
     'code': ''},
    {'types': ['POSTAL_CODE'],
     'longName': '04524',
     'shortName': '04524',
     'code': ''}],
   'x': '126.9783882',
   'y': '37.5666103',
   'distance': 0.0}],
 'errorMessage': ''}

참조서에서 보시는 응답바디라는 부분과 똑같이 리턴을 받을 수 있게됩니다. 아주 친절하게도 그냥 좌표만 나오는 것이 아니라 행정동과 건물의 이름 구주소 등도 알 수 있습니다.


# python의 folium으로 띄워보겠습니다.
m = folium.Map(
    location=[res_["addresses"][0]["y"],res_["addresses"][0]["x"]],
    zoom_start=18
)

folium.Marker(
  location=[res_["addresses"][0]["y"],res_["addresses"][0]["x"]],
  popup=res_["addresses"][0]["addressElements"][6]["longName"],
  icon=folium.Icon(color='red',icon='star')
).add_to(m)

m

다시 reverse geocoding을 통하여 좌표가 다시 서울시청 주소로 나오는지 확인해보겠습니다.
reverse geocoding의 경우 출력 format을 요청 파라미터로 지정해주고, 변환 주소 타입이 지번 혹은 도로명인지에 대해서도 지정을 해주어야합니다.
요청 파라미터에 도로명 주소와 json 형식으로 받아오도록 request를 해보겠습니다.


naver_geocoding = "https://naveropenapi.apigw.ntruss.com/map-reversegeocode/v2/gc"
exam_point = ",".join([res_["addresses"][0]["x"], res_["addresses"][0]["y"]])
output_format = "json"
naver_geturl = f"{naver_geocoding}?coords={str(exam_point)}&orders=roadaddr&output={output_format}"
print("naver_geturl = {}".format(naver_geturl))
naver_geturl = https://naveropenapi.apigw.ntruss.com/map-reversegeocode/v2/gc?coords=126.9783882,37.5666103&orders=roadaddr&output=json
res = requests.get(naver_geturl, headers = header)
res_ = json.loads(res.text)
res_
{'status': {'code': 0, 'name': 'ok', 'message': 'done'},
 'results': [{'name': 'roadaddr',
   'code': {'id': '1114010300', 'type': 'L', 'mappingId': '09140103'},
   'region': {'area0': {'name': 'kr',
     'coords': {'center': {'crs': '', 'x': 0.0, 'y': 0.0}}},
    'area1': {'name': '서울특별시',
     'coords': {'center': {'crs': 'EPSG:4326',
       'x': 126.9783882,
       'y': 37.5666103}},
     'alias': '서울'},
    'area2': {'name': '중구',
     'coords': {'center': {'crs': 'EPSG:4326',
       'x': 126.997602,
       'y': 37.563843}}},
    'area3': {'name': '태평로1가',
     'coords': {'center': {'crs': 'EPSG:4326',
       'x': 126.9772484,
       'y': 37.5676845}}},
    'area4': {'name': '',
     'coords': {'center': {'crs': '', 'x': 0.0, 'y': 0.0}}}},
   'land': {'type': '',
    'number1': '110',
    'number2': '',
    'addition0': {'type': 'building', 'value': '서울특별시청'},
    'addition1': {'type': 'zipcode', 'value': '04524'},
    'addition2': {'type': 'roadGroupCode', 'value': '111402005001'},
    'addition3': {'type': '', 'value': ''},
    'addition4': {'type': '', 'value': ''},
    'name': '세종대로',
    'coords': {'center': {'crs': '', 'x': 0.0, 'y': 0.0}}}}]}
print(" ".join([res_["results"][0]["region"][f"area{i + 1}"]["name"] for i in range(3)] + [res_["results"][0]["land"]["number1"]]))
print(exam_address)
서울특별시 중구 태평로1가 110
서울특별시 중구 세종대로 110

결과가 조금 이상하게 나왔지만 세종대로? 태평대로?
잘 맞게 나왔다는 것을 알 수 있습니다.



B. Kakao MAP API

카카오는 네이버에서 제공하는 모든 API를 모아둔 사이트가 있는 것과 달리 Kakao Map API 페이지가 따로 있습니다.
API가 익숙하신 분들이라면 크게 상관 없겠지만 왠지 카카오가 좀 더 친절하다고 느껴집니다.
네이버도 예전에는 Map API 사이트가 따로 있었고 사이트 구조도 비슷했었습니다.
왜 더 친절하게 느껴지는 지는 Kakao MAP API Sampler 여기에 들어가면 샘플 코드로 html과 js로 실행할 수 있는 샘플들도 할 수 있습니다.


HTML, CSS, JS 아무것도 모르는 데이터 사이언티스트인데 이걸 왜 쓰고 어떻게 쓰나요?

물론 웹 관련하여 지식이 없는 분들에겐 어렵고 복잡하게만 느껴지시겠지만,
굳이 지금 당장 파이썬을 안키고 자바스크립트에 간단하게 값만 넣으면 샘플로 효율적으로 작업하실 수 있습니다.


카카오도 다른 API들과 마찬가지로 회원가입과 어플리케이션 등록 후 key를 발급 받아야 사용할 수 있습니다.


Kakao MAP API 실습은 네이버에서는 볼 수 없었던 키워드로 검색하는 기능을 해보겠습니다.

# 위에서 말했던 header에 key를 넣어주고 url 을 지정해줍니다.
header = {}
header["Authorization"]= "KakaoAK "+ key_csv.loc["kakao_key"]["value"]
kakao_url = f"https://dapi.kakao.com/v2/local/search/keyword.json"
kakao_url = kakao_url + "?query=서울시청"
kakao_url
'https://dapi.kakao.com/v2/local/search/keyword.json?query=서울시청'
res = requests.get(kakao_url, headers = header)
res_ = json.loads(res.text)
["{} : {}({}, {})".format(x["place_name"], x["address_name"], x["x"], x["y"]) for x in res_["documents"]]
['서울특별시청 : 서울 중구 태평로1가 31(126.978652258823, 37.56682420267543)',
 '서울특별시청 서소문청사 : 서울 중구 서소문동 37(126.975655748641, 37.5644395872256)',
 '서울특별시청 서소문2청사 : 서울 중구 서소문동 143(126.975189846884, 37.5631474614776)',
 '서울시청 본청사 주차장 : 서울 중구 태평로1가 31(126.97864772708567, 37.56683861779011)',
 '서울시청 서소문청사 주차장 : 서울 중구 서소문동 37(126.975175855106, 37.5643818235373)',
 '시청역 1호선 : 서울 중구 정동 5-5(126.977199342956, 37.5653444955867)',
 '서울시립미술관 서소문본관 : 서울 중구 서소문동 37(126.973790543874, 37.5641076212639)',
 '다이소 서울시청광장점 : 서울 중구 태평로2가 360-1(126.976629074232, 37.5647028748099)',
 '서울특별시청 서소문청사 1동 : 서울 중구 서소문동 37(126.975646708937, 37.5643927335562)',
 '서울시청 신청사 개방화장실 : 서울 중구 태평로1가 31(126.978643291552, 37.5665160604517)',
 '서울특별시청 청계청사 : 서울 중구 무교동 96(126.978221551817, 37.5688261365316)',
 '서울중앙지방법원 중부등기소 : 서울 중구 서소문동 37-8(126.973174653239, 37.5645435651232)',
 '우리은행 서울시청금융센터 : 서울 중구 무교동 45(126.97881722643558, 37.56785046661765)',
 '시청역 2호선 : 서울 중구 서소문동 90-1(126.9755971383, 37.5636827382285)',
 '신한은행 서울시청금융센터 : 서울 중구 태평로1가 31(126.978244947578, 37.5662231640346)']

키워드다 보니 서울시청에 대한 여러가지 결과가 나온 것을 볼 수 있습니다.
하지만 category와 좌표 반경 등으로 제한할 수 있기 때문에, 잘 쓴다면 유용한 API가 될 것 같습니다.


서울시청과 서울특별시청의 주소가 조금 다르므로 두개의 좌표를 지도에 한번 띄워보겠습니다.

# python의 folium으로 띄워보겠습니다.
m = folium.Map(
    location=[37.5666103, 126.9783882],
    zoom_start=18
)

folium.CircleMarker(
  location=[37.5666103, 126.9783882],
  popup="네이버 서울시청",
  icon=folium.Icon(color='red',icon='star')
).add_to(m)

folium.CircleMarker(
  location=[37.56682420267543, 126.978652258823],
  popup="카카오 서울시청",
  icon=folium.Icon(color='red',icon='star')
).add_to(m)

m

주소와 좌표가 조금 다른 것을 확인할 수 있으나, 두 좌표 모두 시청 건물 위에 있는 것 또한 확인할 수 있습니다.
카카오도 geocoding과 reverse geocoding을 제공하나 사용 방법이 비슷하므로 실습을 하진 않겠습니다


C. T map API

TMAP API는 지도를 기반으로 한다는 느낌보다는 역시 네비게이션에 특화되어 있는 느낌이 강합니다.
네이버에서도 경유지에 대한 정보를 얻을 수 있지만 차량에 대해서만 진행이 가능하나, TMAP에서는 단순 경유지 탐색뿐 아니라 경유지를 최적화시키거나 보행자에 대해서 혹은 더 많은 옵션들이 있으니 TMAP API 가이드에서 참고하시기 바랍니다.


역시 이번에도 key를 받으시셔야합니다
이번엔 다중경유지와 경유지 최적화 API에 대해서만 실습하겠습니다.
경유지를 얻기 위해서 카카오 API를 통하여 주소 몇개를 가져오도록 하겠습니다

# 위에서 말했던 header에 key를 넣어주고 url 을 지정해줍니다.
header = {}
header["Authorization"]= "KakaoAK "+ key_csv.loc["kakao_key"]["value"]
points_list = ["서울시청", "강남구청", "종로구청", "서초구청", "서대문구청"]
points_ = {}
for i in points_list :
    kakao_url = f"https://dapi.kakao.com/v2/local/search/keyword.json"
    kakao_url = kakao_url + f"?query={i}"
    kakao_url

    res = requests.get(kakao_url, headers = header)
    res_ = json.loads(res.text)
    points_[res_["documents"][0]["place_name"]] = [res_["documents"][0]["x"], res_["documents"][0]["y"]]

points_
{'서울특별시청': ['126.978652258823', '37.56682420267543'],
 '강남구청': ['127.047377408384', '37.51733192586'],
 '종로구청': ['126.97898995418838', '37.57350424298736'],
 '서초구청': ['127.032693842117', '37.4835924256444'],
 '서대문구청': ['126.9368156604', '37.5791618639849']}
headers = {}
headers["appKey"] = key_csv.loc["tmap_key"]["value"]
headers["Content-Type"] = "application/json"
param = {}
# 여기서 좌표값을 string 타입으로 바꿔주지 않으면, api자체에서 type error가 뜹니다. 주의해서 string으로 바꿔주시길 바랍니다.
param["startName"] = list(points_.keys())[0]
param["startX"] = str(list(points_.values())[0][0])
param["startY"] = str(list(points_.values())[0][1])
param["startTime"] = "202105251200"
param["endName"] = list(points_.keys())[4]
param["endX"] = str(list(points_.values())[4][0])
param["endY"] = str(list(points_.values())[4][1])
param
{'startName': '서울특별시청',
 'startX': '126.978652258823',
 'startY': '37.56682420267543',
 'startTime': '202105251200',
 'endName': '서대문구청',
 'endX': '126.9368156604',
 'endY': '37.5791618639849'}
viaPoints = [{"viaPointId" : "vidPoint" + str(a), "viaPointName" : list(points_.keys())[a] , "viaX" : str(list(points_.values())[a][0]), "viaY" : str(list(points_.values())[4][1])} for a in range(1,4)]
viaPoints
[{'viaPointId': 'vidPoint1',
  'viaPointName': '강남구청',
  'viaX': '127.047377408384',
  'viaY': '37.5791618639849'},
 {'viaPointId': 'vidPoint2',
  'viaPointName': '종로구청',
  'viaX': '126.97898995418838',
  'viaY': '37.5791618639849'},
 {'viaPointId': 'vidPoint3',
  'viaPointName': '서초구청',
  'viaX': '127.032693842117',
  'viaY': '37.5791618639849'}]
param["viaPoints"] = viaPoints

이렇게 하여 경유지를 탐색할 수 있는 param들을 다 넣었습니다.


param
{'startName': '서울특별시청',
 'startX': '126.978652258823',
 'startY': '37.56682420267543',
 'startTime': '202105251200',
 'endName': '서대문구청',
 'endX': '126.9368156604',
 'endY': '37.5791618639849',
 'viaPoints': [{'viaPointId': 'vidPoint1',
   'viaPointName': '강남구청',
   'viaX': '127.047377408384',
   'viaY': '37.5791618639849'},
  {'viaPointId': 'vidPoint2',
   'viaPointName': '종로구청',
   'viaX': '126.97898995418838',
   'viaY': '37.5791618639849'},
  {'viaPointId': 'vidPoint3',
   'viaPointName': '서초구청',
   'viaX': '127.032693842117',
   'viaY': '37.5791618639849'}]}
# 좌표계 설정
param["reqCoordType"] = "WGS84GEO"
param["resCoordType"] = "WGS84GEO"
res = requests.post(url = "https://apis.openapi.sk.com/tmap/routes/routeSequential30?version=1&format=json", data = json.dumps(param), headers = headers)
res = res.json()
[{'type': 'Feature',
  'geometry': {'type': 'Point', 'coordinates': [126.97865155, 37.56682361]},
  'properties': {'index': '0',
   'viaPointId': '',
   'viaPointName': '[0] 서울특별시청',
   'arriveTime': '20210525120000',
   'completeTime': '20210525120000',
   'distance': '0',
   'deliveryTime': '0',
   'waitTime': '0',
   'pointType': 'S'}},
 {'type': 'Feature',
  'geometry': {'type': 'Point', 'coordinates': [127.04737828, 37.5791623]},
  'properties': {'index': '1',
   'viaPointId': 'vidPoint1',
   'viaPointName': '[0] 강남구청',
   'viaDetailAddress': '',
   'groupKey': '0',
   'arriveTime': '20210525123524',
   'completeTime': '20210525123524',
   'distance': '7387',
   'deliveryTime': '0',
   'waitTime': '0',
   'pointType': 'B1'}},
 {'type': 'Feature',
  'geometry': {'type': 'LineString',
   'coordinates': [[126.97865988, 37.56701525],
    [126.97818492, 37.56703746],
    [126.97813771, 37.56704024],
    [126.97726001, 37.56703745],
    [126.97725723, 37.5672402],
    [126.97725443, 37.56802344],
    [126.97722941, 37.5687928],
    [126.97722384, 37.56909276],
    [126.97721551, 37.56925941],
    [126.97720995, 37.56938717],
    [126.97722105, 37.56965381],
    [126.97722938, 37.56981212],
    [126.97728492, 37.56994544],
    [126.9773127, 37.56998988],
    [126.97735714, 37.5700371],
    [126.97741546, 37.57008154],
    [126.97750434, 37.57012598],
    [126.97848481, 37.57012322],
    [126.97927085, 37.57010379],
    [126.97929863, 37.57010379],
    [126.9794375, 37.57010102],
    [126.97968748, 37.57009825],
    [126.97987913, 37.57009825],
    [126.98127622, 37.57009827],
    [126.98182617, 37.57009551],
    [126.98230668, 37.57009552],
    [126.98288163, 37.5700983],
    [126.98302606, 37.57009831],
    [126.98343436, 37.57010942],
    [126.98438149, 37.57012888],
    [126.98441205, 37.57012888],
    [126.98532308, 37.5701289],
    [126.98609245, 37.57012891],
    [126.98690071, 37.57012893],
    [126.9875201, 37.57013727],
    [126.98758398, 37.57014005],
    [126.98768675, 37.57013727],
    [126.98778396, 37.57013728],
    [126.98851167, 37.57015395],
    [126.98907273, 37.57018729],
    [126.9894227, 37.57020952],
    [126.99040594, 37.57027064],
    [126.99101977, 37.57030954],
    [126.99212245, 37.57037899],
    [126.99308347, 37.57041234],
    [126.99385007, 37.57044846],
    [126.99393339, 37.57045402],
    [126.99396117, 37.57045402],
    [126.99446112, 37.57047902],
    [126.9947722, 37.57049569],
    [126.99479442, 37.57049847],
    [126.9950944, 37.57051236],
    [126.99534437, 37.57052626],
    [126.99694145, 37.57060961],
    [126.99768304, 37.57066517],
    [126.99773304, 37.57066795],
    [126.99788025, 37.57067628],
    [126.998208, 37.57069851],
    [126.99928012, 37.57076519],
    [126.99990506, 37.57080408],
    [127.00059944, 37.57084853],
    [127.00079387, 37.57085965],
    [127.00183266, 37.57092355],
    [127.00184932, 37.57092633],
    [127.00190487, 37.5709291],
    [127.00235206, 37.57094022],
    [127.0027048, 37.57094856],
    [127.00385747, 37.57096247],
    [127.00481572, 37.57097915],
    [127.00485183, 37.57097915],
    [127.00496293, 37.57098193],
    [127.00569064, 37.57099583],
    [127.00669055, 37.57101529],
    [127.00842094, 37.57106254],
    [127.00848205, 37.57107087],
    [127.00884312, 37.57116809],
    [127.00904033, 37.57122364],
    [127.00919031, 37.57126531],
    [127.00933197, 37.57130142],
    [127.01044019, 37.57155418],
    [127.01074016, 37.57162363],
    [127.01082071, 37.57164307],
    [127.01101236, 37.57168751],
    [127.01157619, 37.57181251],
    [127.01182061, 37.57186528],
    [127.012365, 37.57197917],
    [127.01262887, 37.57204306],
    [127.01380097, 37.57240415],
    [127.01420371, 37.57252914],
    [127.01529527, 37.57286801],
    [127.01533137, 37.57287912],
    [127.01553691, 37.572943],
    [127.01555357, 37.57294856],
    [127.01561468, 37.572968],
    [127.01598131, 37.57305689],
    [127.01650348, 37.57318744],
    [127.01716175, 37.57335132],
    [127.01755893, 37.57344854],
    [127.01825886, 37.57367908],
    [127.01887547, 37.57387907],
    [127.02120579, 37.57467902],
    [127.0214391, 37.57477068],
    [127.02254176, 37.57520398],
    [127.02276674, 37.57529286],
    [127.02308615, 37.57541785],
    [127.0231167, 37.57542896],
    [127.02320281, 37.57546507],
    [127.02324725, 37.57548174],
    [127.02329169, 37.57550951],
    [127.02350555, 37.57561506],
    [127.02378608, 37.57573449],
    [127.02448878, 37.57598448],
    [127.02574422, 37.57632613],
    [127.02618862, 37.57644834],
    [127.02638582, 37.5765039],
    [127.02751349, 37.57683166],
    [127.02755515, 37.57684277],
    [127.02784401, 37.57692054],
    [127.02790511, 37.57693721],
    [127.02806899, 37.5769872],
    [127.02817731, 37.57702054],
    [127.02835507, 37.57707331],
    [127.02976604, 37.57747884],
    [127.02998824, 37.57753717],
    [127.03009934, 37.57756495],
    [127.03046319, 37.57765661],
    [127.03050486, 37.57766772],
    [127.03087426, 37.57777883],
    [127.03117423, 37.57787049],
    [127.03144921, 37.57795382],
    [127.03184917, 37.57803993],
    [127.03187694, 37.57804826],
    [127.0322158, 37.57806771],
    [127.03296018, 37.57807605],
    [127.0333407, 37.57807884],
    [127.03415451, 37.57809552],
    [127.03423784, 37.5780983],
    [127.03471835, 37.57810664],
    [127.03487667, 37.57810942],
    [127.03491, 37.57810942],
    [127.03585158, 37.57811499],
    [127.0364543, 37.57811778],
    [127.03654318, 37.57811778],
    [127.03723756, 37.57811502],
    [127.03787639, 37.57811225],
    [127.03824858, 37.57810948],
    [127.03839301, 37.57811226],
    [127.03840135, 37.57811226],
    [127.03869854, 37.57814004],
    [127.03887908, 37.57817337],
    [127.03936514, 37.57827892],
    [127.03977621, 37.57840669],
    [127.04026505, 37.57855669],
    [127.04141771, 37.57893166],
    [127.04248427, 37.5792622],
    [127.04251483, 37.57927331],
    [127.0429148, 37.57878726],
    [127.0432509, 37.57837898],
    [127.04333978, 37.5782901],
    [127.0434731, 37.57820123],
    [127.04354254, 37.57815957],
    [127.04415916, 37.5777624],
    [127.04470357, 37.57745689],
    [127.04494244, 37.57732636],
    [127.04499521, 37.57730136],
    [127.04516464, 37.57722082],
    [127.04565072, 37.57698752],
    [127.04588959, 37.57687365],
    [127.04614235, 37.57673478],
    [127.04650898, 37.57655148],
    [127.04672286, 37.57644594],
    [127.04678674, 37.57641261],
    [127.04681452, 37.57639872],
    [127.04712838, 37.57624597],
    [127.04756168, 37.57603766],
    [127.04846712, 37.57716811],
    [127.04886429, 37.57766528],
    [127.04866987, 37.57774304],
    [127.04864764, 37.57775137],
    [127.0485421, 37.57779581],
    [127.04841711, 37.57783747],
    [127.04808936, 37.57795134],
    [127.04788382, 37.57802633],
    [127.04751996, 37.57815964],
    [127.04746996, 37.5781763],
    [127.04773937, 37.57849572],
    [127.04778381, 37.57855127],
    [127.04783658, 37.57859293]]},
  'properties': {'index': '1',
   'viaPointId': 'vidPoint1',
   'viaPointName': '[0] 강남구청',
   'viaDetailAddress': '',
   'groupKey': '0',
   'arriveTime': '20210525123524',
   'completeTime': '20210525123524',
   'distance': '7387',
   'time': '2124',
   'deliveryTime': '0',
   'waitTime': '0',
   'Fare': '0',
   'poiId': '',
   'pointType': 'B1'}},
 {'type': 'Feature',
  'geometry': {'type': 'Point', 'coordinates': [126.97899006, 37.57916107]},
  'properties': {'index': '2',
   'viaPointId': 'vidPoint2',
   'viaPointName': '[0] 종로구청',
   'viaDetailAddress': '',
   'groupKey': '0',
   'arriveTime': '20210525131057',
   'completeTime': '20210525131057',
   'distance': '7286',
   'deliveryTime': '0',
   'waitTime': '0',
   'pointType': 'B2'}},
 {'type': 'Feature',
  'geometry': {'type': 'LineString',
   'coordinates': [[127.04783658, 37.57859293],
    [127.04778381, 37.57855127],
    [127.04773937, 37.57849572],
    [127.04746996, 37.5781763],
    [127.04736164, 37.57804021],
    [127.04725888, 37.57788744],
    [127.04715612, 37.57767636],
    [127.0471089, 37.57761525],
    [127.04703669, 37.57754859],
    [127.04699225, 37.57750693],
    [127.04687282, 37.57739583],
    [127.04603679, 37.5769903],
    [127.04595902, 37.5769292],
    [127.04588959, 37.57687365],
    [127.04565072, 37.57698752],
    [127.04516464, 37.57722082],
    [127.04499521, 37.57730136],
    [127.04494244, 37.57732636],
    [127.04470357, 37.57745689],
    [127.04415916, 37.5777624],
    [127.04354254, 37.57815957],
    [127.0434731, 37.57820123],
    [127.04333978, 37.5782901],
    [127.0432509, 37.57837898],
    [127.0429148, 37.57878726],
    [127.04251483, 37.57927331],
    [127.04235928, 37.57935941],
    [127.04123162, 37.57901776],
    [127.04020394, 37.57869833],
    [127.03972066, 37.57854279],
    [127.03957345, 37.57849835],
    [127.03897351, 37.57833724],
    [127.03876797, 37.57828447],
    [127.03843189, 37.57826502],
    [127.03839856, 37.57826224],
    [127.03825691, 37.57825946],
    [127.03773751, 37.57825112],
    [127.03723756, 37.57824833],
    [127.03680427, 37.57824833],
    [127.0365154, 37.57824832],
    [127.0362071, 37.57824831],
    [127.03490722, 37.5782344],
    [127.03471557, 37.57822885],
    [127.03423783, 37.57821495],
    [127.03415173, 37.57821495],
    [127.03280185, 37.57819548],
    [127.03204637, 37.57817047],
    [127.03186027, 37.57814825],
    [127.03182972, 37.57814269],
    [127.03174917, 37.57812603],
    [127.03139365, 37.57805936],
    [127.03084926, 37.5779177],
    [127.03051874, 37.57783159],
    [127.03049652, 37.57782604],
    [127.03043541, 37.57780937],
    [127.03006878, 37.57769549],
    [127.0299438, 37.5776566],
    [127.02971882, 37.57758994],
    [127.02894667, 37.57737329],
    [127.02857449, 37.57726496],
    [127.02813286, 37.57713441],
    [127.02804954, 37.57710941],
    [127.02788567, 37.57705941],
    [127.02781345, 37.57703997],
    [127.02751626, 37.57695942],
    [127.02748848, 37.57695109],
    [127.02704964, 37.57682887],
    [127.02602752, 37.57654277],
    [127.02581365, 37.57648444],
    [127.02569422, 37.57645111],
    [127.02558312, 37.57642056],
    [127.02405271, 37.57601502],
    [127.02375274, 37.57589559],
    [127.02337223, 37.57574837],
    [127.02324446, 37.5756956],
    [127.02314447, 37.57565116],
    [127.02305004, 37.5756095],
    [127.02270563, 37.57545951],
    [127.02246954, 37.57535951],
    [127.02143909, 37.57492621],
    [127.02089748, 37.57472345],
    [127.02002257, 37.57441514],
    [127.01882825, 37.57401794],
    [127.01761448, 37.57360963],
    [127.01709786, 37.57347075],
    [127.01591742, 37.57317354],
    [127.01567856, 37.57311243],
    [127.01566189, 37.57310688],
    [127.01561468, 37.57309577],
    [127.01531193, 37.5730041],
    [127.01528138, 37.57299577],
    [127.01432869, 37.5727069],
    [127.01415649, 37.57265412],
    [127.01364265, 37.57250135],
    [127.01253998, 37.57215693],
    [127.01231223, 37.57210138],
    [127.0117845, 37.57198471],
    [127.01094292, 37.57180972],
    [127.01078182, 37.57177639],
    [127.0103152, 37.57167361],
    [127.00974025, 37.57154862],
    [127.00927363, 37.57144029],
    [127.00917364, 37.57145695],
    [127.00912087, 37.57146806],
    [127.00907643, 37.57148472],
    [127.0089431, 37.5715486],
    [127.00825426, 37.57226795],
    [127.00796261, 37.57253736],
    [127.00766541, 37.57281232],
    [127.00749042, 37.57299841],
    [127.0074182, 37.57306784],
    [127.00740154, 37.57308729],
    [127.00724043, 37.57324838],
    [127.00717933, 37.57331226],
    [127.00701267, 37.57349001],
    [127.00678491, 37.5737372],
    [127.00675157, 37.57377608],
    [127.00665436, 37.57387885],
    [127.00662936, 37.57390384],
    [127.00653214, 37.57400105],
    [127.00642382, 37.57412326],
    [127.00607106, 37.57450932],
    [127.00555998, 37.57506758],
    [127.00552665, 37.57510646],
    [127.00506001, 37.57553418],
    [127.00501835, 37.57557306],
    [127.00497946, 37.57560917],
    [127.00492669, 37.57565083],
    [127.00481559, 37.57571193],
    [127.00450172, 37.5758758],
    [127.00416564, 37.57599245],
    [127.00386011, 37.57605632],
    [127.00374067, 37.57607021],
    [127.00340737, 37.57610631],
    [127.00273521, 37.57615351],
    [127.00221859, 37.5761535],
    [127.00211304, 37.57615072],
    [127.00112702, 37.57605905],
    [127.00091593, 37.57603127],
    [127.00018544, 37.57595627],
    [127.00008545, 37.57594516],
    [126.99942996, 37.57587848],
    [126.99918554, 37.5758757],
    [126.99879668, 37.57587292],
    [126.9978801, 37.57592567],
    [126.99764123, 37.57593678],
    [126.99755791, 37.57593955],
    [126.9974357, 37.57594511],
    [126.99740237, 37.57594788],
    [126.99731071, 37.57595066],
    [126.9971635, 37.57596177],
    [126.99711628, 37.5759701],
    [126.99706906, 37.57598399],
    [126.99645244, 37.57621728],
    [126.99589416, 37.57645058],
    [126.99339158, 37.57748375],
    [126.99324437, 37.57754485],
    [126.99308327, 37.57759206],
    [126.99291384, 37.57762539],
    [126.9927333, 37.57763927],
    [126.99252498, 37.57764482],
    [126.99235, 37.57764482],
    [126.99147786, 37.57760592],
    [126.99080014, 37.57753369],
    [126.98995578, 37.57744758],
    [126.98942527, 37.57736424],
    [126.98935306, 37.57736146],
    [126.98931973, 37.57736146],
    [126.98929751, 37.57736146],
    [126.98923918, 37.57736146],
    [126.98913641, 37.57736146],
    [126.98874478, 37.57735868],
    [126.98865868, 37.57735867],
    [126.98855869, 37.57735867],
    [126.98821705, 37.57736422],
    [126.98812539, 37.577367],
    [126.98797541, 37.57736977],
    [126.98762266, 37.57734755],
    [126.98751712, 37.57733643],
    [126.98743379, 37.5773281],
    [126.98734213, 37.57731977],
    [126.98729769, 37.57731143],
    [126.98708105, 37.57726699],
    [126.9868394, 37.57718644],
    [126.98650333, 37.57704478],
    [126.98640889, 37.57700312],
    [126.98613948, 37.57684758],
    [126.98608115, 37.5768198],
    [126.98575896, 37.57667259],
    [126.9857173, 37.57665315],
    [126.98556454, 37.57658926],
    [126.98541733, 37.57653093],
    [126.98478128, 37.57627262],
    [126.98451742, 37.57615318],
    [126.98425634, 37.57603375],
    [126.98406747, 37.57595875],
    [126.9834592, 37.57575599],
    [126.98324811, 37.57568655],
    [126.98312867, 37.575656],
    [126.98304257, 37.57563377],
    [126.98302313, 37.575631],
    [126.98295369, 37.57562266],
    [126.98279259, 37.57562266],
    [126.98272871, 37.57562821],
    [126.98245374, 37.57564765],
    [126.98129273, 37.57582261],
    [126.98063723, 37.57591703],
    [126.98022893, 37.57596146],
    [126.97984008, 37.57596423],
    [126.97979564, 37.57595868],
    [126.97973175, 37.5759559],
    [126.97969287, 37.57596979],
    [126.97965398, 37.57598367],
    [126.97959288, 37.57601422],
    [126.9795651, 37.576042],
    [126.97954566, 37.57607533],
    [126.97953455, 37.57609755],
    [126.97957341, 37.57667248],
    [126.97957897, 37.57679469],
    [126.97959284, 37.57713632],
    [126.97962337, 37.577914],
    [126.97964559, 37.57823341],
    [126.9796539, 37.57876946],
    [126.97967334, 37.57908609],
    [126.97973166, 37.5792944],
    [126.97983997, 37.57969158],
    [126.97992329, 37.57994988],
    [126.97981497, 37.5799721],
    [126.97964555, 37.57946382],
    [126.97954557, 37.57909442]]},
  'properties': {'index': '2',
   'viaPointId': 'vidPoint2',
   'viaPointName': '[0] 종로구청',
   'viaDetailAddress': '',
   'groupKey': '0',
   'arriveTime': '20210525131057',
   'completeTime': '20210525131057',
   'distance': '7286',
   'time': '2133',
   'deliveryTime': '0',
   'waitTime': '0',
   'Fare': '0',
   'poiId': '',
   'pointType': 'B2'}},
 {'type': 'Feature',
  'geometry': {'type': 'Point', 'coordinates': [127.0326935, 37.57916203]},
  'properties': {'index': '3',
   'viaPointId': 'vidPoint3',
   'viaPointName': '[0] 서초구청',
   'viaDetailAddress': '',
   'groupKey': '0',
   'arriveTime': '20210525134025',
   'completeTime': '20210525134025',
   'distance': '6466',
   'deliveryTime': '0',
   'waitTime': '0',
   'pointType': 'B3'}},
 {'type': 'Feature',
  'geometry': {'type': 'LineString',
   'coordinates': [[126.97954557, 37.57909442],
    [126.9794845, 37.577889],
    [126.97946231, 37.57679469],
    [126.97946509, 37.57663359],
    [126.97947065, 37.57648639],
    [126.97946787, 37.57645861],
    [126.97944843, 37.57642806],
    [126.97926234, 37.57621697],
    [126.97924846, 37.57614476],
    [126.97924291, 37.57597533],
    [126.97924291, 37.57592812],
    [126.97950678, 37.57580591],
    [126.97987063, 37.57583925],
    [126.97996507, 37.57584203],
    [126.98019838, 37.57582815],
    [126.98081499, 37.57575316],
    [126.98146771, 37.57565874],
    [126.98201489, 37.57557265],
    [126.98242041, 37.57552266],
    [126.98270927, 37.57550045],
    [126.98283982, 37.5754949],
    [126.98293147, 37.57548934],
    [126.9830398, 37.57550323],
    [126.98319534, 37.57553379],
    [126.983287, 37.57555879],
    [126.98335366, 37.57557823],
    [126.98349809, 37.57563934],
    [126.98366751, 37.57572266],
    [126.98406747, 37.57595875],
    [126.98425634, 37.57603375],
    [126.98451742, 37.57615318],
    [126.98478128, 37.57627262],
    [126.98541733, 37.57653093],
    [126.98556454, 37.57658926],
    [126.9857173, 37.57665315],
    [126.98575896, 37.57667259],
    [126.98608115, 37.5768198],
    [126.98613948, 37.57684758],
    [126.98640889, 37.57700312],
    [126.98650333, 37.57704478],
    [126.9868394, 37.57718644],
    [126.98708105, 37.57726699],
    [126.98729769, 37.57731143],
    [126.98734213, 37.57731977],
    [126.98743379, 37.5773281],
    [126.98751712, 37.57733643],
    [126.98762266, 37.57734755],
    [126.98797541, 37.57736977],
    [126.98812539, 37.577367],
    [126.98821705, 37.57736422],
    [126.98855869, 37.57735867],
    [126.98865868, 37.57735867],
    [126.98874478, 37.57735868],
    [126.98913641, 37.57736146],
    [126.98923918, 37.57736146],
    [126.98929751, 37.57736146],
    [126.98931973, 37.57736146],
    [126.98935306, 37.57736146],
    [126.98942527, 37.57736424],
    [126.98971692, 37.57733647],
    [126.99008355, 37.57736426],
    [126.99035574, 37.57739481],
    [126.99040018, 37.57739759],
    [126.99081126, 37.57744481],
    [126.99127788, 37.57749482],
    [126.99185838, 37.57752816],
    [126.99218613, 37.57753372],
    [126.99234723, 37.57752539],
    [126.99254165, 37.57752539],
    [126.9927333, 37.57751429],
    [126.99290551, 37.57748929],
    [126.99305827, 37.5774643],
    [126.99320271, 37.57742264],
    [126.99334714, 37.57737265],
    [126.99584416, 37.57635337],
    [126.99642745, 37.57611729],
    [126.9968052, 37.57596176],
    [126.99701351, 37.57587844],
    [126.99704684, 37.57586455],
    [126.9971024, 37.57585067],
    [126.99715795, 37.57584511],
    [126.99723294, 37.57583956],
    [126.99731904, 37.57583401],
    [126.99756624, 37.5758229],
    [126.99764401, 37.57582013],
    [126.99777733, 37.57581457],
    [126.9978801, 37.5758118],
    [126.99879668, 37.57587292],
    [126.99918554, 37.5758757],
    [126.99942996, 37.57587848],
    [127.00008545, 37.57594516],
    [127.00018544, 37.57595627],
    [127.00091593, 37.57603127],
    [127.00112702, 37.57605905],
    [127.00211304, 37.57615072],
    [127.00221859, 37.5761535],
    [127.00273521, 37.57615351],
    [127.00340737, 37.57610631],
    [127.00374067, 37.57607021],
    [127.00386011, 37.57605632],
    [127.00416564, 37.57599245],
    [127.00450172, 37.5758758],
    [127.00481559, 37.57571193],
    [127.00492669, 37.57565083],
    [127.00497946, 37.57560917],
    [127.00501835, 37.57557306],
    [127.00506001, 37.57553418],
    [127.00552665, 37.57510646],
    [127.00555998, 37.57506758],
    [127.00607106, 37.57450932],
    [127.00642382, 37.57412326],
    [127.00653214, 37.57400105],
    [127.00662936, 37.57390384],
    [127.00665436, 37.57387885],
    [127.00675157, 37.57377608],
    [127.00678491, 37.5737372],
    [127.00701267, 37.57349001],
    [127.00717933, 37.57331226],
    [127.00724043, 37.57324838],
    [127.00740154, 37.57308729],
    [127.0074182, 37.57306784],
    [127.00749042, 37.57299841],
    [127.00766541, 37.57281232],
    [127.00817649, 37.57217629],
    [127.00894589, 37.57134029],
    [127.00919031, 37.57126531],
    [127.00933197, 37.57130142],
    [127.01044019, 37.57155418],
    [127.01074016, 37.57162363],
    [127.01082071, 37.57164307],
    [127.01101236, 37.57168751],
    [127.01157619, 37.57181251],
    [127.01182061, 37.57186528],
    [127.012365, 37.57197917],
    [127.01262887, 37.57204306],
    [127.01380097, 37.57240415],
    [127.01420371, 37.57252914],
    [127.01529527, 37.57286801],
    [127.01533137, 37.57287912],
    [127.01553691, 37.572943],
    [127.01555357, 37.57294856],
    [127.01561468, 37.572968],
    [127.01598131, 37.57305689],
    [127.01650348, 37.57318744],
    [127.01716175, 37.57335132],
    [127.01755893, 37.57344854],
    [127.01825886, 37.57367908],
    [127.01887547, 37.57387907],
    [127.02120579, 37.57467902],
    [127.0214391, 37.57477068],
    [127.02254176, 37.57520398],
    [127.02276674, 37.57529286],
    [127.02308615, 37.57541785],
    [127.0231167, 37.57542896],
    [127.02320281, 37.57546507],
    [127.02324725, 37.57548174],
    [127.02329169, 37.57550951],
    [127.02350555, 37.57561506],
    [127.02378608, 37.57573449],
    [127.02448878, 37.57598448],
    [127.02574422, 37.57632613],
    [127.02618862, 37.57644834],
    [127.02638582, 37.5765039],
    [127.02751349, 37.57683166],
    [127.02755515, 37.57684277],
    [127.02784401, 37.57692054],
    [127.02790511, 37.57693721],
    [127.02806899, 37.5769872],
    [127.02817731, 37.57702054],
    [127.02835507, 37.57707331],
    [127.02976604, 37.57747884],
    [127.02998824, 37.57753717],
    [127.03009934, 37.57756495],
    [127.03046319, 37.57765661],
    [127.03050486, 37.57766772],
    [127.03087426, 37.57777883],
    [127.03117423, 37.57787049],
    [127.03117424, 37.57763996],
    [127.03117425, 37.57731222],
    [127.03049932, 37.57710946],
    [127.03048542, 37.57732054],
    [127.03047431, 37.57753996],
    [127.03046319, 37.57765661],
    [127.03043541, 37.57780937],
    [127.0303743, 37.57815655],
    [127.03033541, 37.57832598],
    [127.03026874, 37.57868427],
    [127.0301104, 37.57948417],
    [127.03001317, 37.58002022],
    [127.02999372, 37.58011465],
    [127.02991872, 37.58052571],
    [127.0298326, 37.58096733],
    [127.02977704, 37.58125063],
    [127.03015201, 37.58127563],
    [127.03051309, 37.58129786],
    [127.03132412, 37.5813312],
    [127.03140189, 37.58133676],
    [127.03159076, 37.58135065],
    [127.03174076, 37.58102569],
    [127.03179909, 37.58089793],
    [127.03201853, 37.58040632],
    [127.03206297, 37.58030633],
    [127.03232963, 37.57960364],
    [127.03239074, 37.5794731],
    [127.03246296, 37.57934812],
    [127.03251574, 37.57928702],
    [127.0326074, 37.57913426]]},
  'properties': {'index': '3',
   'viaPointId': 'vidPoint3',
   'viaPointName': '[0] 서초구청',
   'viaDetailAddress': '',
   'groupKey': '0',
   'arriveTime': '20210525134025',
   'completeTime': '20210525134025',
   'distance': '6466',
   'time': '1768',
   'deliveryTime': '0',
   'waitTime': '0',
   'Fare': '0',
   'poiId': '',
   'pointType': 'B3'}},
 {'type': 'Feature',
  'geometry': {'type': 'Point', 'coordinates': [126.93681613, 37.57916309]},
  'properties': {'index': '4',
   'viaPointId': '',
   'viaPointName': '[0] 서대문구청',
   'arriveTime': '20210525141155',
   'completeTime': '20210525141155',
   'distance': '16309',
   'deliveryTime': '0',
   'waitTime': '0',
   'pointType': 'E'}},
 {'type': 'Feature',
  'geometry': {'type': 'LineString',
   'coordinates': [[127.03261296, 37.57912037],
    [127.03284906, 37.57866487],
    [127.03285184, 37.57863154],
    [127.0328324, 37.57855377],
    [127.03282962, 37.57853433],
    [127.03281574, 37.57836491],
    [127.03280185, 37.57819548],
    [127.03296018, 37.57807605],
    [127.0333407, 37.57807884],
    [127.03415451, 37.57809552],
    [127.03423784, 37.5780983],
    [127.03471835, 37.57810664],
    [127.03487667, 37.57810942],
    [127.03491, 37.57810942],
    [127.03585158, 37.57811499],
    [127.0364543, 37.57811778],
    [127.03654318, 37.57811778],
    [127.03723756, 37.57811502],
    [127.03787639, 37.57811225],
    [127.03805138, 37.57801504],
    [127.0380986, 37.57797894],
    [127.03813749, 37.57794005],
    [127.03823748, 37.57782062],
    [127.03823748, 37.57772341],
    [127.03823193, 37.57756232],
    [127.03823472, 37.57709293],
    [127.03823751, 37.57681518],
    [127.03823473, 37.57673186],
    [127.03819587, 37.57596251],
    [127.03815422, 37.57541257],
    [127.03812646, 37.57489318],
    [127.03811536, 37.57477098],
    [127.03809036, 37.57455433],
    [127.03805149, 37.57416549],
    [127.03804871, 37.57409328],
    [127.03804594, 37.57401551],
    [127.03802095, 37.573585],
    [127.03802095, 37.57356278],
    [127.0380043, 37.57331559],
    [127.03799319, 37.57318505],
    [127.03784321, 37.57297396],
    [127.03777933, 37.57290174],
    [127.03771267, 37.57283508],
    [127.03762935, 37.57277953],
    [127.03736548, 37.5726601],
    [127.03729882, 37.57265454],
    [127.0372155, 37.57264343],
    [127.03692664, 37.57261287],
    [127.03664611, 37.57257398],
    [127.03637391, 37.57252954],
    [127.03607672, 37.57251842],
    [127.03591562, 37.57252953],
    [127.03585174, 37.57254342],
    [127.03574063, 37.57259619],
    [127.03555176, 37.57270173],
    [127.03536566, 37.57280727],
    [127.03513235, 37.57296558],
    [127.03503513, 37.57305168],
    [127.03492125, 37.57317944],
    [127.03485736, 37.57327109],
    [127.03477681, 37.57340441],
    [127.03470181, 37.57360161],
    [127.03464903, 37.57382936],
    [127.0346268, 37.57405711],
    [127.03461569, 37.57417098],
    [127.03459346, 37.57460149],
    [127.034599, 37.57504588],
    [127.0345851, 37.57548472],
    [127.03453787, 37.57592355],
    [127.03447953, 37.57623463],
    [127.03445173, 37.57739838],
    [127.03444616, 37.57794832],
    [127.03447392, 37.57848159],
    [127.03452112, 37.57900653],
    [127.03457944, 37.57937871],
    [127.03464053, 37.57974533],
    [127.03471274, 37.58009252],
    [127.03478772, 37.58043137],
    [127.03491825, 37.58099242],
    [127.03506822, 37.58162568],
    [127.03515709, 37.58202008],
    [127.03541814, 37.58329216],
    [127.0355931, 37.58416984],
    [127.03567086, 37.58452535],
    [127.03576806, 37.58487254],
    [127.03588193, 37.58523083],
    [127.03594858, 37.58541692],
    [127.03606801, 37.585703],
    [127.03617077, 37.5859252],
    [127.03626798, 37.58611962],
    [127.03631242, 37.58620295],
    [127.03674847, 37.58701953],
    [127.03749003, 37.58838883],
    [127.03801217, 37.58948871],
    [127.03847043, 37.59050526],
    [127.03884815, 37.5913885],
    [127.03915366, 37.59208843],
    [127.03944806, 37.59276613],
    [127.03968691, 37.59332163],
    [127.04005074, 37.59414931],
    [127.04014517, 37.59439095],
    [127.04031736, 37.59484646],
    [127.04039513, 37.59509088],
    [127.04042012, 37.5951742],
    [127.04046456, 37.59532418],
    [127.04051733, 37.59549917],
    [127.04057565, 37.59571859],
    [127.04066174, 37.59606299],
    [127.04072839, 37.59639906],
    [127.04078671, 37.59672403],
    [127.04083947, 37.59710454],
    [127.04086446, 37.59731007],
    [127.04089501, 37.59763781],
    [127.04091722, 37.59801832],
    [127.04092554, 37.59838217],
    [127.04093108, 37.59873213],
    [127.04093663, 37.59909598],
    [127.04092829, 37.59928762],
    [127.04092551, 37.59944594],
    [127.04090051, 37.59962369],
    [127.04086162, 37.59981811],
    [127.04081995, 37.59997087],
    [127.0407505, 37.60017085],
    [127.0406894, 37.60030972],
    [127.04065051, 37.6003986],
    [127.04052551, 37.6006319],
    [127.04040885, 37.60079577],
    [127.04030886, 37.60093186],
    [127.04026441, 37.60099297],
    [127.04012553, 37.60113461],
    [127.0400061, 37.60127071],
    [127.03983944, 37.60141235],
    [127.03968112, 37.60154845],
    [127.03948669, 37.60167898],
    [127.03934781, 37.60177341],
    [127.03918671, 37.60186229],
    [127.0389895, 37.60196783],
    [127.03876452, 37.60206781],
    [127.0385812, 37.60213447],
    [127.03831178, 37.6022289],
    [127.03796736, 37.60231499],
    [127.03769794, 37.60236776],
    [127.03720076, 37.60244274],
    [127.03636473, 37.60253716],
    [127.03543425, 37.6026538],
    [127.03509539, 37.6026899],
    [127.03497596, 37.60270378],
    [127.03490097, 37.60271211],
    [127.03438434, 37.60277599],
    [127.03416492, 37.60280931],
    [127.0337094, 37.60290096],
    [127.03331221, 37.60300927],
    [127.03306223, 37.60309537],
    [127.03284558, 37.60317036],
    [127.03247895, 37.60333144],
    [127.03211509, 37.60350364],
    [127.03165957, 37.60372027],
    [127.03114572, 37.60396746],
    [127.03109017, 37.60399523],
    [127.03101239, 37.60403134],
    [127.03073741, 37.60415909],
    [127.03051521, 37.6042563],
    [127.0302569, 37.60435906],
    [127.03005969, 37.60442572],
    [127.02953474, 37.60457291],
    [127.02951251, 37.60458124],
    [127.02920976, 37.6046479],
    [127.02884313, 37.60472844],
    [127.02861815, 37.60477287],
    [127.02842927, 37.60479231],
    [127.0281793, 37.60480897],
    [127.02793487, 37.60479786],
    [127.02767379, 37.6047673],
    [127.02746825, 37.60472008],
    [127.02729327, 37.60467286],
    [127.02718495, 37.6046312],
    [127.02700997, 37.60456176],
    [127.02682943, 37.6044701],
    [127.02671278, 37.60439788],
    [127.02656835, 37.60429789],
    [127.02640448, 37.60416179],
    [127.02625449, 37.60400903],
    [127.02612951, 37.60385905],
    [127.02581011, 37.60338409],
    [127.02573512, 37.603273],
    [127.02569068, 37.60320634],
    [127.02558236, 37.60305913],
    [127.02543793, 37.6028897],
    [127.02533517, 37.60278416],
    [127.02523796, 37.60268972],
    [127.0251102, 37.60257029],
    [127.02487411, 37.60240086],
    [127.02476579, 37.60233142],
    [127.0245797, 37.60222587],
    [127.02440194, 37.60213699],
    [127.02412697, 37.60202311],
    [127.02386033, 37.60193145],
    [127.02351036, 37.6018509],
    [127.02346037, 37.60183701],
    [127.02334093, 37.60181757],
    [127.02305485, 37.60177312],
    [127.02292708, 37.60175645],
    [127.02257434, 37.60174256],
    [127.02235769, 37.60174533],
    [127.02216882, 37.60175644],
    [127.02195217, 37.6017731],
    [127.02172164, 37.60180643],
    [127.02151054, 37.60184531],
    [127.02132723, 37.60188974],
    [127.0211078, 37.60194807],
    [127.0208356, 37.60202861],
    [127.02064117, 37.60208415],
    [127.02052174, 37.60212026],
    [127.02029398, 37.60218691],
    [127.02007733, 37.60224801],
    [127.0198829, 37.60230634],
    [127.01976347, 37.60234244],
    [127.01900242, 37.60256462],
    [127.0179414, 37.60287568],
    [127.01723868, 37.60308675],
    [127.01695814, 37.60317007],
    [127.01640541, 37.60332838],
    [127.01614988, 37.60340336],
    [127.01576935, 37.60349779],
    [127.01542772, 37.60354778],
    [127.01514441, 37.60356999],
    [127.01487499, 37.60357277],
    [127.01468334, 37.60356443],
    [127.01460001, 37.60355887],
    [127.01420561, 37.60351998],
    [127.01397229, 37.60351998],
    [127.01375009, 37.60353664],
    [127.01359177, 37.60356163],
    [127.01346123, 37.60358663],
    [127.01332791, 37.60362273],
    [127.01316125, 37.6036755],
    [127.01301126, 37.6037366],
    [127.01281961, 37.60382548],
    [127.01265574, 37.60392546],
    [127.01237798, 37.60413654],
    [127.01228076, 37.60421431],
    [127.01209189, 37.6043504],
    [127.01185024, 37.60450038],
    [127.01162525, 37.60462536],
    [127.01143083, 37.60472257],
    [127.0112364, 37.60480867],
    [127.01088365, 37.6049642],
    [127.01037813, 37.60518361],
    [127.01016981, 37.60527248],
    [127.00970874, 37.60546967],
    [127.00891713, 37.60581406],
    [127.00817553, 37.60613624],
    [127.00748947, 37.60643063],
    [127.00675342, 37.60675003],
    [127.006409, 37.6069],
    [127.00584238, 37.60714441],
    [127.0055174, 37.60727217],
    [127.00502856, 37.60741103],
    [127.00470636, 37.60746657],
    [127.00450916, 37.60749712],
    [127.00409808, 37.60751933],
    [127.00390643, 37.60751655],
    [127.00347592, 37.6074971],
    [127.00328149, 37.6074971],
    [127.00311484, 37.60750265],
    [127.00295096, 37.60751931],
    [127.00272876, 37.60754708],
    [127.00253156, 37.60758597],
    [127.00238157, 37.60762485],
    [127.0021927, 37.60767206],
    [127.00170662, 37.60784148],
    [127.00114834, 37.60803311],
    [126.99949291, 37.60859968],
    [126.99898185, 37.60876632],
    [126.99791249, 37.60911348],
    [126.99787916, 37.60912459],
    [126.99777639, 37.60915792],
    [126.99735698, 37.60929123],
    [126.99717644, 37.60934955],
    [126.99678203, 37.60947731],
    [126.99629318, 37.60963839],
    [126.99579044, 37.60980225],
    [126.99554602, 37.60987724],
    [126.99522104, 37.60996334],
    [126.99499606, 37.61000777],
    [126.99477108, 37.61004387],
    [126.99461276, 37.61006609],
    [126.99437667, 37.61008553],
    [126.99420724, 37.61009386],
    [126.99397949, 37.61009941],
    [126.99378228, 37.61009385],
    [126.99360452, 37.61008829],
    [126.99337676, 37.61006329],
    [126.99304624, 37.61002162],
    [126.99247685, 37.6099494],
    [126.99198245, 37.60988273],
    [126.99172137, 37.60984662],
    [126.99119086, 37.60977717],
    [126.98960768, 37.60956606],
    [126.98836057, 37.60940772],
    [126.98562194, 37.60905494],
    [126.98385267, 37.60880493],
    [126.98233892, 37.60858549],
    [126.98116959, 37.60844104],
    [126.98015858, 37.60830215],
    [126.97878926, 37.60811048],
    [126.97766437, 37.60797159],
    [126.97635894, 37.60778547],
    [126.97564789, 37.6076327],
    [126.97521738, 37.60751882],
    [126.97487853, 37.60741604],
    [126.97445357, 37.60727439],
    [126.97420915, 37.6071855],
    [126.9738453, 37.60704107],
    [126.97368143, 37.60696607],
    [126.97347311, 37.60687442],
    [126.97305649, 37.60667999],
    [126.97299261, 37.60664388],
    [126.97233712, 37.60627446],
    [126.97187606, 37.60596338],
    [126.97169553, 37.6058495],
    [126.97108726, 37.60537732],
    [126.97066231, 37.6049857],
    [126.96946246, 37.60376637],
    [126.96803763, 37.60224152],
    [126.96677945, 37.60088332],
    [126.96577124, 37.5998001],
    [126.96374649, 37.59760587],
    [126.96339375, 37.59730868],
    [126.96284937, 37.59690872],
    [126.96262439, 37.59678095],
    [126.96214111, 37.59653097],
    [126.96189113, 37.59641987],
    [126.96149673, 37.59627543],
    [126.96128564, 37.59621432],
    [126.96110232, 37.59615877],
    [126.96070514, 37.59607266],
    [126.96033018, 37.596006],
    [126.95990244, 37.59596155],
    [126.95945804, 37.59593655],
    [126.95884698, 37.59591154],
    [126.95838036, 37.59589764],
    [126.95734434, 37.59586985],
    [126.95692216, 37.59586429],
    [126.95654719, 37.5958865],
    [126.95644998, 37.59590039],
    [126.95609723, 37.59595871],
    [126.95575559, 37.59603925],
    [126.95518064, 37.59620866],
    [126.95511676, 37.59622532],
    [126.95464457, 37.59633364],
    [126.95428349, 37.59638362],
    [126.95418628, 37.59639473],
    [126.95384187, 37.59640861],
    [126.95362244, 37.5963975],
    [126.95337802, 37.59638083],
    [126.95303361, 37.59631972],
    [126.95276697, 37.59625861],
    [126.95255032, 37.59618639],
    [126.95235312, 37.5961114],
    [126.95220869, 37.59605585],
    [126.95184206, 37.59589475],
    [126.95163653, 37.59580587],
    [126.95100882, 37.59553644],
    [126.95058664, 37.59537534],
    [126.95023945, 37.59527812],
    [126.94992559, 37.59519757],
    [126.94971172, 37.59515313],
    [126.94919511, 37.59506424],
    [126.94902846, 37.59503646],
    [126.94840629, 37.59493924],
    [126.94799522, 37.59492535],
    [126.94779246, 37.59488368],
    [126.94752582, 37.59479758],
    [126.94724807, 37.59468925],
    [126.94688422, 37.59451982],
    [126.94670924, 37.59442261],
    [126.94657314, 37.59433372],
    [126.94641205, 37.59421151],
    [126.94623152, 37.59405875],
    [126.94604821, 37.59385044],
    [126.945901, 37.59367823],
    [126.94573436, 37.59346714],
    [126.94560382, 37.59330883],
    [126.94534552, 37.59304774],
    [126.94513165, 37.5928422],
    [126.94490668, 37.59271166],
    [126.94454838, 37.59252001],
    [126.9440901, 37.59230614],
    [126.9438429, 37.59223392],
    [126.94379568, 37.5922117],
    [126.94376513, 37.59222836],
    [126.94375402, 37.59223392],
    [126.94373735, 37.59223392],
    [126.94372069, 37.59223392],
    [126.94359292, 37.5922117],
    [126.94342349, 37.59217003],
    [126.9420653, 37.59175339],
    [126.94168478, 37.59161729],
    [126.94160423, 37.59158951],
    [126.94155701, 37.59157562],
    [126.94148758, 37.59155062],
    [126.94130148, 37.59147563],
    [126.9409543, 37.59132564],
    [126.94078209, 37.59124787],
    [126.94033214, 37.591009],
    [126.93939613, 37.59051182],
    [126.93841568, 37.59001186],
    [126.93830458, 37.58995075],
    [126.93800183, 37.58979243],
    [126.93776019, 37.58965633],
    [126.93746578, 37.58949523],
    [126.93712693, 37.58929803],
    [126.93684362, 37.58913693],
    [126.93657699, 37.58895084],
    [126.93650199, 37.58890084],
    [126.93631035, 37.5887703],
    [126.93624925, 37.58871753],
    [126.93615203, 37.58863142],
    [126.93601038, 37.58848699],
    [126.93593539, 37.58840089],
    [126.93584929, 37.58830368],
    [126.93546601, 37.58774262],
    [126.93519105, 37.58728156],
    [126.93500774, 37.58689827],
    [126.93497442, 37.58681495],
    [126.93490776, 37.58665663],
    [126.93486332, 37.58649276],
    [126.93485777, 37.58643443],
    [126.93484944, 37.58619557],
    [126.93486056, 37.5861178],
    [126.93489667, 37.58584006],
    [126.9349689, 37.58554565],
    [126.93508556, 37.58523735],
    [126.93521889, 37.58496239],
    [126.93589108, 37.58379309],
    [126.93604386, 37.58346258],
    [126.93611053, 37.58319317],
    [126.93616331, 37.58291264],
    [126.93617164, 37.58276822],
    [126.93619388, 37.58231827],
    [126.93618555, 37.58215995],
    [126.93616333, 37.58189609],
    [126.93616056, 37.58186554],
    [126.93616056, 37.5818461],
    [126.93616056, 37.58181277],
    [126.93616056, 37.581785],
    [126.93616057, 37.58155447],
    [126.93615779, 37.58148781],
    [126.9361467, 37.58092121],
    [126.93613837, 37.5805768],
    [126.9361356, 37.58030461],
    [126.93613561, 37.58018796],
    [126.93614395, 37.57978523],
    [126.93614673, 37.5797269],
    [126.93641893, 37.57968525],
    [126.93662169, 37.57963525],
    [126.93672724, 37.57960193],
    [126.93689111, 37.57953527],
    [126.93706332, 37.57942695],
    [126.93699667, 37.57912421]]},
  'properties': {'index': '4',
   'viaPointId': '',
   'viaPointName': '[0] 서대문구청',
   'arriveTime': '20210525141155',
   'completeTime': '20210525141155',
   'distance': '16309',
   'time': '1890',
   'deliveryTime': '0',
   'waitTime': '0',
   'Fare': '0',
   'poiId': '',
   'pointType': 'E'}}]

리턴되면 굉장히 복잡하고 LineString이 길게 나옵니다. 이것을 geopandas의 GeoDataFrame 형식으로 바꾸겠습니다.

df = pd.DataFrame([
    [res["features"][li[0]]["properties"]["viaPointName"], 
     res["features"][li[1]]["properties"]["viaPointName"], 
     res["features"][li[0]]["geometry"]["coordinates"], 
     res["features"][li[1]]["geometry"]["coordinates"], 
     LineString(res["features"][li[2]]["geometry"]["coordinates"])] for li in [[0,1,2], [1,3,4], [3,5,6], [5,7,8]]
],
    columns = ["start_name", "end_name", "start_point", "end_point", "geometry"])
df
start_name end_name start_point end_point geometry
0 [0] 서울특별시청 [0] 강남구청 [126.97865155, 37.56682361] [127.04737828, 37.5791623] LINESTRING (126.97865988 37.56701525, 126.9781...
1 [0] 강남구청 [0] 종로구청 [127.04737828, 37.5791623] [126.97899006, 37.57916107] LINESTRING (127.04783658 37.57859293, 127.0477...
2 [0] 종로구청 [0] 서초구청 [126.97899006, 37.57916107] [127.0326935, 37.57916203] LINESTRING (126.97954557 37.57909442, 126.9794...
3 [0] 서초구청 [0] 서대문구청 [127.0326935, 37.57916203] [126.93681613, 37.57916309] LINESTRING (127.03261296 37.57912037, 127.0328...
df["start_name"] = df["start_name"].str.replace(pat = "\[0\]", repl = "")
df["end_name"] = df["end_name"].str.replace(pat = "\[0\]", repl = "")
df
start_name end_name start_point end_point geometry
0 서울특별시청 강남구청 [126.97865155, 37.56682361] [127.04737828, 37.5791623] LINESTRING (126.97865988 37.56701525, 126.9781...
1 강남구청 종로구청 [127.04737828, 37.5791623] [126.97899006, 37.57916107] LINESTRING (127.04783658 37.57859293, 127.0477...
2 종로구청 서초구청 [126.97899006, 37.57916107] [127.0326935, 37.57916203] LINESTRING (126.97954557 37.57909442, 126.9794...
3 서초구청 서대문구청 [127.0326935, 37.57916203] [126.93681613, 37.57916309] LINESTRING (127.03261296 37.57912037, 127.0328...
# 공간 관련 데이터프레임으로 만들어줌
gdf = gpd.GeoDataFrame(df, geometry = "geometry")
gdf
start_name end_name start_point end_point geometry
0 서울특별시청 강남구청 [126.97865155, 37.56682361] [127.04737828, 37.5791623] LINESTRING (126.97865988 37.56701525, 126.9781...
1 강남구청 종로구청 [127.04737828, 37.5791623] [126.97899006, 37.57916107] LINESTRING (127.04783658 37.57859293, 127.0477...
2 종로구청 서초구청 [126.97899006, 37.57916107] [127.0326935, 37.57916203] LINESTRING (126.97954557 37.57909442, 126.9794...
3 서초구청 서대문구청 [127.0326935, 37.57916203] [126.93681613, 37.57916309] LINESTRING (127.03261296 37.57912037, 127.0328...

다중 경로 탐색에 대해서 아래의 folium으로 시각화해보겠습니다.
다중 경유지는 순서를 중요시하다보니 param에 넣는 것이나 그걸 다시 보기 편한 데이터로 만드는데 조금 복잡한 부분이 있었습니다.


m = folium.Map(
    location=[gdf["start_point"][0][1],gdf["start_point"][0][0]],
    zoom_start=13
)

for i in range(len(gdf)) :
    folium.Marker(
        [gdf["start_point"][i][1], gdf["start_point"][i][0]], popup= gdf["start_name"][i]
    ).add_to(m)

folium.Marker(
        [gdf["end_point"][i][1], gdf["end_point"][i][0]], popup= gdf["end_name"][i]
).add_to(m)
    
folium.GeoJson(
        gdf.to_json()
).add_to(m)

m



그럼 이제 경로 최적화를 실습해보겠습니다.

headers = {}
headers["appKey"] = key_csv.loc["tmap_key"]["value"]
headers["Content-Type"] = "application/json"
param = {}
# 여기서 좌표값을 string 타입으로 바꿔주지 않으면, api자체에서 type error가 뜹니다. 주의해서 string으로 바꿔주시길 바랍니다.
param["startName"] = list(points_.keys())[0]
param["startX"] = str(list(points_.values())[0][0])
param["startY"] = str(list(points_.values())[0][1])
param["startTime"] = "202105251200"
param["endName"] = list(points_.keys())[4]
param["endX"] = str(list(points_.values())[4][0])
param["endY"] = str(list(points_.values())[4][1])
param
{'startName': '서울특별시청',
 'startX': '126.978652258823',
 'startY': '37.56682420267543',
 'startTime': '202105251200',
 'endName': '서대문구청',
 'endX': '126.9368156604',
 'endY': '37.5791618639849'}
viaPoints = [{"viaPointId" : "vidPoint" + str(a), "viaPointName" : list(points_.keys())[a] , "viaX" : str(list(points_.values())[a][0]), "viaY" : str(list(points_.values())[4][1])} for a in range(1,4)]
param["viaPoints"] = viaPoints

이렇게 하여 경유지를 탐색할 수 있는 param들을 다 넣었습니다.


# 좌표계 설정
param["reqCoordType"] = "WGS84GEO"
param["resCoordType"] = "WGS84GEO"
res = requests.post(url = "https://apis.openapi.sk.com/tmap/routes/routeOptimization10?version=1", data = json.dumps(param), headers = headers)
res = res.json()
df = pd.DataFrame([
    [res["features"][li[0]]["properties"]["viaPointName"], 
     res["features"][li[1]]["properties"]["viaPointName"], 
     res["features"][li[0]]["geometry"]["coordinates"], 
     res["features"][li[1]]["geometry"]["coordinates"], 
     LineString(res["features"][li[2]]["geometry"]["coordinates"])] for li in [[0,1,2], [1,3,4], [3,5,6], [5,7,8]]
],
    columns = ["start_name", "end_name", "start_point", "end_point", "geometry"])

기존의 경유지 순서가 서울시청 - 강남구청 - 종로구청 - 서초구청 - 서대문구청에서
서울시청 - 강남구청 - 서초구청 - 종로구청 - 서대문구청으로 바뀌었습니다. 아래 folium 시각화를 통해서도 훨씬 경로가 깔끔해진 것을 볼 수 있습니다.

df["start_name"] = df["start_name"].str.replace(pat = "\[0\]", repl = "")
df["end_name"] = df["end_name"].str.replace(pat = "\[0\]", repl = "")
df
start_name end_name start_point end_point geometry
0 서울특별시청 강남구청 [126.97865155, 37.56682361] [127.04737828, 37.5791623] LINESTRING (126.97865988 37.56701525, 126.9781...
1 강남구청 서초구청 [127.04737828, 37.5791623] [127.0326935, 37.57916203] LINESTRING (127.04783658 37.57859293, 127.0477...
2 서초구청 종로구청 [127.0326935, 37.57916203] [126.97899006, 37.57916107] LINESTRING (127.0326074 37.57913426, 127.03251...
3 종로구청 서대문구청 [126.97899006, 37.57916107] [126.93681613, 37.57916309] LINESTRING (126.97954557 37.57909442, 126.9794...
# 공간 관련 데이터프레임으로 만들어줌
gdf = gpd.GeoDataFrame(df, geometry = "geometry")
gdf
start_name end_name start_point end_point geometry
0 서울특별시청 강남구청 [126.97865155, 37.56682361] [127.04737828, 37.5791623] LINESTRING (126.97865988 37.56701525, 126.9781...
1 강남구청 서초구청 [127.04737828, 37.5791623] [127.0326935, 37.57916203] LINESTRING (127.04783658 37.57859293, 127.0477...
2 서초구청 종로구청 [127.0326935, 37.57916203] [126.97899006, 37.57916107] LINESTRING (127.0326074 37.57913426, 127.03251...
3 종로구청 서대문구청 [126.97899006, 37.57916107] [126.93681613, 37.57916309] LINESTRING (126.97954557 37.57909442, 126.9794...
m = folium.Map(
    location=[gdf["start_point"][0][1],gdf["start_point"][0][0]],
    zoom_start=13
)

for i in range(len(gdf)) :
    folium.Marker(
        [gdf["start_point"][i][1], gdf["start_point"][i][0]], popup= gdf["start_name"][i]
    ).add_to(m)

folium.Marker(
        [gdf["end_point"][i][1], gdf["end_point"][i][0]], popup= gdf["end_name"][i]
).add_to(m)
    
folium.GeoJson(
        gdf.to_json()
).add_to(m)

m


더 공부하고 싶으신 분들은 google map api 도 역시 성능이 좋으니 한번 같이 해보시는 것도 좋을 것 같네요.


이것으로 GIS 관련 API 소개를 마치겠습니다.

code : https://github.com/Chanjun-kim/Chanjun-kim.github.io/blob/main/_ipynb/2021-05-24-GIS_API.ipynb