5

So I was wondering if it's possible to convert the KML files to an CSV attribute table (of those geometric features).

So I've found this code that converts the KML to CSV, but really just prints the tags there in a CSV :

import csv
from lxml import etree

out = raw_input("Name for output file:  ")
if out.strip() is "":
  out = "trader-joes-all-locations.csv"

out_data = []

parser = etree.XMLParser(recover=True, remove_blank_text=True)

file_name = "trader-joes-all-locations.xml"


root = etree.parse(file_name, parser)

tag_list = [ "name", "address1", "address2", "beer", "city", "comingsoon", "hours", "latitude", "longitude", "phone", "postalcode", "spirits", "state", "wine" ]

out_data.append(tag_list[:])

def missing_location(p):
  lat = p.find("latitude")
  lon = p.find("longitude")
  if lat is None or lon is None:
    return True
  else:
    return False

def get_poi_info(p):
  # if latitude or longitude doesn't exist, skip
  if missing_location(p):
    print "tMissing location for %s" % p.find("name").text
    return None
  info = []
  for tag in tag_list:
    # if tag == "name":
    #   print "%s" % p.find(tag).text
    node = p.find(tag)
    if node is not None and node.text:
      if tag == "latitude" or tag == "longitude":
        info.append(round(float(node.text), 5))
      else:
        info.append(node.text.encode("utf-8"))
        # info.append(node.text.encode("ascii", "ignore"))
    else:
      info.append("")
  return info

print "nreading xml..."

# get all <poi> elements
pois = root.findall(".//poi")
for p in pois:
  poi_info = get_poi_info(p)
  # print "%s" % (poiInfo)
  if poi_info:
    out_data.append(poi_info)

print "finished xml, writing file..."

out_file  = open(out, "wb")
csv_writer = csv.writer(out_file, quoting=csv.QUOTE_MINIMAL)
for row in out_data:
  csv_writer.writerow(row)

out_file.close()

print "wrote %sn" % out

There is a copy of the KML here ( KML ), and what I'm wondering is how to extract this metadata info and convert it to an attribute table, in csv, similar to this [Image][2]. I've searched a little bit and it seems the site http://www.gpsvisualizer.com/ does create a text table, containing only geometric data (long/lat).

Could you guys help me out here?

Thanks.

3

Where is your image ?
There was lots of Python modules to parse KML files (Pypi: KML) and you can also use all the Python modules to parse XML files (Pypi: XML), lxml is one of them, but not the easiest to use.

For example

The problem is that your KML file is singular:

enter image description here

It is easy to extract the name, the snippet and the geometry

from lxml import etree
parser = etree.XMLParser(recover=True, remove_blank_text=True)
file_name="hospitais_Project_Buffer_Int.kml"
root = etree.parse(file_name, parser)
names = root.xpath('//kml:name', namespaces={'kml': "http://www.opengis.net/kml/2.2"})
for names in names:
    print names.text,
hospitais_Project_Buffer_Int, HJM, MAC, HTS, HSAC,IGP, HSJ, ....

But the content of the tag description is a CDATA HTML file, much more difficult to parse.

enter image description here

1

I worked on a similar problem. This is what i did. I used lxml to parse, read and write back data. I read a kml file and wrote output to another kml file. But you can use my approach to write to a csv file as well.

import lxml.etree as et
html_parser = et.HTMLParser()
for Document in root:
  for subtree in Document:
    if 'Folder' in subtree.tag:
        folder = subtree
        for subtree in folder:
            if 'Placemark' in subtree.tag:
                placemark = subtree
                for subtree in placemark:
                    if 'description' in subtree.tag:
                        desc_old = subtree.text
                        # this step will give you the description data as a ElementTree
                        desc_old_tree = et.parse(StringIO(desc_old),html_parser)
                        #get Element from Element tree 
                        desc_old_tree_html = desc_old_tree.getroot()
                        for child_in_html in desc_old_tree_html:
                            # check if subtag is the one you require and 
                            if 'head' in child_in_html.tag:
                                for head_child in child_in_html:
                                    if 'meta' in head_child.tag:
                                        # you got your meta elemet
                                if 'meta' in subtag_in_html.tag:
                                    # do something

                            elif 'body' in child_in_html.tag:
                                #parse bodyhere

Another way to read meta is

meta_element=desc_old_tree_html.findall("head")[0].findall("Meta")[0]

For more info about parsing, checkout these two links that helped me. http://lxml.de/parsing.html#parsing-html

https://stackoverflow.com/questions/37820087/updating-coordinates-in-a-kml-file-using-python

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.