Trying to make a KML file in Python - 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.

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?

Save output from biopython object into a file?

Here i have a code written to extract "locus_tag" of gene using "id". How can i save the output from this into a file in a tab seperated format????code adopted and modified https://www.biostars.org/p/110284/
from Bio import SeqIO
foo = open("geneid.txt")
lines = foo.read().splitlines()
genbank_file = open("example.gbk")
for record in SeqIO.parse(genbank_file, "genbank"):
for f in record.features:
if f.type == "CDS" and "protein_id" in f.qualifiers:
protein_id = f.qualifiers["protein_id"][0]
if protein_id in lines:
print f.qualifiers["protein_id"][0],f.qualifiers["locus_tag"][0]
Try adding something like this -- but you will need to make certain the indentations are correct with the code that you have already written.
with open(your_outputFileName, 'w') as outputFile:
string = '\t'.join([f.qualifiers['protein_id'][0],f.qualifiers['locus_tag'][0]])
outputFile.write(string + '\n')
You should also consider opening your initial file using "with". This will automatically close the file when you are done with it -- otherwise -- be certain to close the file (e.g., foo.close()).
for record in SeqIO.parse(genbank_file, 'genbank'):
for f in record.features:
if f.type == 'CDS' and 'protein_id' in f.qualifiers:
protein_id = f.qualifiers['protein_id'][0]
if protein_id in lines:
print f.qualifiers['protein_id'][0],f.qualifiers['locus_tag'][0]
with open('your_outputFileName', 'w') as outputFile:
string = '\t'.join([f.qualifiers['protein_id'][0],f.qualifiers['locus_tag'][0]]) + '\n'
outputFile.write(string)

how to parse a file and write to an output file in python

i am newbie to python. I am trying to parse a file to extract certain columns and write to an output file. I was able to parse and extract the desired columns but having trouble writing them to an output file.
Here is the original test file:
EGW05759 Pld5 I79_005987 GO_function: GO:0003824 - catalytic activity [Evidence IEA]; GO_process: GO:0008152 - metabolic process [Evidence IEA]
EGW05760 Exo1 I79_005988 GO_function: GO:0003677 - DNA binding [Evidence IEA]; GO_function: GO:0003824 - catalytic activity [Evidence IEA]; GO_function: GO:0004518 - nuclease activity [Evidence IEA]; GO_process: GO:0006281 - DNA repair [Evidence IEA]
Here is my python code
f = open('test_parsing.txt', 'rU')
f1 = open('test_parsing_out.txt', 'a')
for line in f:
match = re.search('\w+\s+(\w+)\s+\w+\s+\w+\:', line)
match1 = re.findall('GO:\d+', line)
f1.write(match.group(1), match1)
f1.close()
Basically i want the output to look like this (though i know my code is not complete to achieve this)
Pld5 GO:0003824:GO:0008152
Exo1 GO:0003677:GO:0003824:GO:0004518:GO:0006281
Thanks
Upendra
f = open('test_parsing.txt', 'rU')
f1 = open('test_parsing_out.txt', 'a')
for line in f:
match = re.search('\w+\s+(\w+)\s+\w+\s+\w+\:', line)
match1 = re.findall('GO:\d+', line)
f1.write('%s %s \n'%(match.group(1), ''.join(match1)))
f1.close()
Using the csv module:
import csv, re
with open('test_parsing.txt', 'rU') as infile, open('test_parsing_out.txt', 'a') as outfile:
reader = csv.reader(infile, delimiter="\t")
for line in reader:
result = line[1] + " " + ':'.join(re.findall("GO:\d{6}", line[3]))
outfile.write(result + "\n")
# OUTPUT
Pld5 GO:000382:GO:000815
Exo1 GO:000367:GO:000382:GO:000451:GO:000628

How can I make this program more efficient

This program is a basic encoder in python and I want to see if I can make it more efficient without changing the names of the defined variables. Can someone give me some suggestions?
def encode(pattern, filename):
f = open(filename, "rt")
contents = f.read()
f.close()
printNow(contents)
changes = pattern.split("|")
for str in changes:
printNow("Change "+ str[0] + " to " + str[1])
newMsg = ""
for char in contents:
for change in changes:
if char == change [0]:
char = change[1]
newMsg += char
f = open(filename + "encoded", "wt")
f.write(newMsg)
f.close()
f = open(filename + "encoded", "rt")
printNow(f.read())
f.close()
encode("ae|ga|s3", "C:\\Users\\Shaun\\Desktop\\Test.txt")
import string
def encode(pattern, filename):
with open(filename) as f:
contents = f.read()
s = string.maketrans(*[''.join(a) for a in zip(*pattern.split('|'))])
newMsg = contents.translate(s)
with open(filename + 'encoded', 'rt') as f:
f.write(newMsg)
Use str.translate() instead of doing all the replacements the hard way, and do it line-by-line.
First of all you need to consider the option that your algorithm is already good enough. Even if it can be optimized, if your code is part of a bigger program and it only executes during 0.1% of time, for instance, then it will be most probably useless to optimize the code, since the rest of the program will dominate the total execution time.
If you really have a problem in your code, then I would start by analyzing the complexity of your algorithm.
And finally, you could try to find some bottlenecks in your code. For that, I would profile the code with something like python's timeit.
The str.translate() method works well for character substitutions, but here's another fast way I've used that also works for multi-character substitutions:
import re
def encode(pattern, filename):
f = open(filename, "rt")
contents = f.read()
f.close()
printNow(contents)
change_dict = {}
matches = []
changes = pattern.split("|")
for str in changes:
printNow("Change "+ str[0] + " to " + str[1])
change_dict[str[0]] = str[1]
matches.append(str[0])
change_re = re.compile("|".join(re.escape(x) for x in matches))
newMsg = change_re.sub(lambda m: change_dict[m.group(0)], contents)
f = open(filename + "encoded", "wt")
f.write(newMsg)
f.close()
f = open(filename + "encoded", "rt")
printNow(f.read())
f.close()
encode("ae|ga|s3", "C:\\Users\\Shaun\\Desktop\\Test.txt")

Create kml from csv in 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', '')

Categories