मार्च 2008
मकसद
इस ट्यूटोरियल में, Python का इस्तेमाल करके कॉमा सेपरेटेड वैल्यू (CSV) डेटा से KML बनाने के तरीके के बारे में बुनियादी जानकारी दी गई है. CSV डेटा, आज के समय में सबसे ज़्यादा इस्तेमाल होने वाले फ़ाइल फ़ॉर्मैट में से एक है. ज़्यादातर स्प्रेडशीट और डेटाबेस, CSV फ़ाइलों को पढ़ और लिख सकते हैं. इसके सामान्य फ़ॉर्मैट में, टेक्स्ट एडिटर में बदलाव किया जा सकता है. Python जैसी कई प्रोग्रामिंग भाषाओं में, CSV फ़ाइलों को पढ़ने और लिखने के लिए खास लाइब्रेरी होती हैं. इसलिए, यह बड़ी मात्रा में डेटा का आदान-प्रदान करने का एक बेहतरीन तरीका है.
इस ट्यूटोरियल में कोड के सैंपल Python में दिए गए हैं. हालांकि, इन्हें ज़्यादातर अन्य प्रोग्रामिंग भाषाओं के हिसाब से भी इस्तेमाल किया जा सकता है. इस ट्यूटोरियल में, KML में इस्तेमाल करने के लिए पतों को जियोकोड करना लेख में दिए गए कोड का इस्तेमाल किया गया है. इससे किसी पते को अक्षांश/देशांतर निर्देशांकों में बदला जा सकता है. यह KML 2.2 के नए <ExtendedData>
एलिमेंट का इस्तेमाल करता है. साथ ही, कस्टम डेटा जोड़ने में बताए गए बलून टेंप्लेटिंग का फ़ायदा लेता है. इसलिए, अभी Google Maps या KML का इस्तेमाल करने वाले अन्य ऐप्लिकेशन में, इस KML का इस्तेमाल नहीं किया जा सकता. हालांकि, कोड में बदलाव करके, Maps के साथ काम करने वाली KML बनाई जा सकती है.
सैंपल डेटा
इस ट्यूटोरियल के लिए, google-addresses.csv फ़ाइल को सैंपल CSV फ़ाइल के तौर पर इस्तेमाल करें. इस फ़ाइल में, अमेरिका में मौजूद Google के अलग-अलग ऑफ़िस के पते, फ़ोन नंबर, और फ़ैक्स नंबर दिए गए हैं. फ़ाइल का टेक्स्ट यहां दिया गया है:
Office,Address1,Address2,Address3,City,State,Zip,Phone,Fax Headquarters,1600 Amphitheatre Parkway,,,Mountain View,CA,94043,650-253-0000,650-253-0001 New York Sales & Engineering Office,76 Ninth Avenue,,,New York,NY,10011,212-565-0000,212-565-0001 Ann Arbor Sales Office,201 South Division Street,,,Ann Arbor,MI,48104,734-332-6500,734-332-6501 Atlanta Sales & Engineering Office,10 10th Street NE,,,Atlanta,GA,30309,404-487-9000,404-487-9001 Boulder Sales & Engineering Office,2590 Pearl St.,,,Boulder,CO,80302,303-245-0086,303-535-5592 Cambridge Sales & Engineering Office,5 Cambridge Center,,,Cambridge,MA,02142,617-682-3635,617-249-0199 Chicago Sales & Engineering Office,20 West Kinzie St.,,,Chicago,IL,60610,312-840-4100,312-840-4101 Coppell Sales Office,701 Canyon Drive,,,Coppell,TX,75019,214-451-4000,214-451-4001 Detroit Sales Office,114 Willits Street,,,Birmingham,MI,48009,248-351-6220,248-351-6227 Irvine Sales & Engineering Office,19540 Jamboree Road,,,Irvine,CA,92612,949-794-1600,949-794-1601 Pittsburgh Engineering Office,4720 Forbes Avenue,,,Pittsburgh,PA,15213,, Santa Monica Sales & Engineering Office,604 Arizona Avenue,,,Santa Monica,CA,90401,310-460-4000,310-309-6840 Seattle Engineering Office,720 4th Avenue,,,Kirkland,WA,98033,425-739-5600,425-739-5601 Seattle Sales Office,501 N. 34th Street,,,Seattle,WA,98103,206-876-1500,206-876-1501 Washington D.C. Public Policy Office,1001 Pennsylvania Avenue NW,,,Washington,DC,20004,202-742-6520,
ध्यान दें कि हर लाइन में टेक्स्ट स्ट्रिंग की एक सीरीज़ होती है, जिसे कॉमा लगाकर अलग किया जाता है.
हर कॉमा, एक फ़ील्ड को अलग करता है. हर लाइन में कॉमा की संख्या एक जैसी होती है.
पहली लाइन में फ़ील्ड के नाम क्रम से दिए गए हैं. उदाहरण के लिए, हर लाइन में टेक्स्ट का पहला ब्लॉक "Office" फ़ील्ड है, दूसरा "Address1" वगैरह. Python इसे dicts
के कलेक्शन में बदल सकता है. इसे DictReader
कहा जाता है. इससे आपको हर लाइन में जाने की सुविधा मिलती है. इस कोड सैंपल के लिए, आपको अपने डेटा के स्ट्रक्चर के बारे में पहले से पता होना चाहिए. हालांकि, फ़ील्ड स्ट्रक्चर को डाइनैमिक तरीके से पास करने के लिए, कुछ बुनियादी हैंडलर जोड़े जा सकते हैं.
CSV फ़ाइल को पार्स करना
Python का xml.dom.minidom
मॉड्यूल, एक्सएमएल दस्तावेज़ बनाने के लिए बेहतरीन टूल उपलब्ध कराता है. साथ ही, KML एक एक्सएमएल फ़ाइल है. इसलिए, इस ट्यूटोरियल में इसका इस्तेमाल काफ़ी ज़्यादा किया जाएगा. createElement
या createElementNS
की मदद से कोई एलिमेंट बनाया जाता है. इसके बाद, appendChild
की मदद से उसे किसी दूसरे एलिमेंट में जोड़ा जाता है.
CSV फ़ाइल को पार्स करने और KML फ़ाइल बनाने का तरीका यहां दिया गया है.
- geocoding_for_kml.py को अपने मॉड्यूल में इंपोर्ट करें.
- CSV फ़ाइलों के लिए
DictReader
बनाएं.DictReader
,dicts
का कलेक्शन होता है. हर लाइन के लिए एकdicts
होता है. - Python के
xml.dom.minidom.Document()
का इस्तेमाल करके दस्तावेज़ बनाएं. createElementNS.
का इस्तेमाल करके, रूट<kml>
एलिमेंट बनाएं- इसे दस्तावेज़
में जोड़ें.
createElement
का इस्तेमाल करके,<Document>
तत्व बनाएं.- इसे
appendChild
का इस्तेमाल करके,<kml>
एलिमेंट से जोड़ें. - हर लाइन के लिए, एक
<Placemark>
एलिमेंट बनाएं और उसे<Document>
एलिमेंट में जोड़ें. - हर लाइन के हर कॉलम के लिए, एक
<ExtendedData>
एलिमेंट बनाएं और उसे चरण 8 में बनाए गए<Placemark>
एलिमेंट में जोड़ें. <Data>
एलिमेंट बनाएं और उसे<ExtendedData>
एलिमेंट में जोड़ें.<Data>
एलिमेंट को नाम एट्रिब्यूट दें. साथ ही,setAttribute
का इस्तेमाल करके, इसे कॉलम के नाम की वैल्यू असाइन करें.<value>
एलिमेंट बनाएं और उसे<Data>
एलिमेंट में जोड़ें. एक टेक्स्ट नोड बनाएं औरcreateTextNode
का इस्तेमाल करके, उसे कॉलम की वैल्यू असाइन करें. टेक्स्ट नोड को<value>
एलिमेंट में जोड़ें.<Point>
एलिमेंट बनाएं और उसे<Placemark>
एलिमेंट में जोड़ें.<coordinates>
एलिमेंट बनाएं और उसे<Point>
एलिमेंट में जोड़ें.- लाइन से पता निकालें, ताकि यह इस फ़ॉर्मैट में एक स्ट्रिंग बन जाए: पता1,पता2,शहर,राज्य,पिन कोड. इसलिए, पहली लाइन
1600 Amphitheater Parkway,,Mountain View,CA,94043
होगी. अगर एक साथ कई कॉमा हैं, तो भी कोई समस्या नहीं है. ध्यान दें कि ऐसा करने के लिए, आपको CSV फ़ाइल के स्ट्रक्चर और यह जानकारी होनी चाहिए कि कौनसे कॉलम में पता मौजूद है. - KML में इस्तेमाल करने के लिए पतों को जियोकोड करना में बताए गए geocoding_for_kml.py कोड का इस्तेमाल करके, पते को जियोकोड करें. इससे एक स्ट्रिंग मिलती है. यह जगह का देशांतर और अक्षांश होता है.
- एक टेक्स्ट नोड बनाएं और उसे चरण 14 में दिए गए कोऑर्डिनेट की वैल्यू असाइन करें. इसके बाद, उसे
<coordinates>
एलिमेंट में जोड़ें. - KML दस्तावेज़ को किसी फ़ाइल में लिखें.
- अगर स्क्रिप्ट में कॉलम के नामों की सूची को आर्ग्युमेंट के तौर पर पास किया जाता है, तो स्क्रिप्ट उन एलिमेंट को उसी क्रम में जोड़ेगी. अगर हमें एलिमेंट के क्रम से कोई फ़र्क़ नहीं पड़ता, तो हम
dict.keys()
का इस्तेमाल करकेlist
बना सकते हैं. हालांकि,dict.keys()
से दस्तावेज़ में मौजूद ओरिजनल क्रम को बनाए नहीं रखा जाता. इस आर्ग्युमेंट का इस्तेमाल करने के लिए, फ़ील्ड के नामों की सूची को कॉमा लगाकर अलग की गई सूची के तौर पर पास करें. जैसे:python csvtokml.py Office,Address1,Address2,Address3,City,State,Zip,Phone,Fax
Python कोड का सैंपल
Python 2.2 का इस्तेमाल करके, CSV फ़ाइल से KML फ़ाइल बनाने के लिए सैंपल कोड यहां दिया गया है. इसे यहां से भी डाउनलोड किया जा सकता है.
import geocoding_for_kml
import csv
import xml.dom.minidom
import sys
def extractAddress(row):
# This extracts an address from a row and returns it as a string. This requires knowing
# ahead of time what the columns are that hold the address information.
return '%s,%s,%s,%s,%s' % (row['Address1'], row['Address2'], row['City'], row['State'], row['Zip'])
def createPlacemark(kmlDoc, row, order):
# This creates aelement for a row of data.
# A row is a dict.
placemarkElement = kmlDoc.createElement('Placemark')
extElement = kmlDoc.createElement('ExtendedData')
placemarkElement.appendChild(extElement)
# Loop through the columns and create a element for every field that has a value.
for key in order:
if row[key]:
dataElement = kmlDoc.createElement('Data')
dataElement.setAttribute('name', key)
valueElement = kmlDoc.createElement('value')
dataElement.appendChild(valueElement)
valueText = kmlDoc.createTextNode(row[key])
valueElement.appendChild(valueText)
extElement.appendChild(dataElement)
pointElement = kmlDoc.createElement('Point')
placemarkElement.appendChild(pointElement)
coordinates = geocoding_for_kml.geocode(extractAddress(row))
coorElement = kmlDoc.createElement('coordinates')
coorElement.appendChild(kmlDoc.createTextNode(coordinates))
pointElement.appendChild(coorElement)
return placemarkElement
def createKML(csvReader, fileName, order):
# This constructs the KML document from the CSV file.
kmlDoc = xml.dom.minidom.Document()
kmlElement = kmlDoc.createElementNS('http://earth.google.com/kml/2.2', 'kml')
kmlElement.setAttribute('xmlns','http://earth.google.com/kml/2.2')
kmlElement = kmlDoc.appendChild(kmlElement)
documentElement = kmlDoc.createElement('Document')
documentElement = kmlElement.appendChild(documentElement)
# Skip the header line.
csvReader.next()
for row in csvReader:
placemarkElement = createPlacemark(kmlDoc, row, order)
documentElement.appendChild(placemarkElement)
kmlFile = open(fileName, 'w')
kmlFile.write(kmlDoc.toprettyxml(' ', newl = '\n', encoding = 'utf-8'))
def main():
# This reader opens up 'google-addresses.csv', which should be replaced with your own.
# It creates a KML file called 'google.kml'.
# If an argument was passed to the script, it splits the argument on a comma
# and uses the resulting list to specify an order for when columns get added.
# Otherwise, it defaults to the order used in the sample.
if len(sys.argv) >1: order = sys.argv[1].split(',')
else: order = ['Office','Address1','Address2','Address3','City','State','Zip','Phone','Fax']
csvreader = csv.DictReader(open('google-addresses.csv'),order)
kml = createKML(csvreader, 'google-addresses.kml', order)
if __name__ == '__main__':
main()
सैंपल KML बनाया गया
इस स्क्रिप्ट से बनाई गई KML का सैंपल यहां दिया गया है.
ध्यान दें कि कुछ<value>
एलिमेंट में सिर्फ़ खाली जगह है. ऐसा इसलिए है, क्योंकि फ़ील्ड में कोई डेटा नहीं था. पूरे सैंपल को यहां से भी डाउनलोड किया जा सकता है.
<?xml version="1.0" encoding="utf-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Document>
<Placemark>
<ExtendedData>
<Data name="Office">
<value>
Headquarters
</value>
</Data>
<Data name="Address1">
<value>
1600 Amphitheater Parkway
</value>
</Data>
<Data name="City">
<value>
Mountain View
</value>
</Data>
<Data name="State">
<value>
CA
</value>
</Data>
<Data name="Zip">
<value>
94043
</value>
</Data>
<Data name="Phone">
<value>
650-253-0000
</value>
</Data>
<Data name="Fax">
<value>
650-253-0001
</value>
</Data>
</ExtendedData>
<Point>
<coordinates>
-122.081783,37.423111
</coordinates>
</Point>
</Placemark>
...
स्क्रीनशॉट
यहां एक स्क्रीनशॉट दिया गया है. इसमें दिखाया गया है कि Google Earth में KML फ़ाइल कैसी दिखती है.
हर <Placemark>
एलिमेंट में कोई <BalloonStyle><text>
और कोई <description>
एलिमेंट नहीं होता. इसलिए, बलून डिफ़ॉल्ट रूप से टेबल स्टाइल में होता है. यह <Data>
एलिमेंट का इस्तेमाल करता है.

