Commit c9ef8d55 authored by Christian Ledermann's avatar Christian Ledermann

first commit

parents
# -*- coding: utf-8 -*-
try:
from lxml import etree
except ImportError:
import xml.etree.ElementTree as etree
class KML(object):
""" represents a KML File """
_features = []
def __init__(self):
self._features =[]
def from_file(self, filename):
""" read a KML File and parse into a KML Object"""
f = open(filename, 'r')
self.from_string(f.read())
f.close()
def from_string(self, xml_string):
element = etree.XML(xml_string)
if element.tag.endswith('kml'):
ns = element.tag.rstrip('kml')
documents = element.findall('%sDocument' % ns)
for document in documents:
feature = Document(ns)
feature.from_element(document)
self.append(feature)
folders = element.findall('%sFolder' % ns)
for folder in folders:
feature = Folder(ns)
feature.from_element(folder)
self.append(feature)
placemarks = element.findall('%sPlacemark' % ns)
for placemark in placemarks:
feature = Placemark(ns)
feature.from_element(placemark)
self.append(feature)
else:
raise TypeError
def etree_element(self):
root = etree.Element('{http://www.opengis.net/kml/2.2}kml')
for feature in self.features():
root.append(feature.etree_element())
return root
def to_string(self, prettyprint=False):
""" Returm the KML Object as xml """
return etree.tostring(self.etree_element(), encoding='utf-8')
def features(self):
""" return a list of features """
return self._features
def append(self, kmlobj):
""" append a feature """
if isinstance(kmlobj, (Document, Folder, Placemark)):
self._features.append(kmlobj)
class _Feature(object):
"""
abstract element; do not create
subclasses are:
Container (Document, Folder),
Placemark,
NetworkLink,
GroundOverlay,
PhotoOverlay,
ScreenOverlay
"""
id = None
name = None
description = None
visibility = 1
isopen = 0
#atom_author = None
#atom_link = None
#styleUrl = None
def __init__(self, ns, id=None, name=None, description=None):
self.id = id
self.name=name
self.description=description
self.ns = ns
def etree_element(self):
if self.__name__:
element = etree.Element(self.__name__)
if self.id:
element.set('id', self.id)
if self.name:
name = etree.SubElement(element, "name")
name.text = self.name
if self.description:
description =etree.SubElement(element, "description")
description.text = self.description
visibility = etree.SubElement(element, "visibility")
visibility.text = str(self.visibility)
isopen = etree.SubElement(element, "open")
isopen.text = str(self.isopen)
else:
raise NotImplementedError
return element
def from_string(self, xml_string):
self.from_element(etree.XML(xml_string))
def from_element(self, element):
if self.ns + self.__name__ != element.tag:
raise TypeError
else:
if element.get('id'):
self.id = element.get('id')
name = element.find('%sname' %self.ns)
if name is not None:
self.name = name.text
description = element.find('%sdescription' %self.ns)
if description is not None:
self.description = description.text
visibility = element.find('%svisibility' %self.ns)
if visibility is not None:
self.visibility = visibility.text
isopen = element.find('%sopen' %self.ns)
if isopen is not None:
self.isopen = isopen.text
class _Container(_Feature):
"""
abstract element; do not create
A Container element holds one or more Features and allows the
creation of nested hierarchies.
subclasses are:
Document,
Folder
"""
_features = []
def __init__(self, ns, id=None, name=None, description=None):
super(_Container, self).__init__(ns, id, name, description)
self._features =[]
def features(self):
""" return a list of features """
return self._features
def etree_element(self):
element = super(_Container, self).etree_element()
for feature in self.features():
assert(feature != self)
element.append(feature.etree_element())
return element
def append(self, kmlobj):
""" append a feature """
if isinstance(kmlobj, _Feature):
self._features.append(kmlobj)
assert(kmlobj != self)
class Document(_Container):
"""
A Document is a container for features and styles. This element is
required if your KML file uses shared styles
"""
__name__ = "Document"
def from_element(self, element):
super(Document, self).from_element(element)
folders = element.findall('%sFolder' % self.ns)
for folder in folders:
feature = Folder(self.ns)
feature.from_element(folder)
self.append(feature)
placemarks = element.findall('%sPlacemark' % self.ns)
for placemark in placemarks:
feature = Placemark(self.ns)
feature.from_element(placemark)
self.append(feature)
class Folder(_Container):
"""
A Folder is used to arrange other Features hierarchically
(Folders, Placemarks, NetworkLinks, or Overlays).
"""
__name__ = "Folder"
def from_element(self, element):
super(Folder, self).from_element(element)
folders = element.findall('%sFolder' % self.ns)
for folder in folders:
feature = Folder(self.ns)
feature.from_element(folder)
self.append(feature)
placemarks = element.findall('%sPlacemark' % self.ns)
for placemark in placemarks:
feature = Placemark(self.ns)
feature.from_element(placemark)
self.append(feature)
class Placemark(_Feature):
__name__ = "Placemark"
styleUrl = None
geometry = None
pass
# -*- coding: utf-8 -*-
import unittest
import kml
import xml.etree.ElementTree as etree
class BuildKmlTestCase( unittest.TestCase ):
""" Build a simple KML File """
def test_kml(self):
""" kml file without contents """
k=None
k = kml.KML()
self.assertEqual(len(k.features()),0)
self.assertEqual( k.to_string(),
'<ns0:kml xmlns:ns0="http://www.opengis.net/kml/2.2" />')
def test_folder(self):
""" KML file with folders """
k = kml.KML()
f = kml.Folder('', 'id', 'name', 'description')
nf = kml.Folder('', 'nested-id', 'nested-name', 'nested-description')
f.append(nf)
k.append(f)
f2 = kml.Folder('', 'id2', 'name2', 'description2')
k.append(f2)
self.assertEqual(len(k.features()),2)
self.assertEqual(len( k.features()[0].features()),1)
print k.to_string()
def test_placemark(self):
k = kml.KML()
p = kml.Placemark('', 'id', 'name', 'description')
p2 = kml.Placemark('', 'id2', 'name2', 'description2')
k.append(p)
k.append(p2)
self.assertEqual(len(k.features()),2)
def test_document(self):
k = kml.KML()
d = kml.Document('', 'docid', 'doc name', 'doc description')
f = kml.Folder('', 'fid', 'f name', 'f description')
k.append(d)
d.append(f)
nf = kml.Folder('', 'nested-fid', 'nested f name', 'nested f description')
f.append(nf)
f2 = kml.Folder('', 'id2', 'name2', 'description2')
d.append(f2)
p = kml.Placemark('', 'id', 'name', 'description')
p2 = kml.Placemark('', 'id2', 'name2', 'description2')
f2.append(p)
nf.append(p2)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(k.features()[0].features()),2)
class KmlFromStringTestCase( unittest.TestCase ):
def test_document(self):
doc = """<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>Document.kml</name>
<open>1</open>
<Style id="exampleStyleDocument">
<LabelStyle>
<color>ff0000cc</color>
</LabelStyle>
</Style>
<Placemark>
<name>Document Feature 1</name>
<styleUrl>#exampleStyleDocument</styleUrl>
<Point>
<coordinates>-122.371,37.816,0</coordinates>
</Point>
</Placemark>
<Placemark>
<name>Document Feature 2</name>
<styleUrl>#exampleStyleDocument</styleUrl>
<Point>
<coordinates>-122.370,37.817,0</coordinates>
</Point>
</Placemark>
</Document>
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(k.features()[0].features()),2)
print k.to_string()
def test_folders(self):
doc="""<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Folder>
<name>Folder.kml</name>
<open>1</open>
<description>
A folder is a container that can hold multiple other objects
</description>
<Placemark>
<name>Folder object 1 (Placemark)</name>
<Point>
<coordinates>-122.377588,37.830266,0</coordinates>
</Point>
</Placemark>
<Placemark>
<name>Folder object 2 (Polygon)</name>
<Polygon>
<outerBoundaryIs>
<LinearRing>
<coordinates>
-122.377830,37.830445,0
-122.377576,37.830631,0
-122.377840,37.830642,0
-122.377830,37.830445,0
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark>
<name>Folder object 3 (Path)</name>
<LineString>
<tessellate>1</tessellate>
<coordinates>
-122.378009,37.830128,0 -122.377885,37.830379,0
</coordinates>
</LineString>
</Placemark>
</Folder>
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(k.features()[0].features()),3)
print k.to_string()
def test_placemark(self):
doc="""<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Placemark>
<name>Simple placemark</name>
<description>Attached to the ground. Intelligently places itself
at the height of the underlying terrain.</description>
<Point>
<coordinates>-122.0822035425683,37.42228990140251,0</coordinates>
</Point>
</Placemark>
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(k.features()[0].name, "Simple placemark")
print k.to_string()
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite( KmlFromStringTestCase ))
suite.addTest(unittest.makeSuite( BuildKmlTestCase ))
return suite
if __name__ == '__main__':
unittest.main()
from setuptools import setup, find_packages
import sys, os
version = '0.0'
setup(name='fastkml',
version=version,
description="Fast KML processing for python",
long_description="""\
Create and read KML Files""",
classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
keywords='',
author='Christian Ledermann',
author_email='christian.ledermann@gmail.com',
url='',
license='GPL',
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
include_package_data=True,
zip_safe=False,
install_requires=[
# -*- Extra requirements: -*-
],
entry_points="""
# -*- Entry points: -*-
""",
)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment