Maret 2008
Tujuan
Tutorial ini menguraikan dasar-dasar cara membuat KML dari data Comma Separated Value (CSV) menggunakan Python. Data CSV adalah salah satu format file yang paling banyak digunakan saat ini. Sebagian besar spreadsheet dan database dapat membaca dan menulis file CSV. Formatnya yang sederhana dapat diedit di editor teks. Banyak bahasa pemrograman, seperti Python, memiliki library khusus untuk membaca dan menulis file CSV. Oleh karena itu, SDS menjadi media yang tepat untuk menukar data dalam jumlah besar.
Meskipun
contoh kode dalam tutorial ini menggunakan Python, contoh kode tersebut dapat
disesuaikan dengan sebagian besar
bahasa pemrograman lainnya. Tutorial ini menggunakan kode dari Mengodekan Alamat untuk Digunakan dalam KML untuk mengubah alamat menjadi koordinat bujur/lintang. Fitur ini juga menggunakan elemen <ExtendedData>
baru KML 2.2, dan memanfaatkan pembuatan template balon yang diuraikan dalam Menambahkan Data Kustom. Dengan demikian, KML yang dihasilkan saat ini tidak didukung di Google Maps atau aplikasi lain yang menggunakan KML, tetapi kode dapat disesuaikan untuk menghasilkan KML yang kompatibel dengan Maps.
Data Sampel
Untuk tutorial ini, gunakan file google-addresses.csv sebagai contoh file CSV. File ini berisi semua alamat, nomor telepon, dan nomor faks dari berbagai kantor Google di Amerika Serikat. Berikut adalah teks file:
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,
Perhatikan bagaimana setiap baris adalah serangkaian string teks yang dipisahkan oleh koma.
Setiap koma membatasi kolom; setiap baris memiliki jumlah koma yang sama.
Baris pertama berisi nama kolom secara berurutan. Misalnya,
blok
teks pertama di setiap baris adalah kolom "Office", yang kedua
"Address1", dll. Python dapat mengubahnya menjadi kumpulan dicts
yang disebut DictReader
yang memungkinkan Anda
menelusuri setiap baris. Contoh kode ini mengandalkan pengetahuan Anda sebelumnya tentang struktur data, tetapi Anda dapat menambahkan beberapa pengendali dasar untuk meneruskan struktur kolom secara dinamis.
Mengurai File CSV
Modul xml.dom.minidom
Python menyediakan
alat yang sangat baik untuk membuat dokumen XML, dan karena KML adalah XML, Anda akan sering menggunakannya dalam tutorial ini. Anda membuat elemen dengan createElement
atau
createElementNS
, dan menambahkan ke elemen lain dengan appendChild
.
Berikut adalah langkah-langkah untuk mengurai file CSV dan membuat file KML.
- Impor geocoding_for_kml.py ke dalam modul Anda.
- Buat
DictReader
untuk file CSV.DictReader
adalah kumpulandicts
, satu untuk setiap baris. - Buat dokumen menggunakan
xml.dom.minidom.Document()
Python. - Buat elemen
<kml>
root menggunakancreateElementNS.
- Tambahkan ke dokumen
.
- Buat elemen
<Document>
menggunakancreateElement
. - Tambahkan ke elemen
<kml>
menggunakanappendChild
. - Untuk setiap baris, buat elemen
<Placemark>
, lalu tambahkan ke elemen<Document>
. - Untuk setiap kolom di setiap baris, buat elemen
<ExtendedData>
dan tambahkan ke elemen<Placemark>
yang Anda buat di langkah 8. - Buat elemen
<Data>
, lalu tambahkan ke elemen<ExtendedData>
. Beri elemen<Data>
atribut nama, dan tetapkan nilai nama kolom menggunakansetAttribute
. - Buat elemen
<value>
dan tambahkan ke elemen<Data>
. Buat node teks, dan tetapkan nilai kolom menggunakancreateTextNode
. Tambahkan node teks ke elemen<value>
. - Buat elemen
<Point>
dan tambahkan ke elemen<Placemark>
. Buat elemen<coordinates>
dan tambahkan ke elemen<Point>
. - Ekstrak alamat dari baris sehingga menjadi satu string dalam format ini: Address1,Address2,City,State,Zip. Jadi, baris pertama
adalah
1600 Amphitheater Parkway,,Mountain View,CA,94043
. Tidak masalah jika ada koma yang berdekatan. Perhatikan, untuk melakukannya, Anda harus mengetahui terlebih dahulu struktur file CSV dan kolom mana yang membentuk alamat. - Beri geocode pada alamat menggunakan kode geocoding_for_kml.py yang dijelaskan dalam Geocoding Alamat untuk Digunakan dalam KML. Tindakan ini akan menampilkan string yang merupakan bujur dan lintang lokasi.
- Buat node teks dan tetapkan nilai koordinat di langkah 14, lalu tambahkan ke elemen
<coordinates>
. - Tulis dokumen KML ke file.
- Jika Anda meneruskan daftar nama kolom sebagai argumen ke
skrip, skrip akan menambahkan elemen dalam urutan tersebut. Jika kita tidak peduli
dengan urutan elemen, kita dapat menggunakan
dict.keys()
untuk menghasilkanlist
. Namun,dict.keys()
tidak mempertahankan urutan asli dari dokumen. Untuk menggunakan argumen ini, teruskan daftar nama kolom sebagai daftar yang dipisahkan koma, seperti ini:python csvtokml.py Office,Address1,Address2,Address3,City,State,Zip,Phone,Fax
Contoh Kode Python
Contoh kode untuk membuat file KML dari file CSV menggunakan Python 2.2 ditampilkan di bawah. Anda juga dapat mendownloadnya di sini.
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()
Contoh KML yang Dibuat
Contoh KML yang dibuat oleh skrip ini ditampilkan di bawah.
Perhatikan bagaimana beberapa elemen<value>
hanya memiliki spasi kosong. Hal ini karena kolom tidak
memiliki data apa pun. Anda juga dapat mendownload contoh lengkapnya di sini.
<?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>
...
Screen shot
Di bawah ini adalah screenshot tampilan file KML tersebut di Google Earth.
Karena setiap elemen <Placemark>
tidak memiliki <BalloonStyle><text>
dan tidak memiliki elemen <description>
, balon akan menggunakan gaya tabel secara default, dengan memanfaatkan elemen <Data>
.