जियोकोडिंग से जुड़ी बातें
इस बारे में "KML में इस्तेमाल करने के लिए पतों को जियोकोड करना" लेख में बताया गया है. हालांकि, हम इसे फिर से दोहरा रहे हैं. आपके जियोकोडिंग अनुरोधों पर, जियोकोडर के ज़्यादा से ज़्यादा क्वेरी रेट और आपके आईपी के आधार पर हर दिन 15,000 क्वेरी की सीमा लागू होगी. इसके अलावा, अगर जियोकोडर से बहुत तेज़ी से क्वेरी की जाती है, तो वह 620
वाला स्टेटस कोड दिखाएगा. (स्टेटस कोड की पूरी सूची यहां उपलब्ध है.)
यह पक्का करने के लिए कि जियोकोडर को बहुत तेज़ी से क्वेरी न भेजी जाएं, हर जियोकोड अनुरोध के बीच देरी तय की जा सकती है. हर बार 620
स्टेटस मिलने पर, इस देरी को बढ़ाया जा सकता है. साथ ही, while
लूप का इस्तेमाल करके यह पक्का किया जा सकता है कि आपने अगले पते पर जाने से पहले, किसी पते को जियोकोड कर लिया है. इसका मतलब है कि अगर आपकी CSV फ़ाइल बहुत बड़ी है, तो आपको जियोकोडिंग कोड में बदलाव करना पड़ सकता है. इसके अलावा, आपको यह भी ट्रैक करना होगा कि प्लेस मार्क कितनी तेज़ी से बनाए जा रहे हैं. अगर प्लेस मार्क बहुत तेज़ी से बनाए जा रहे हैं, तो आपको इसकी स्पीड कम करनी होगी.
नतीजा
अब Python का इस्तेमाल करके, CSV फ़ाइल से KML फ़ाइल बनाई जा सकती है. दिए गए कोड का इस्तेमाल करके, KML फ़ाइल सिर्फ़ Google Earth में काम करेगी. <ExtendedData>
की जगह <description>
का इस्तेमाल करके, इसे Maps और Earth, दोनों में काम करने के लिए बदला जा सकता है.
इस कोड सैंपल को, XML के साथ काम करने वाली किसी भी दूसरी प्रोग्रामिंग भाषा में आसानी से बदला जा सकता है.
अब आपने सभी CSV फ़ाइलों को KML में बदल लिया है. इसलिए, आपको KML के बारे में अन्य लेख पढ़ने चाहिए. जैसे, KML बनाने के लिए PHP और MySQL का इस्तेमाल करना और ExtendedData के बारे में Google डेवलपर गाइड का लेख, कस्टम डेटा जोड़ना.