آدرس های کدگذاری جغرافیایی برای استفاده در KML

Mano Marks، تیم Google Geo
تالیف: دسامبر 2007
به روز رسانی: دسامبر 2013

هدف، واقعگرایانه

این آموزش برای توسعه دهندگانی در نظر گرفته شده است که با زبان های اسکریپت نویسی آشنا هستند و می خواهند یاد بگیرند که چگونه از Google Geocoding API برای geocode آدرس ها و ترکیب آنها در یک فایل KML استفاده کنند. در حالی که نمونه‌های کد در پایتون ارائه می‌شوند، می‌توانند به راحتی با اکثر زبان‌های برنامه‌نویسی دیگر سازگار شوند.

ژئوکدینگ فرآیند تبدیل یک آدرس به مجموعه ای از مختصات طول و عرض جغرافیایی است که نشان دادن آدرس ها را بر روی نقشه ممکن می کند. ممکن است بخواهید آدرس ها را ژئوکد کنید و مستقیماً در یک فایل KML قرار دهید. این امر رایج است، به عنوان مثال، زمانی که داده ها در یک فرم وارد می شوند و شما در حال تولید فایل های KML در پاسخ به درخواست ها هستید. این فایل‌های KML می‌توانند در یک پایگاه داده، در یک سیستم فایل ذخیره شوند یا به NetworkLink که به فایل شما متصل می‌شود، بازگردانده شوند. توجه داشته باشید که هنگام استفاده از این تکنیک، باید شرایط سرویس API Geocoding را رعایت کنید، زیرا محدودیت‌هایی در زمان ذخیره نتایج و همچنین تعداد عناصری که می‌توانید هر روز آن‌ها را به صورت جغرافیایی کدگذاری کنید وجود دارد.

این آموزش به شما نشان می‌دهد که چگونه از پایتون برای گرفتن رشته " 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 است، بنابراین ما می توانیم از توابع ساخته شده در xml.dom.minidom پایتون برای ایجاد یک سند KML استفاده کنیم. minidom پایتون یک پیاده سازی DOM است و DOM در اکثر زبان های برنامه نویسی پشتیبانی می شود، بنابراین این فرآیند باید به راحتی به یک زبان برنامه نویسی دیگر منتقل شود. در اینجا مراحل انجام می شود:

  1. سند را با استفاده از xml.dom.minidom.Document() پایتون ایجاد کنید.
  2. عنصر ریشه <kml> را با استفاده از createElementNS.
  3. با استفاده از appendChild آن را به سند اضافه کنید.
  4. با استفاده از createElement یک عنصر Document ایجاد کنید.
  5. آن را با استفاده از appendChild به عنصر <kml> اضافه کنید.
  6. برای هر آدرس، یک عنصر <Placemark> createElement > با استفاده از createElement ایجاد کنید و آن را به عنصر Document اضافه کنید. سپس، یک عنصر <description> ایجاد کنید، مقدار آدرس را به آن اختصاص دهید و آن را به عنصر <Placemark> اضافه کنید.
  7. یک عنصر <Point> ایجاد کنید، یک عنصر <coordinates> را اضافه کنید و آن را به عنصر <Placemark> اضافه کنید.
  8. آدرس را به Maps API Geocoder ارسال کنید، که پاسخ را به JSON یا XML ارسال می کند. از urllib.urlopen() برای بازیابی فایل و خواندن آن در یک رشته استفاده کنید.
  9. پاسخ را تجزیه کنید و عناصر طول و عرض جغرافیایی را استخراج کنید.
  10. یک گره متنی در عنصر <coordinates> ایجاد کنید و رشته طول و عرض جغرافیایی را به عنوان مقدار آن اختصاص دهید.
  11. سند KML را در یک فایل متنی بنویسید.

نمونه کد پایتون

توجه داشته باشید که کد نمونه زیر از یک متغیر ساختگی mapsKey استفاده می‌کند—شما باید این کلید را با کلید خود جایگزین کنید.

کد نمونه برای ژئوکدینگ با خروجی پایتون 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 مراجعه کنید. برای اطمینان از عدم ارسال سریع درخواست‌ها به geocoder، می‌توانید یک تاخیر بین هر درخواست geocode تعیین کنید. می‌توانید هر بار که وضعیت OVER_QUERY_LIMIT را دریافت می‌کنید، این تأخیر را افزایش دهید و از حلقه while استفاده کنید تا مطمئن شوید که یک آدرس را با موفقیت رمزگذاری کرده‌اید، قبل از اینکه به آدرس بعدی تکرار کنید.

تغییر کشور پایه

geocoder طوری برنامه ریزی شده است که نتایج خود را بسته به دامنه مبدأ بایاس کند. به عنوان مثال، با وارد کردن "syracuse" در کادر جستجو در maps.google.com، شهر "Syracuse, NY" را کد جغرافیایی می کند، در حالی که با وارد کردن همان عبارت در maps.google.it (دامنه ایتالیا) شهر "سیراکوزا" را پیدا خواهید کرد. "در سیسیل. با ارسال آن پرس و جو از طریق کدگذاری جغرافیایی HTTP به maps.google.com به جای maps.google.com ، همان نتایج را دریافت خواهید کرد، که می توانید با تغییر متغیر mapsUrl در کد نمونه بالا انجام دهید. برای اطلاعات بیشتر در مورد منطقه بایاس به مستندات API Geocoding مراجعه کنید.

توجه: شما نمی‌توانید درخواستی را به سرور maps.google.* که وجود ندارد ارسال کنید، بنابراین قبل از هدایت درخواست‌های کدگذاری جغرافیایی خود به آن، مطمئن شوید که دامنه کشور وجود دارد. برای پشتیبانی از ژئوکد بر اساس کشور، این پست را بررسی کنید.

نتیجه

با استفاده از کد بالا، اکنون می توانید یک آدرس را با استفاده از پایتون ژئوکد کنید، یک KML <Placemark> از آن ایجاد کنید و آن را در دیسک ذخیره کنید. اگر متوجه شدید که باید آدرس‌های بیشتری را در روز نسبت به محدودیت‌های مجاز تعیین کنید، یا اینکه geocoder Google مناطقی را که به آن‌ها علاقه دارید را پوشش نمی‌دهد، از سرویس‌های وب کدگذاری جغرافیایی اضافی استفاده کنید.

اکنون که می‌دانید چگونه آدرس‌های خود را ژئوکد کنید، مقاله‌های استفاده از KML در Google Mashup Editor و استفاده از PHP و MySQL برای ایجاد KML را بررسی کنید. اگر در مورد این آموزش مشکلی دارید یا سؤالی دارید، لطفاً در انجمن Stack Overflow پست کنید.