Pertimbangan Geocoding
Hal ini disebutkan dalam "Geocoding Addresses for Use in KML", tetapi perlu diulang. Permintaan geocoding Anda akan tunduk pada kecepatan kueri maksimum geocoder dan 15.000 kueri per hari berdasarkan IP Anda. Selain itu, kode status 620
akan ditampilkan oleh geocoder jika Anda membuat kueri lebih cepat daripada yang dapat ditangani. (Daftar lengkap kode status
tersedia
di sini.)
Untuk memastikan Anda tidak mengirim kueri terlalu cepat ke geocoder, Anda dapat menentukan penundaan di antara setiap permintaan geocode. Anda dapat meningkatkan
penundaan ini setiap kali Anda menerima status 620
, dan menggunakan loop while
untuk memastikan Anda telah
berhasil melakukan geokode alamat sebelum melakukan iterasi ke alamat berikutnya. Artinya, jika file CSV Anda sangat besar, Anda mungkin harus mengubah kode geocoding, atau melacak seberapa cepat Anda membuat Penanda Tempat dan memperlambatnya jika Anda melakukannya terlalu cepat.
Kesimpulan
Sekarang Anda dapat menggunakan Python untuk membuat file KML dari file CSV. Dengan menggunakan kode yang diberikan, file KML hanya akan berfungsi di Google Earth. Anda dapat mengubahnya agar berfungsi di Maps dan Earth menggunakan
<description>
, bukan <ExtendedData>
.
Contoh kode ini juga mudah dikonversi ke bahasa pemrograman lain yang menyediakan dukungan XML.
Setelah selesai mengonversi semua file CSV ke KML, Anda mungkin ingin membaca artikel KML lainnya, seperti Menggunakan PHP dan MySQL untuk membuat KML dan artikel Panduan Developer Google tentang ExtendedData, Menambahkan Data Kustom.