عناوين الترميز الجغرافي للاستخدام في KML

Mano Marks، فريق Google Geo
تاريخ النشر: كانون الأول (ديسمبر) 2007
تاريخ التحديث: كانون الأول (ديسمبر) 2013

الغرض

هذا البرنامج التعليمي مخصص لمطوّري البرامج الذين لديهم دراية باللغات البرمجية ويريدون التعرف على كيفية استخدام واجهة برمجة تطبيقات الترميز الجغرافي في Google لترميز العناوين جغرافيًا ودمجها في ملف KML. وبينما يتم تقديم نماذج الشفرات في Python، فإنه يمكن تكييفها بسهولة إلى حد كبير مع معظم لغات البرمجة الأخرى.

الترميز الجغرافي هو عملية تحويل العنوان إلى مجموعة من إحداثيات خطوط الطول/العرض، مما يجعل من الممكن الإشارة إلى العناوين على الخريطة. قد ترغب في ترميز العناوين الجغرافية ووضعها مباشرةً في ملف KML. وهذا أمر شائع، مثلاً، عند إدخال البيانات في نموذج وإنشاء ملفات KML استجابةً للطلبات. يمكن تخزين ملفات KML هذه في قاعدة بيانات، في نظام ملفات، أو إرجاعها إلى NetworkLink الذي يتصل بملفك. لاحظ أنه عند استخدام هذا الأسلوب، يجب عليك ملاحظة بنود الخدمة لواجهة برمجة تطبيقات الترميز الجغرافي، نظرًا لوجود بعض القيود على وقت تخزين النتائج، فضلاً عن عدد العناصر التي يمكنك ترميزها جغرافيًا كل يوم.

يوضح لك هذا البرنامج التعليمي كيفية استخدام 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، لذلك يمكننا استخدام دوال xml.domdom.minidom المدمجة في Python لإنشاء مستند 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. إرسال العنوان إلى Geocoder لواجهة برمجة التطبيقات للخرائط، والذي يرسل استجابةً بتنسيق 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 للحصول على مزيد من المعلومات حول هذه الحدود. ولضمان عدم إرسال طلبات بحث بسرعة كبيرة جدًا إلى أداة الترميز، يمكنك تحديد فترة تأخير بين كل طلب ترميز جغرافي. يمكنك زيادة هذا التأخير في كل مرة تتلقى فيها حالة OVER_QUERY_LIMIT، واستخدام حلقة while لضمان ترميزك لعنوان جغرافيًا بنجاح قبل تكراره إلى العنوان التالي.

تغيير البلد الأساسي

تمت برمجة أداة الترميز الجغرافي لانحياز نتائجها بناءً على النطاق المنشأ. على سبيل المثال، سيؤدي إدخال "syracuse" في مربع البحث على maps.google.com إلى إجراء ترميز جغرافي لمدينة "سيراكي، نيويورك"، بينما يؤدي إدخال طلب البحث نفسه على maps.google.it (نطاق إيطاليا) إلى العثور على مدينة "سيراكيا" في صقلية. ستحصل على النتائج نفسها عن طريق إرسال طلب البحث هذا عبر الترميز الجغرافي لبروتوكول HTTP إلى maps.google.it بدلاً من maps.google.com، وهو ما يمكنك تنفيذه من خلال تعديل المتغير mapsUrl في نموذج الرمز أعلاه. يمكنك الرجوع إلى وثائق واجهة برمجة التطبيقات للترميز الجغرافي للحصول على مزيد من المعلومات حول انحياز المنطقة.

ملاحظة: لا يمكنك إرسال طلب إلى خادم maps.google.* غير موجود، لذا تأكد من وجود نطاق بلد قبل إعادة توجيه طلبات الترميز الجغرافي إليه. للحصول على دعم الترميز الجغرافي حسب البلد، اطلع على هذه المشاركة.

الخاتمة

باستخدام الرمز أعلاه، يمكنك الآن ترميز عنوان جغرافي باستخدام Python، وإنشاء ملف KML <Placemark> منه، وحفظه على القرص. إذا وجدت أنك بحاجة إلى ترميز عناوين أكثر يوميًا مما هو مسموح به في الحدود المسموح بها، أو أن أداة الترميز الجغرافي في Google لا تغطي المناطق التي تهتم بها، يمكنك استخدام خدمات إضافية للترميز الجغرافي على الويب.

والآن بعد أن تعرّفت على كيفية ترميز عناوينك جغرافيًا، يمكنك الاطّلاع على المقالات حول استخدام KML في "محرر المزج من Google" واستخدام PHP وMySQL لإنشاء KML. إذا واجهت أي مشاكل أو استفسارات بشأن هذا البرنامج التعليمي، يُرجى النشر في منتدى Stack Overflow.