KML에 사용할 지오코딩 주소

Mano Marks, Google Geo팀
작성자: 2007년 12월
업데이트: 2013년 12월

목표

이 튜토리얼은 스크립트 언어에 익숙하며 Google Geocoding API를 사용하여 주소를 지오코딩하고 이를 KML 파일에 통합하는 방법을 알아보려는 개발자를 대상으로 합니다. 코드 샘플은 Python으로 제공되지만 대부분의 다른 프로그래밍 언어에도 상당히 쉽게 적용할 수 있습니다.

지오코딩은 주소를 위도/경도 좌표 집합으로 변환하는 과정이며, 지도에 주소를 표시할 수 있게 해줍니다. 주소를 지오코딩해서 KML 파일에 직접 넣는 것이 좋습니다. 예를 들어 데이터를 양식에 입력하고 요청에 대한 응답으로 KML 파일을 생성하는 경우가 일반적입니다. 이러한 KML 파일은 데이터베이스, 파일 시스템에 저장되거나 파일에 연결되는 네트워크 링크로 반환될 수 있습니다. 이 기법을 사용할 때는 결과를 저장할 수 있는 시간뿐만 아니라 매일 지오코딩할 수 있는 요소의 수에 제한이 있으므로 Geocoding API의 서비스 약관을 준수해야 합니다.

이 튜토리얼에서는 Python을 사용하여 '1600 Amphitheatre Pkwy, Mountain View, CA 94043' 문자열을 다음과 같이 변환하는 방법을 보여줍니다.

<?xml version='1.0' encoding='UTF-8'?> 
<kml xmlns='http://earth.google.com/kml/2.2'>
<Document>
<Placemark>
<description>1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA</description>
<Point>
<coordinates>-122.081783,37.423111,0</coordinates>
</Point>
</Placemark>
</Document>
</kml>

KML 문서 만들기

KML은 XML 마크업 언어이므로 Python의 기본 제공 xml.dom.minidom 함수를 사용하여 KML 문서를 만들 수 있습니다. Python의 축소 기능은 DOM 구현이며 DOM은 대부분의 프로그래밍 언어에서 지원되므로 이 프로세스는 다른 프로그래밍 언어로 쉽게 이식할 수 있어야 합니다. 다음 단계를 따르세요.

  1. Python의 xml.dom.minidom.Document()를 사용하여 문서를 만듭니다.
  2. createElementNS.를 사용하여 루트 <kml> 요소를 만듭니다.
  3. appendChild를 사용하여 문서에 추가합니다.
  4. createElement를 사용하여 문서 요소를 만듭니다.
  5. appendChild를 사용하여 <kml> 요소에 추가합니다.
  6. 각 주소에 대해 createElement를 사용하여 <Placemark> 요소를 만들어 Document 요소에 추가합니다. 그런 다음 <description> 요소를 만들어 주소 값을 할당하고 <Placemark> 요소에 추가합니다.
  7. <Point> 요소를 만들고 하위 <coordinates> 요소를 추가하여 <Placemark> 요소에 추가합니다.
  8. Maps API 지오코더에 주소를 보내면 JSON 또는 XML로 응답이 전송됩니다. urllib.urlopen()를 사용하여 파일을 검색하고 문자열로 읽습니다.
  9. 응답을 파싱하고 경도 및 위도 요소를 추출합니다.
  10. <coordinates> 요소에 텍스트 노드를 만들고 경도/위도 문자열을 값으로 할당합니다.
  11. KML 파일을 텍스트 파일에 작성합니다.

샘플 Python 코드

아래의 샘플 코드는 더미 mapsKey 변수를 사용합니다. 이 키를 자체 키로 바꿔야 합니다.

다음은 Python 2.7 및 JSON 출력으로 지오코딩하는 샘플 코드입니다.

import urllib
import xml.dom.minidom
import json 

def geocode(address, sensor=False):
 # This function queries the Google Maps API geocoder with an
 # address. It gets back a csv file, which it then parses and
 # returns a string with the longitude and latitude of the address.

 # This isn't an actual maps key, you'll have to get one yourself.
 # Sign up for one here: https://code.google.com/apis/console/
  mapsKey = 'abcdefgh'
  mapsUrl = 'https://maps.googleapis.com/maps/api/geocode/json?address='
     
 # This joins the parts of the URL together into one string.
  url = ''.join([mapsUrl,urllib.quote(address),'&sensor=',str(sensor).lower()])
