CSV फ़ाइलों को KML में बदलना

मेनो मार्क्स, Google Geo API टीम
मार्च 2008

उद्देश्य

यह ट्यूटोरियल, Python का इस्तेमाल करके कॉमा सेपरेटेड वैल्यू (CSV) डेटा से KML बनाने की बुनियादी बातों को बताता है. CSV डेटा आज इस्तेमाल किए जाने वाले सबसे ज़्यादा फ़ाइल फ़ॉर्मैट में से एक है. ज़्यादातर स्प्रेडशीट और डेटाबेस, CSV फ़ाइलों को पढ़ और लिख सकते हैं. इसका आसान फ़ॉर्मैट टेक्स्ट एडिटर में बदला जा सकता है. Python जैसी कई प्रोग्रामिंग भाषाओं में CSV लाइब्रेरी को पढ़ने और लिखने के लिए खास लाइब्रेरी होती हैं. इस वजह से, यह बड़ी संख्या में डेटा के लेन-देन के लिए बेहतरीन माध्यम है.

हालांकि, इस ट्यूटोरियल के कोड सैंपल Python में हैं, लेकिन इन्हें प्रोग्रामिंग की ज़्यादातर अन्य भाषाओं के हिसाब से बनाया जा सकता है. इस ट्यूटोरियल में, किसी पते को देशांतर/अक्षांश के निर्देशांक में बदलने के लिए, KML में पते के लिए KML में पते का इस्तेमाल किया जाता है. यह KML 2.2 के नए <ExtendedData> एलिमेंट का भी इस्तेमाल करता है. साथ ही, यह कस्टम डेटा जोड़ना में बताए गए गुब्बारा लेआउट का इस्तेमाल करता है. फ़िलहाल, जो KML बनाया जा रहा है वह फ़िलहाल Google Maps या KML इस्तेमाल करने वाले दूसरे ऐप्लिकेशन में काम नहीं करता. हालांकि, Maps के साथ काम करने वाले KML बनाने के लिए, कोड में बदलाव किया जा सकता है.

सैंपल डेटा

इस ट्यूटोरियल के लिए, CSV फ़ाइल के नमूने के तौर पर google-addresses.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 फ़ाइल बनाने के चरण हैं.

  1. अपने मॉड्यूल में जियोकोडिंग_for_KML.py इंपोर्ट करें.
  2. CSV फ़ाइलों के लिए DictReader बनाएं. DictReader, dicts का संग्रह है और हर पंक्ति में एक होता है.
  3. Python की xml.dom.minidom.Document() का इस्तेमाल करके, दस्तावेज़ बनाएं.
  4. createElementNS. का इस्तेमाल करके रूट <kml> एलिमेंट बनाएं
  5. इसे दस्तावेज़ में जोड़ें.
  6. createElement का इस्तेमाल करके <Document> एलिमेंट बनाएं.
  7. इसे appendChild का इस्तेमाल करके <kml> एलिमेंट में जोड़ें.
  8. हर लाइन के लिए, <Placemark> एलिमेंट बनाएं और उसे <Document> एलिमेंट में जोड़ें.
  9. हर पंक्ति के हर कॉलम के लिए एक <ExtendedData> एलिमेंट बनाएं और उसे चरण 8 में बनाए गए <Placemark> एलिमेंट में जोड़ें.
  10. <Data> एलिमेंट बनाएं और उसे <ExtendedData> एलिमेंट में जोड़ें. <Data> एलिमेंट को नाम का एट्रिब्यूट दें और setAttribute का इस्तेमाल करके, कॉलम के नाम की वैल्यू असाइन करें.
  11. <value> एलिमेंट बनाएं और उसे <Data> एलिमेंट में जोड़ें. एक टेक्स्ट नोड बनाएं, और createTextNode का इस्तेमाल करके कॉलम की वैल्यू असाइन करें. टेक्स्ट नोड में <value> एलिमेंट जोड़ें.
  12. <Point> एलिमेंट बनाएं और उसे <Placemark> एलिमेंट में जोड़ें. <coordinates> एलिमेंट बनाएं और उसे <Point> एलिमेंट में जोड़ें.
  13. पंक्ति से पता निकालें, ताकि इस फ़ॉर्मैट में एक स्ट्रिंग हो: पते1, पता2, शहर, राज्य, पिन. इसलिए, पहली पंक्ति 1600 Amphitheater Parkway,,Mountain View,CA,94043 होगी. एक-दूसरे के बगल में कॉमा होने पर कोई दिक्कत नहीं है. ध्यान दें, ऐसा करने के लिए CSV फ़ाइल के स्ट्रक्चर और पते वाले कॉलम की जानकारी होना ज़रूरी है.
  14. जियोकोडिंग_for_KML.py कोड का इस्तेमाल करके, पते को जीकोड करें. KML में इस्तेमाल करने के लिए पतों की जानकारी. यह एक स्ट्रिंग दिखाता है, जो जगह का देशांतर और अक्षांश होता है.
  15. एक टेक्स्ट नोड बनाएं और उसे चरण 14 में निर्देशांकों का मान असाइन करें, फिर उसे <coordinates> एलिमेंट में जोड़ें.
  16. KML फ़ाइल को किसी फ़ाइल में लिखें.
  17. अगर कॉलम के नामों की सूची को स्क्रिप्ट में आर्ग्युमेंट के तौर पर पास किया जाता है, तो स्क्रिप्ट के क्रम में एलिमेंट जुड़ जाएंगे. अगर हम एलिमेंट के क्रम पर ध्यान नहीं देते, तो हम 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 a  element 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 का स्क्रीनशॉट, जिसे इस स्क्रिप्ट ने बनाया है

