Адреса геокодирования для использования в KML

Мано Маркс, команда Google Geo
Автор: декабрь 2007 г.
Обновлено: декабрь 2013 г.

Задача

Это руководство предназначено для разработчиков, знакомых с языками сценариев и желающих узнать, как использовать Google Geocoding API для геокодирования адресов и включения их в файл KML. Хотя примеры кода представлены на Python, их довольно легко адаптировать к большинству других языков программирования.

Геокодирование — это процесс преобразования адреса в набор координат широты/долготы, позволяющий указывать адреса на карте. Вы можете захотеть геокодировать адреса и поместить их непосредственно в файл KML. Это обычное дело, например, когда данные вводятся в форму и вы создаете файлы KML в ответ на запросы. Эти файлы KML могут быть сохранены в базе данных, в файловой системе или возвращены в NetworkLink, который подключается к вашему файлу. Обратите внимание, что при использовании этого метода вы должны соблюдать Условия использования 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. Minidom в Python — это реализация DOM , а DOM поддерживается большинством языков программирования, поэтому этот процесс должно быть легко перенести на другой язык программирования. Вот шаги:

  1. Создайте документ, используя Python xml.dom.minidom.Document() .
  2. Создайте корневой элемент <kml> с помощью createElementNS.
  3. Добавьте его к документу с помощью appendChild .
  4. Создайте элемент Document с помощью createElement .
  5. Добавьте его к элементу <kml> с помощью appendChild .
  6. Для каждого адреса создайте элемент <Placemark> с помощью createElement и добавьте его к элементу Document . Затем создайте элемент <description> , присвойте ему значение адреса и добавьте его к элементу <Placemark> .
  7. Создайте элемент <Point> , добавьте дочерний элемент <coordinates> и присоедините его к элементу <Placemark> .
  8. Отправьте адрес геокодеру Maps API, который отправит ответ в формате JSON или XML. Используйте urllib.urlopen() , чтобы получить файл и прочитать его в строку.
  9. Разберите ответ и извлеките элементы долготы и широты.
  10. Создайте текстовый узел в элементе <coordinates> и назначьте строку долготы/широты в качестве его значения.
  11. Запишите документ KML в текстовый файл.

Пример кода Python

Обратите внимание, что в приведенном ниже примере кода используется фиктивная переменная mapsKey — вам нужно будет заменить этот ключ своим собственным key .

Пример кода для геокодирования с выводом 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, будет геокодирован город «Сиракузы, штат Нью-Йорк», а при вводе того же запроса на maps.google.it (домен Италии) будет найден город «Сиракузы». "на Сицилии. Вы получите те же результаты, отправив этот запрос через геокодирование HTTP на maps.google.it вместо maps.google.com , что можно сделать, изменив переменную mapsUrl в приведенном выше примере кода. Дополнительные сведения о смещении регионов см. в документации API геокодирования.

Примечание. Вы не можете отправить запрос на несуществующий сервер maps.google.*, поэтому убедитесь, что домен страны существует, прежде чем перенаправлять на него запросы геокодирования. Чтобы узнать о поддержке геокодирования по странам, ознакомьтесь с этим постом .

Заключение

Используя приведенный выше код, теперь вы можете геокодировать адрес с помощью Python, создать из него KML <Placemark> и сохранить его на диск. Если вы обнаружите, что вам нужно геокодировать больше адресов в день, чем позволяют ограничения, или что геокодер Google не охватывает интересующие вас регионы, рассмотрите возможность использования дополнительных веб-служб геокодирования.

Теперь, когда вы знаете, как геокодировать свои адреса, ознакомьтесь со статьями Использование KML в Google Mashup Editor и Использование PHP и MySQL для создания KML . Если у вас есть какие-либо проблемы или вопросы по этому руководству, напишите об этом на форуме Stack Overflow .