Create kml from csv in Python - python

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.

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()

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.)

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.

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

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.

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', '')

Related

f.write to kml files

So, I've been tasked with writing kml files from phython, without using simplekml. I going wrong in the code... can anyone please identify the mistake?
#Input the file name."XYpoints1_wgs84"
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('Buffered_kml.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(" <name>" + fname + '.kml' +"</name>\n")
f.write(" <Polygon> <outerBoundaryIs> <LinearRing>\n")
f.write(" <coordinates>\n" )
next(data)
for row in data:
f.write(str((row[1])) + "," + (str(row[2]))+"\n")
f.write(" </coordinates>\n" )
f.write(" </LinearRing> </outerBoundaryIs> </Polygon> \n")
f.write("</kml>\n")
print ("File Created. ")
print ("Press ENTER to exit. ")
input()
f.close()
It does produce kml file but without the coordinate end tag. Why is this happening?

How to export text to a new file, userinput?

So i wrote a little program in python which allows me to take a .csv file, filter out the lines i need and then export these into a new .txt file.
This worked quite well, so i decided to make it more user friendly by allowing the user to select the file that should be converted by himself through the console (command line).
My problem: The file is imported as a .csv file but not exported as a .txt file which leads to my program overwriting the original file which will be emptied because of a step in my program which allows me to delete the first two lines of the output text.
Does anyone know a solution for this?
Thanks :)
import csv
import sys
userinput = raw_input('List:')
saveFile = open(userinput, 'w')
with open(userinput, 'r') as file:
reader = csv.reader(file)
count = 0
for row in reader:
print(row[2])
saveFile.write(row[2] + ' ""\n')
saveFile.close()
saveFile = open(userinput, 'r')
data_list = saveFile.readlines()
saveFile.close()
del data_list[1:2]
saveFile = open(userinput, 'w')
saveFile.writelines(data_list)
saveFile.close()
Try This:
userinput = raw_input('List:')
f_extns = userinput.split(".")
saveFile = open(f_extns[0]+'.txt', 'w')
I think you probably just want to save the file with a new name, this Extracting extension from filename in Python talks about splitting out the extension so then you can just add your own extension
you would end up with something like
name, ext = os.path.splitext(userinput)
saveFile = open(name + '.txt', 'w')
You probably just need to change the extension of the output file. Here is a solution that sets the output file extension to .txt; if the input file is also .txt then there will be a problem, but for all other extensions of the input file this should work.
import csv
import os
file_name = input('Name of file:')
# https://docs.python.org/3/library/os.path.html#os.path.splitext
# https://stackoverflow.com/questions/541390/extracting-extension-from-filename-in-python
file_name, file_ext_r = os.path.splitext(file_name)
file_ext_w = '.txt'
file_name_r = ''.format(file_name, file_ext_r)
file_name_w = ''.format(file_name, file_ext_w)
print('File to read:', file_name_r)
print('File to write:', file_name_w)
with open(file_name_r, 'r') as fr, open(file_name_w, 'w') as fw:
reader = csv.reader(fr)
for i, row in enumerate(reader):
print(row[2])
if i >= 2:
fw.write(row[2] + ' ""\n')
I also simplified your logic to avoid writting the first 2 lines to the output file; no need to read and write the output file again.
Does this work for you?

Unable to read csv file present in Unix in Python

I want to read CSV file which is present in Unix at a path say-/var/lib/Folder/abc.csv
I am using below code to read this file, but it looks like it's not returning any rows and hence it's not going inside the for loop.
file_path = "/var/lib/Folder/abc.csv"
with open(file_path, newline='') as csv_file:
reader = csv.reader(csv_file)
for row in reader:
logging.debug(str(datetime.datetime.now()) + " Checking rows...")
logging.debug(str(datetime.datetime.now()) + " Row(" + str(count) + ") = " + row)
CSV file looks something like-
"Account ID","Detail","Description","Date created"
"123456","Customer","Savings","2017/10/24"
I am using Python 2.7
This works when i try in my local. But I am actually using Jenkins to run this and the file is placed in my Jenkins Master server. I have copied that file from the code server to jenkins using below - with ssh_shell.open(path + fileName, "rb") as remote_file: with open(path + fileName, "wb") as local_file: shutil.copyfileobj(remote_file, local_file) After this I am trying to read the file, its not working. i.e not going inside that for loop. Any idea on that?
You could try the following:
reader = csv.reader(csv_file, delimiter=',', quotechar='"')
Also, please try to see what "reader" actually contains. If the for loop is not entered that means that the contents have not been read correctly. Try to start debugging from there.
try this changed row to str(row)
file_path = "/var/lib/Folder/abc.csv"
with open(file_path, newline='') as csv_file:
reader = csv.reader(csv_file)
for row in reader:
logging.debug(str(datetime.datetime.now()) + " Checking rows...")
logging.debug(str(datetime.datetime.now()) + " Row(" + str(count) + ") = " + str(row))

Trying to make a KML file in Python