जियोकोडिंग के लिए विचार

इस बारे में, "KML में इस्तेमाल करने के लिए जियोकोडिंग पते" बताया गया था, लेकिन इसमें बार-बार एक ही बात बताई गई है. आपके जियोकोडिंग अनुरोध जियोकोडर की अधिकतम क्वेरी दर और आपके IP के आधार पर प्रति दिन 15,000 क्वेरी के अधीन होंगे. साथ ही, अगर आप क्वेरी करने में लगने वाले समय की तुलना में ज़्यादा तेज़ी से क्वेरी करते हैं, तो 620 का स्टेटस कोड फिर से जियोकोडर के पास आ जाएगा. (स्थिति कोड की पूरी सूची यहां उपलब्ध है.) यह तय करने के लिए कि आप भौगोलिक स्थान पर मौजूद क्वेरी को तेज़ी से न भेजें, आप हर भौगोलिक अनुरोध के बीच देरी की जानकारी दे सकते हैं. जब भी आपको 620 का स्टेटस मिले, तो इस देरी को बढ़ाया जा सकता है. साथ ही, while लूप का इस्तेमाल करके, यह पक्का किया जा सकता है कि आपने अगले पते पर जाने से पहले किसी पते को जियोकोड किया है. इसका मतलब है कि अगर आपकी CSV फ़ाइल बहुत बड़ी है, तो आपको या तो जियोकोडिंग कोड में बदलाव करना होगा या ट्रैक करना होगा कि आप कितनी तेज़ी से प्लेसमार्क बना रहे हैं और अगर आप बहुत तेज़ी से जा रहे हैं, तो उन्हें धीमा कर दें.

नतीजा

अब आप CSV फ़ाइल से KML फ़ाइल बनाने के लिए, Python का इस्तेमाल कर सकते हैं. दिए गए कोड का इस्तेमाल करके, KML फ़ाइल सिर्फ़ Google Earth में काम करेगी. Maps और Earth में काम करने के लिए <ExtendedData> के बजाय <description> का इस्तेमाल किया जा सकता है. इस कोड सैंपल को ऐसी किसी भी दूसरी प्रोग्रामिंग भाषा में बदलना भी आसान है जो एक्सएमएल के साथ काम करती है.

अब जब आप अपनी सभी CSV फ़ाइलों को KML में बदलने का काम पूरा कर चुके हैं, तो हो सकता है कि आप दूसरे KML लेख देखना चाहें, जैसे कि KML बनाने के लिए PHP और MySQL का इस्तेमाल करना. साथ ही, एक्सटेंडेड डेटा पर Google डेवलपर गाइड लेख, कस्टम डेटा जोड़ना देखें.

पेज पर सबसे ऊपर जाएं