כתובות גיאוגרפיות לשימוש ב-KML

Mano Marks, צוות Google Geo
פורסם: דצמבר 2007
עודכן: דצמבר 2013

מטרה

המדריך הזה מיועד למפתחים בעלי מומחיות בכתיבת סקריפטים ואתם רוצים ללמוד איך להשתמש ב-Google Geocoding API כדי להוסיף כתובות לקידוד גיאוגרפי ולשלב אותן בקובץ KML. אמנם דוגמאות הקוד מוצגות ב-Python, אבל ניתן להתאים אותן בקלות יחסית לרוב שפות התכנות האחרות.

קידוד גיאוגרפי הוא תהליך של המרת כתובת לקבוצה של קואורדינטות גובה/אורך, שמאפשר לציין כתובות במפה. מומלץ לבצע קידוד גיאוגרפי של כתובות ולהכניס אותן ישירות לקובץ KML. זה דבר נפוץ, לדוגמה, כשמזינים נתונים בטופס ואתם יוצרים קובצי KML בתגובה לבקשות. את קובצי ה-KML האלה אפשר לאחסן במסד נתונים, במערכת קבצים או לחזור ל-NetworkLink שמתחבר לקובץ שלכם. שימו לב: כשמשתמשים בשיטה הזו, חובה לעיין בתנאים ובהגבלות של ה-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. יוצרים את המסמך באמצעות xml.dom.minidom.Document() של Python.
  2. יצירת רכיב הבסיס <kml> באמצעות createElementNS.
  3. אפשר להוסיף אותם למסמך באמצעות appendChild.
  4. ניתן ליצור רכיב מסמך באמצעות createElement.
  5. הוסיפו אותו לרכיב <kml> באמצעות appendChild.
  6. לכל כתובת, יוצרים אלמנט <Placemark> באמצעות createElement, ומצרפים אותו לרכיב Document. לאחר מכן יוצרים רכיב <description>, מקצים לו את ערך הכתובת ומצרפים אותו לרכיב <Placemark>.
  7. יוצרים אלמנט <Point>, מוסיפים רכיב <coordinates> של צאצא ומצרפים אותו לרכיב <Placemark>.
  8. שולחים את הכתובת לגיאוגרפיה של ה-API של מפות Google, ששולח תגובה ב-JSON או ב-XML. משתמשים בפונקציה urllib.urlopen() כדי לאחזר את הקובץ ולקרוא אותו במחרוזת.
  9. ניתוח התגובה וחילוץ רכיבי קו האורך וקו הרוחב.
  10. יוצרים צומת טקסט ברכיב <coordinates> ומקצים את המחרוזת של קו האורך/קו הרוחב כערך שלו.
  11. כותבים את מסמך ה-KML בקובץ טקסט.

קוד Python לדוגמה

הערה: הקוד לדוגמה שלמטה משתמש במשתנה דמה של מיפוי מקשים – צריך להחליף את המפתח הזה במפתח משלכם.

קוד לדוגמה לקידוד גיאוגרפי באמצעות פלט 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 כדי לוודא שהקוד עבר בהצלחה קידוד גיאוגרפי לפני חזרה לכתובת הבאה.

שינוי מדינת הבסיס

כלי הקידוד הגיאוגרפי מוטה את תוצאותיו בהתאם לדומיין המקורי. לדוגמה, אם מזינים "syracuse" בתיבת החיפוש ב-maps.google.com, העיר תבוצע קידוד גיאוגרפי של העיר "Siracuse, NY", ובאותה שאילתה ב-maps.google.it (הדומיין של איטליה) תמצא את העיר "Siracusa" בסיציליה. כדי לקבל את אותן התוצאות על ידי שליחת השאילתה דרך קידוד גיאוגרפי של HTTP אל maps.google.it במקום אל maps.google.com, אפשר לשנות את המשתנה mapsUrl בקוד לדוגמה שלמעלה. למידע נוסף על הטיית אזור, עיינו במסמכי התיעוד של Geocoding API.

הערה: לא ניתן לשלוח בקשה לשרת maps.google.* לא קיים, לכן חשוב לוודא שיש דומיין של מדינה לפני ההפניה אליו. לקבלת תמיכה גיאוגרפית לפי מדינה, כדאי לעיין בפוסט הזה.

סיכום

באמצעות הקוד שלמעלה, ניתן עכשיו ליצור קידוד גיאוגרפי של כתובת באמצעות Python, ליצור ממנה קובץ KML <Placemark> ולשמור אותו בדיסק. אם אתם צריכים להוסיף יותר קוד גיאוגרפי לכתובות רבות יותר מהמותר בימים, או שהמקודד של Google לא כולל את האזורים שמעניינים אתכם, כדאי לכם להשתמש בשירותי אינטרנט נוספים כדי לבצע קידוד גיאוגרפי.

עכשיו שאתם יודעים איך לקודד את הכתובות שלכם לפי קידוד, קראו את המאמרים על שימוש ב-KML ב-Google Mashup Editor ושימוש ב-PHP וב-MySQL כדי ליצור KML. אם תיתקלו בבעיות או שיש לכם שאלות לגבי המדריך, ניתן לפרסם פוסט בפורום Stack Overflow.