KML में इस्तेमाल करने के लिए पतों को जियोकोड करना

मनो मार्क्स, Google की जियो टीम
लेखक: दिसंबर 2007
अपडेट किया गया: दिसंबर 2013

मकसद

यह ट्यूटोरियल उन डेवलपर के लिए है जिन्हें स्क्रिप्टिंग भाषाओं के बारे में जानकारी है. साथ ही, वे पतों को जियोकोड करने और उन्हें KML फ़ाइल में शामिल करने के लिए, Google Geocoding API का इस्तेमाल करने का तरीका जानना चाहते हैं. कोड के सैंपल 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 एक एक्सएमएल मार्कअप लैंग्वेज है. इसलिए, KML दस्तावेज़ बनाने के लिए, Python के बिल्ट-इन xml.dom.minidom फ़ंक्शन का इस्तेमाल किया जा सकता है. Python का minidom, DOM को लागू करने का तरीका है. साथ ही, DOM को ज़्यादातर प्रोग्रामिंग भाषाओं में इस्तेमाल किया जा सकता है. इसलिए, इस प्रोसेस को किसी दूसरी प्रोग्रामिंग भाषा में पोर्ट करना आसान होना चाहिए. इसका तरीका यहां बताया गया है:

  1. Python के xml.dom.minidom.Document() का इस्तेमाल करके दस्तावेज़ बनाएं.
  2. createElementNS. का इस्तेमाल करके, रूट <kml> एलिमेंट बनाएं
  3. appendChild का इस्तेमाल करके, इसे दस्तावेज़ में जोड़ें.
  4. createElement का इस्तेमाल करके, Document एलिमेंट बनाएं.
  5. इसे <kml> एलिमेंट में appendChild का इस्तेमाल करके जोड़ें.
  6. हर पते के लिए, createElement का इस्तेमाल करके <Placemark> एलिमेंट बनाएं. इसके बाद, इसे Document एलिमेंट में जोड़ें. इसके बाद, एक <description> एलिमेंट बनाएं, उसे पते की वैल्यू असाइन करें, और उसे <Placemark> एलिमेंट में जोड़ें.
  7. एक <Point> एलिमेंट बनाएँ, उसमें एक चाइल्ड <coordinates> एलिमेंट जोड़ें, और उसे <Placemark> एलिमेंट में जोड़ें.
  8. Maps API Geocoder को पता भेजें. यह JSON या एक्सएमएल में जवाब भेजता है. फ़ाइल को वापस पाने और उसे स्ट्रिंग में पढ़ने के लिए, 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" शहर का जियोकोड मिलेगा. अगर आपको वही नतीजे चाहिए, तो maps.google.com के बजाय maps.google.it पर HTTP जियोकोडिंग के ज़रिए क्वेरी भेजें. इसके लिए, आपको ऊपर दिए गए सैंपल कोड में mapsUrl वैरिएबल में बदलाव करना होगा. क्षेत्र के हिसाब से नतीजों को प्राथमिकता देने के बारे में ज़्यादा जानने के लिए, Geocoding API का दस्तावेज़ देखें.

ध्यान दें: maps.google.* के ऐसे सर्वर को अनुरोध नहीं भेजा जा सकता जो मौजूद नहीं है. इसलिए, पक्का करें कि किसी देश का डोमेन मौजूद हो. इसके बाद ही, अपनी जियोकोडिंग क्वेरी को उस पर रीडायरेक्ट करें. देश के हिसाब से जियोकोड की सुविधा के बारे में जानने के लिए, यह पोस्ट पढ़ें.

नतीजा

ऊपर दिए गए कोड का इस्तेमाल करके, अब Python की मदद से किसी पते को जियोकोड किया जा सकता है. साथ ही, उससे KML <Placemark> बनाया जा सकता है और उसे डिस्क में सेव किया जा सकता है. अगर आपको लगता है कि आपको हर दिन, तय सीमा से ज़्यादा पतों को जियोकोड करने की ज़रूरत है या Google जियोकोडर उन इलाकों को कवर नहीं करता जिनमें आपकी दिलचस्पी है, तो जियोकोडिंग की अन्य वेब सेवाओं का इस्तेमाल करें.

अब आपको अपने पतों को जियोकोड करने का तरीका पता चल गया है. इसलिए, Google Mashup Editor में KML का इस्तेमाल करना और KML बनाने के लिए PHP और MySQL का इस्तेमाल करना लेख पढ़ें. अगर आपको इस ट्यूटोरियल से जुड़ी कोई समस्या आ रही है या इसके बारे में कोई सवाल पूछना है, तो कृपया Stack Overflow फ़ोरम में पोस्ट करें.