I'm still very new to python, i am trying to export the locations on a list (List2) into a kml file which will then display the results on google maps. I have no idea really what i am doing and atm all i am getting is a syntax error around every ,", symbol. Can someone help me with this please.
KMLFile = open("KML.txt", "w")
f.write("<KML_File>\n")
f.write("<Document>\n")
for line in List2:
f.write(" <Placemark>")
f.write(" <decription>" + str(row[0]) + "</description>")
f.write(" <Point>")
f.write(" <coordinates>" + str(row[2]) + str(row[1])"</coordinates>")
f.write(" </Point>")
f.write(" </Placemark>")
f.write("</Document>\n")
f.write("</kml>\n")
KMLFile = close()
Hard-coding XML output to create a KML file in a series of print statements is error-prone and hard to maintain. Rather use a Python KML library such as simplekml or pyKML to generate the KML. The simplekml API simplifies writing KML and produces valid KML with code that is cleaner and easier to understand.
import simplekml
# list2 = ...some assignment with list of point data elements
kml = simplekml.Kml()
for row in list2:
kml.newpoint(description=row[0],
coords=[(row[2], row[1])]) # lon, lat, optional height
# save KML to a file
kml.save("test.kml")
Using this test input for a single point:
list2 = [ [ 'description', 51.500152, -0.126236 ] ] # description, lat, lon
The KML output would be this:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">
<Document id="feat_1">
<Placemark id="feat_2">
<description>description</description>
<Point id="geom_0">
<coordinates>-0.126236,51.500152,0.0</coordinates>
</Point>
</Placemark>
</Document>
</kml>
In brief:
You should change KMLFile to f or vice versa.
You should call the close() method like this : f.close().
Your corrected code:
f = open("KML.txt", "w")
f.write("<KML_File>\n")
f.write("<Document>\n")
for line in List2:
f.write("\t<Placemark>")
f.write("\t\t<decription>" + str(row[0]) + "</description>")
f.write("\t\t<Point>")
f.write("\t\t\t<coordinates>" + str(row[2]) + str(row[1]) + "</coordinates>")
f.write("\t\t</Point>")
f.write("\t</Placemark>")
f.write("</Document>\n")
f.write("</kml>\n")
f.close()
In addition, if you do not want to write the f.close() line and let python manage the file closure:
with open("KML.txt", "w") as f:
f.write("<KML_File>\n")
f.write("<Document>\n")
for line in List2:
f.write("\t<Placemark>")
f.write("\t\t<decription>" + str(row[0]) + "</description>")
f.write("\t\t<Point>")
f.write("\t\t\t<coordinates>" + str(row[2]) + str(row[1]) + "</coordinates>")
f.write("\t\t</Point>")
f.write("\t</Placemark>")
f.write("</Document>\n")
f.write("</kml>\n")
Eventually, if you do not want to have many + into your f.write() lines, you can also opt for the format() method:
f.write("\t\t\t<coordinates>{}{}/coordinates>".format(row[2], row[1]))
In your code you haven't defined the variable f which should reference the file-object you want to write to. You could either do
f = open("KML.txt", "w")
f.write("<KML_File>\n")
...
f.close()
or better:
with open("KML.txt", "w") as f:
f.write("<KML_File>\n")
...
which makes sure to always close the file even if some code in between fails.
For writing XML-files you might want to take a look at the Python xml-package.
import geopandas as gpd
polys = gpd.GeoDataFrame(df)
polys.to_file(r'../docs/database.kml', driver = 'KML')
df should contain description, geometry, name.

Search and replace specific line which starts with specific string in a file

My requirement is to open a properties file and update the file, for update purpose i need to search for a specific string which stores the url information. For this purpose i have written the below code in python:
import os
owsURL="https://XXXXXXXXXXXXXX/"
reowsURL = "gStrOwsEnv = " + owsURL + "/" + "OWS_WS_51" + "/"
fileName='C:/Users/XXXXXXXXXXX/tempconf.properties'
if not os.path.isfile(fileName):
print("!!! Message : Configuraiton.properties file is not present ")
else:
print("+++ Message : Located the configuration.properties file")
with open(fileName) as f:
data = f.readlines()
for m in data:
if m.startswith("gStrOwsEnv"):
print("ok11")
m = m.replace(m,reowsURL)
after executing the program i am not able to update the properties file.
Any help is highly appreciated
Sample Content of file:
# ***********************************************
# Test Environment Details
# ***********************************************
# Application URL pointing to test execution
#gStrApplicationURL =XXXXXXXXXXXXXXXX/webservices/person
#gStrApplicationURL = XXXXXXXXXXXXXX/GuestAPIService/ProxyServices/
# FOR JSON
#gStrApplicationURL = XXXXXXXXXXXXXX
#SOAP_gStrApplicationURL =XXXXXXXXXXXXXXXXXXXXXXX
#(FOR WSDL PARSING)
version = 5
#v9
#SOAP_gStrApplicationURL = XXXXXXXXXXX/XXXXXXXXX/XXXXXXXXX/
#v5
SOAP_gStrApplicationURL = XXXXXXXXXXXXXXX/OWS_WS_51/
gStrApplicationXAIServerPath=
gStrEnvironmentName=XXXXXXXXX
gStrOwsEnv = XXXXXXXXXXXXXXXXXXXX/OWS_WS_51/
gStrConnectEnv = XXXXXXXXXXXXXXXXX/OWSServices/Proxy/
gStrSubscriptionKey =XXXXXXXXXXXXXXXXXXXXXX
I'm pretty sure that this is not the best way of doing that, but this is still one way:
with open(input_file_name, 'r') as f_in, open(output_file_name, 'w') as f_out:
for line in f_in:
if line.startswith("gStrOwsEnv"):
f_out.write(reowsURL)
else:
f_out.write(line)
That script copy every line of input_file_name into output_file_name except the lines that you want to change.

Categories