#'&key=',mapsKey])
  jsonOutput = str(urllib.urlopen(url).read ()) # get the response 
  # fix the output so that the json.loads function will handle it correctly
  jsonOutput=jsonOutput.replace ("\\n", "")
  result = json.loads(jsonOutput) # converts jsonOutput into a dictionary 
  # check status is ok i.e. we have results (don't want to get exceptions)
  if result['status'] != "OK": 
    return ""
  coordinates=result['results'][0]['geometry']['location'] # extract the geometry 
  return str(coordinates['lat'])+','+str(coordinates['lng'])

def createKML(address, fileName):
 # This function creates an XML document and adds the necessary
 # KML elements.

  kmlDoc = xml.dom.minidom.Document()
  
  kmlElement = kmlDoc.createElementNS('http://earth.google.com/kml/2.2','kml')

  kmlElement = kmlDoc.appendChild(kmlElement)

  documentElement = kmlDoc.createElement('Document')
  documentElement = kmlElement.appendChild(documentElement)

  placemarkElement = kmlDoc.createElement('Placemark')
  
  descriptionElement = kmlDoc.createElement('description')
  descriptionText = kmlDoc.createTextNode(address)
  descriptionElement.appendChild(descriptionText)
  placemarkElement.appendChild(descriptionElement)
  pointElement = kmlDoc.createElement('Point')
  placemarkElement.appendChild(pointElement)
  coorElement = kmlDoc.createElement('coordinates')

  # This geocodes the address and adds it to a  element.
  coordinates = geocode(address)
  coorElement.appendChild(kmlDoc.createTextNode(coordinates))
  pointElement.appendChild(coorElement)

  documentElement.appendChild(placemarkElement)

  # This writes the KML Document to a file.
  kmlFile = open(fileName, 'w')
  kmlFile.write(kmlDoc.toprettyxml(' '))  
  kmlFile.close()

if __name__ == '__main__':
  createKML('1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA', 'google.kml')

기타 고려사항

지오코드 요청 타이밍

지오코딩 요청에는 지오코더의 최대 쿼리 비율 일일 한도가 적용됩니다. 이러한 제한에 대한 자세한 내용은 Google Geocoding API 문서를 참고하세요. 쿼리를 지오코더로 너무 빨리 전송하지 않도록 하려면 각 지오코드 요청 간의 지연 시간을 지정하면 됩니다. OVER_QUERY_LIMIT 상태를 수신할 때마다 이 지연을 늘리고 while 루프를 사용하여 다음 주소로 반복하기 전에 주소를 성공적으로 지오코딩했는지 확인할 수 있습니다.

기본 국가 변경

지오코더는 원래 도메인에 따라 결과를 편성하도록 프로그래밍되어 있습니다. 예를 들어 maps.google.com의 검색창에 'syracuse'를 입력하면 'Syracuse, NY' 도시를 지오코딩하고 maps.google.it(이탈리아의 도메인)에서 동일한 쿼리를 입력하면 시칠리아의 'Siracusa' 도시를 찾습니다. HTTP 지오코딩을 통해 maps.google.com 대신 maps.google.it에 쿼리를 전송하면 동일한 결과를 얻게 됩니다. 위 샘플 코드에서 mapsUrl 변수를 수정하면 됩니다. 지역 상세 검색에 대한 자세한 내용은 Geocoding API 문서를 참고하세요.

참고: 존재하지 않는 maps.google.* 서버에는 요청을 보낼 수 없으므로 지오코딩 쿼리를 리디렉션하기 전에 국가 도메인이 존재하는지 확인하세요. 국가별 지오코딩 지원은 이 게시물을 참고하세요.

마무리

이제 위 코드를 사용하여 Python을 사용하여 주소를 지오코딩하고 이 주소에서 KML <Placemark>를 만든 다음 디스크에 저장할 수 있습니다. 하루에 허용되는 주소 수보다 더 많은 주소를 지오코딩해야 하거나 Google 지오코더에 관심 있는 지역이 없는 경우 추가 지오코딩 웹 서비스를 사용해 보세요.

주소를 지오코딩하는 방법을 알아보았으니 이제 Google 매쉬업 에디터에서 KML 사용하기PHP 및 MySQL을 사용하여 KML 만들기에 관한 도움말을 확인하세요. 이 튜토리얼에 문제가 있거나 궁금한 점이 있으면 Stack Overflow 포럼에 게시해 주세요.