[엑셀VBA] 다음지도 API를 이용한 지오코딩
본문 바로가기
코딩/엑셀 VBA

[엑셀VBA] 다음지도 API를 이용한 지오코딩

by BizAnalytics 2014. 7. 10.
반응형

자주 하는 일은 아니지만, 가끔 여러 업체들의 주소를 기준으로 경도와 위도를 불러온 뒤 다시 경도와 위도를 기준으로 지도를 만드는 작업을 하곤 한다. 이 작업을 하기 위해서 VBA코드를 작성해 보았다.

(이번 글에서는 우선 지오코딩만 설명하고 지도를 만드는 과정은 추후 설명하도록 하겠다.)

 

"서울시 중구 태평로1가 31"와 같이 한글로 된 주소를 지도에 표시하기 위해서는 경도, 위도 정보로 변환하는 지오코딩 과정이 필요하다. 구글,네이버,다음 모두 지오코딩 서비스를 제공하고 있으나 개인적으로 느끼기에 구주소, 신주소 체계 모두 지원하면서 정확도가 가장 우수한 다음지도 API를 즐겨 사용한다.(정확하게는 다음 로컬 API이나, 편의상 지도API로 부르겠다.)

 

아래 VBA 예제도 다음지도 API를 사용하여 작성하였다. API key가 없으면 http://dna.daum.net/apis/local 로 가서 신청한 뒤 사용하면 된다.

 

세부 내용은 아래 VBA 코드를 보면 알 수 있겠지만 간단히 설명하면 아래와 같은 절차로 이루어진다.

 

 

1.주소를 UTF8 url 형식으로 변환 (URLEncodeUTF8 사용)

 

다음지도 API는 UTF8 형식으로 주소를 전송해야만 제대로 된 결과값을 회신한다. 아쉽게도 VBA 내부적으로 또는 Microsoft에서 추가로 제공하는 라이브러리에는 한글을 UTF8로 변환하는 기능을 제공하지 않는다. 때문에 UTF8로 변환하는 UDF를 같이 예제에 첨부한다.(지금까지는 문제없이 사용 가능했으나, 에러가 발생한다면 나도 잘 모르겠다. 알아서 잘 해결하길 바란다.)

 

2.변환된 주소와 API key를 전송하여 결과값을 XML로 수신

 

3.수신한 XML 노드 중 lng와 lat노드의 값을 출력

 

2.3은 달리 설명할 내용이 없이, 아래 코드를 보고 이해하길 바란다.

 

'----------------------------------------------------------------------------------------------------

 

Sub Geo_coding()

 

'참조 : Microsoft XML, v6.0 사용 체크

 

Dim xml As MSXML2.DOMDocument
Set xml = New MSXML2.DOMDocument
xml.async = False               'False로 해두지 않으면, 반복구문에서 에러가 발생

 

Dim url As String

url = "http://apis.daum.net/local/geo/addr2coord?apikey=API키입력&output=xml&q="
url = url & URLEncodeUTF8("서울시 중구 태평로1가 31")

xml.Load (url)

 

If xml.SelectSingleNode("//result").text <> "0" Then
debug.print xml.SelectSingleNode("//lng").text
debug.print xml.SelectSingleNode("//lat").text

End If

 

End Sub

 

'----------------------------------------여기서부터 UDF---------------------------------------------

 

Private Declare Function WideCharToMultiByte Lib "kernel32" ( _
     ByVal codepage As Long, _
     ByVal dwFlags As Long, _
     ByVal lpWideCharStr As Long, _
     ByVal cchWideChar As Long, _
     ByVal lpMultiByteStr As Long, _
     ByVal cchMultiByte As Long, _
     ByVal lpDefaultChar As Long, _
     ByVal lpUsedDefaultChar As Long _
) As Long
    
Private Declare Function MultiByteToWideChar Lib "kernel32" ( _
     ByVal codepage As Long, _
     ByVal dwFlags As Long, _
     ByVal lpMultiByteStr As Long, _
     ByVal cchMultiByte As Long, _
     ByVal lpWideCharStr As Long, _
     ByVal cchWideChar As Long _
) As Long

Private Const CP_UTF8 As Long = 65001

 

Public Function URLEncodeUTF8(str As String) As String

 

On Error GoTo ErrLbl

     Dim BufSize As Long, MultiArr() As Byte, Buf As String, i As Long
     Dim UniArr() As Byte
     UniArr = str
   
     BufSize = WideCharToMultiByte(CP_UTF8, 0&, VarPtr(UniArr(0)), (UBound(UniArr) + 1) / 2, 0&, 0&, 0&, 0&)
   
     If BufSize > 0 Then
          ReDim MultiArr(BufSize - 1&)
          WideCharToMultiByte CP_UTF8, 0&, VarPtr(UniArr(0)), (UBound(UniArr) + 1) / 2, VarPtr(MultiArr(0)), BufSize, 0&, 0&
     End If
   
     For i = 0 To UBound(MultiArr)
          Buf = Buf & "%" & Hex$(MultiArr(i))
     Next i
   

URLEncodeUTF8 = Buf

ErrLbl:

 

End Function

 

'------------------------------------------UDF 끝----------------------------------------------------

 

tip. Google Fusion Table을 이용하면 속도가 다소 느리기는 하지만 지오코딩과 지도 작성까지 한번에 해결이 가능하다. 따라서 간단히 지도를 작성하길 원한다면 VBA를 활용하기 보다는 Google Fusion Table을 사용하는 것이 편리하다.

반응형