10

I am new to Python. I am working on gps files. I need to convert a CSV file having all the gps data to kml file. Below is the code in python I am using :

import csv
#Input the file name.
fname = raw_input("Enter file name WITHOUT extension: ")
data = csv.reader(open(fname + '.csv'), delimiter = ',')
#Skip the 1st header row.
data.next()
#Open the file to be written.
f = open('csv2kml.kml', 'w')

#Writing the kml file.
f.write("<?xml version='1.0' encoding='UTF-8'?>\n")
f.write("<kml xmlns='http://earth.google.com/kml/2.1'>\n")
f.write("<Document>\n")
f.write("   <name>" + fname + '.kml' +"</name>\n")
for row in data:
    f.write("   <Placemark>\n")
    f.write("       <name>" + str(row[1]) + "</name>\n")
    f.write("       <description>" + str(row[0]) + "</description>\n")
    f.write("       <Point>\n")
    f.write("           <coordinates>" + str(row[3]) + "," + str(row[2]) + "," + str(row[4]) + "</coordinates>\n")
    f.write("       </Point>\n")
    f.write("   </Placemark>\n")
f.write("</Document>\n")
f.write("</kml>\n")
print "File Created. "
print "Press ENTER to exit. "
raw_input()

The csv file I am using is available here : dip12Sep11newEdited.csv The kml file generated is available here : csv2kml.kml But the kml file is not getting created correctly. Apparently after some rows in the csv the code is not able to generate more Placemarks. Its not able to iterate. You can see that by scrolling to the last part of the kml file generated.

Can anyone help me finding out the error in the code, because for some smaller csv files it worked correctly and created kml files fully.

Thanks.

Bobby
  • 11,419
  • 5
  • 44
  • 69
Darkpain
  • 135
  • 1
  • 3
  • 10
  • How do you know that it's not able to generate more Placemarks? (Does it ever prompt 'File Created'?) – KevinDTimm Sep 23 '11 at 13:38
  • Yes it promts 'File Creted'. But if you open the kml file in notepad you can see that the file didnt write completely. – Darkpain Sep 23 '11 at 17:40

6 Answers6

9

You didn't answer the query above, but my guess is that the error is that you're not closing your output file (which would flush your output).

f.close()
KevinDTimm
  • 14,226
  • 3
  • 42
  • 60
4

use etree to create your file

http://docs.python.org/library/xml.etree.elementtree.html

It's included with Python and protects you from generating broken XML. (eg. because fname contained &, which has special meaning in XML.)

ssokolow
  • 14,938
  • 7
  • 52
  • 57
Louis
  • 2,854
  • 2
  • 19
  • 24
2

This code is well written thank you for the post. I got it to work by putting my CSV in the same directory as the .py code.

I made a few edits to bring it to py 3.3

import csv
#Input the file name."JoeDupes3_forearth"
fname = input("Enter file name WITHOUT extension: ")
data = csv.reader(open(fname + '.csv'), delimiter = ',')
#Skip the 1st header row.
#data.next()
#Open the file to be written.
f = open('csv2kml.kml', 'w')

#Writing the kml file.
f.write("<?xml version='1.0' encoding='UTF-8'?>\n")
f.write("<kml xmlns='http://earth.google.com/kml/2.1'>\n")
f.write("<Document>\n")
f.write("   <name>" + fname + '.kml' +"</name>\n")
for row in data:
    f.write("   <Placemark>\n")
    f.write("       <name>" + str(row[1]) + "</name>\n")
    f.write("       <description>" + str(row[3]) + "</description>\n")
    f.write("       <Point>\n")
    f.write("           <coordinates>" + str(row[10]) + "," + str(row[11]) + "," + str() + "</coordinates>\n")
    f.write("       </Point>\n")
    f.write("   </Placemark>\n")
f.write("</Document>\n")
f.write("</kml>\n")
print ("File Created. ")
print ("Press ENTER to exit. ")
input()
f.close()

Hope it helps if you are trying to convert your data.

Reverend_Dude
  • 148
  • 1
  • 10
1

The simplekml package works very well, and makes easy work of such things.

To install on Ubuntu, download the latest version and run the following from the directory containing the archive contents.

sudo python setup.py install

There are also some tutorials to get you started.

CodeMonkey
  • 22,825
  • 4
  • 35
  • 75
ryanjdillon
  • 17,658
  • 9
  • 85
  • 110
1

One answer mentions the "etree", one advantage that you do not have to hardcode the xml format:

Below one of my examples, of course you have to adjust it to your case, but you may get the principle idea of how etree works:

to get something like this

<OGRVRTDataSource>
 <OGRVRTLayer name="GW1AM2_201301010834_032D_L1SGRTBR_1110110_channel89H">
  <SrcDataSource>G:\AMSR\GW1AM2_201301010834_032D_L1SGRTBR_1110110_channel89H.csv</SrcDataSource>
  <GeometryType>wkbPoint</GeometryType>
  <GeometryField encoding="PointFromColumns" x="lon" y="lat" z="brightness" />
 </OGRVRTLayer>
</OGRVRTDataSource>

you can use this code:

import xml.etree.cElementTree as ET
[....]
root = ET.Element("OGRVRTDataSource")

OGRVRTLayer  = ET.SubElement(root, "OGRVRTLayer")
OGRVRTLayer.set("name", AMSRcsv_shortname)

SrcDataSource = ET.SubElement(OGRVRTLayer, "SrcDataSource")
SrcDataSource.text = AMSRcsv

GeometryType = ET.SubElement(OGRVRTLayer, "GeometryType")
GeometryType.text = "wkbPoint"

GeometryField = ET.SubElement(OGRVRTLayer,"GeometryField")
GeometryField.set("encoding", "PointFromColumns")

GeometryField.set("x", "lon")
GeometryField.set("y", "lat")
GeometryField.set("z", "brightness")

tree = ET.ElementTree(root)
tree.write(AMSRcsv_vrt)

also some more info here

Community
  • 1
  • 1
  • Note that I made a correction in my post to make it more concise. Any element where you're just setting the text or a single attribute and don't need to keep a reference for adding subelements can be done in a single line. For example: `ET.SubElement(OGRVRTLayer, "GeometryType").text = "wkbPoint"` – ssokolow Oct 18 '15 at 15:21
0

Just use simplekml library to create kml easily.. instead of writing the kml data.. I achieved it directly by using simplekml.

import simplekml

Read the documentation of simplekml

with open(arguments+'.csv', 'r') as f:
    datam = [(str(line['GPSPosLongitude']), str(line['GPSPosLatitude'])) for line in csv.DictReader(f)]
    kml = simplekml.Kml()
    linestring = kml.newlinestring(name='linename')
    linestring.coords = datam
    linestring.altitudemode = simplekml.AltitudeMode.relativetoground
    linestring.style.linestyle.color = simplekml.Color.lime
    linestring.style.linestyle.width = 2
    linestring.extrude = 1
    kml.save('file.kml')
    kml.savekmz('file.kmz', format=False)
    kml2geojson.main.convert('file.kml', '')
Gokul Raghu
  • 55
  • 2
  • 11